Hace tiempo "publiqué" un
juengo de serpiente con ncurses y hoy quiero revelar su código fuente !!!
El motivo es simple: Apoyo al OpenSource. (No al sofware privado) [Y yo con Windows,XD]
El código fuente viene comentado pero no muy detallado, XD. [Ahora lo leo de nuevo y ciertamente me mareo, me sorprendo a mí mismo, si ahora me mandara hacerlo de nuevo, tendría que dejarme una cuantas hora para idearmelo todo de nuevo,XD, es muy difícil de leerlo].
Aqui os dejo un copy+paste del codigo. (Espero que no haya incompatiblidad y que blogger no me coma ningún caracter...)
Aclaración: La función kbhit es copiado de otra persona
y las librerias de los includes estan separado con espacio, porque sino blogger lo omite.
===== Serpiente.c =====
/*********************************************************
*Fichero: serpiente.c
*Fecha: 15-05-2009
*Autor: Sui Zhao
*Contacto: sui1990(at)gmail(dot)com
*
*Descripcion:
* El tipico juego de serpiente
*
*gcc -lncurses -o serpiente serpiente.c
*
*Ultima actuacion:
************************************************************/
#include - stdio.h>
#include - ncurses.h>
#include - stdlib.h>
//* libreria y funcion para kbhit
#include - termios.h>
#include - unistd.h>
#include - sys/types.h>
#include - sys/time.h>
void changemode(int);
int kbhit(void);
//-------------------
//Funciones
void inicio();
/* ordenes() -> tiene como fin de anhadir
*los movimiento en que debe mover
*/
void ordenes(int y, int x, int longitud, int direccion);
// mover() -> todos los movimieto
void mover();
// Funcion dentro de mover
void ordena_posi_ejecutar(int aux);
//al dar una tecla
void dar_tecla();
//Funcion para aparecer la comida
void comida();
// game over
void fin_juego();
void bienvenida();
//Variables Globales
int y,x;
int longitud;
int el_ultimo;
int comida_y;
int comida_x;
int cantidad_comida=0;
struct POSICION
{
struct EJECUTA
{
int y;
int x;
int direccion;
}ejecuta[50];
}posicion[50];
//----prueba---
//------------
/*
* Direcciones:
* arriba = 1 = w = 119
* abajo = 2 = s = 115
* izq. = 3 = a = 97
* derch. = 4 = d = 100
*
*
* y, x = Posicion de la cabeza del serpiente
*/
main()
{
initscr();
bienvenida();
inicio();
mover();
getch();
endwin();
}
void inicio()
{
y=10;
x=25;
longitud=5;
posicion[1].ejecuta[1].y = 10;
posicion[1].ejecuta[1].x = 25;
posicion[1].ejecuta[1].direccion = 2;
posicion[2].ejecuta[1].y = 9;
posicion[2].ejecuta[1].x = 25;
posicion[2].ejecuta[1].direccion = 2;
posicion[3].ejecuta[1].y = 8;
posicion[3].ejecuta[1].x = 25;
posicion[3].ejecuta[1].direccion = 2;
posicion[4].ejecuta[1].y = 7;
posicion[4].ejecuta[1].x = 25;
posicion[4].ejecuta[1].direccion = 2;
posicion[5].ejecuta[1].y = 6;
posicion[5].ejecuta[1].x = 25;
posicion[5].ejecuta[1].direccion = 2;
comida();
}
void ordenes(int y, int x, int longitud, int direccion)
{
int aux;
for (aux=1;aux<=longitud;aux++)
{
el_ultimo=1;
while (posicion[aux].ejecuta[el_ultimo].direccion != 0)
{
el_ultimo++;
}
posicion[aux].ejecuta[el_ultimo].y = y;
posicion[aux].ejecuta[el_ultimo].x = x;
posicion[aux].ejecuta[el_ultimo].direccion = direccion;
}
}
void mover()
{
int aux;
int tiempo=1;
int aux_comida_y;
int aux_comida_x;
while (tiempo<=60000)
{
erase();
// iniciar la comida
move(comida_y,comida_x);
printw("*");
refresh();
// una vez que sea comido, generar mas comida
if (posicion[1].ejecuta[1].y == comida_y && posicion[1].ejecuta[1].x == comida_x)
{
aux_comida_y = comida_y;
aux_comida_x = comida_x;
comida();
++cantidad_comida;
}
// si toca algun tecla
if (kbhit())
{
dar_tecla();
}
for(aux=1; aux<=longitud;aux++)
{
ordena_posi_ejecutar(aux);
}
//dibujar los movimientos
for(aux=1; aux<=longitud;aux++)
{
switch(posicion[aux].ejecuta[1].direccion)
{//case 1,2,3,4
case 1:
posicion[aux].ejecuta[1].y = posicion[aux].ejecuta[1].y - 1;
move(posicion[aux].ejecuta[1].y,posicion[aux].ejecuta[1].x);
printw("o");
refresh();
break;
case 2:
posicion[aux].ejecuta[1].y = posicion[aux].ejecuta[1].y + 1;
move(posicion[aux].ejecuta[1].y,posicion[aux].ejecuta[1].x);
printw("o");
refresh();
break;
case 3:
posicion[aux].ejecuta[1].x = posicion[aux].ejecuta[1].x - 1;
move(posicion[aux].ejecuta[1].y,posicion[aux].ejecuta[1].x);
printw("o");
refresh();
break;
case 4:
posicion[aux].ejecuta[1].x = posicion[aux].ejecuta[1].x + 1;
move(posicion[aux].ejecuta[1].y,posicion[aux].ejecuta[1].x);
printw("o");
refresh();
break;
}
}
if (posicion[longitud].ejecuta[1].y == aux_comida_y &&
posicion[longitud].ejecuta[1].x == aux_comida_x)
{
++longitud;
//pasar todas las ordenes que tenga al ultimo
int aux_el_ultimo;
for(aux_el_ultimo=1;aux_el_ultimo<=el_ultimo;aux_el_ultimo++)
{
posicion[longitud].ejecuta[aux_el_ultimo].direccion =
posicion[longitud - 1].ejecuta[aux_el_ultimo].direccion;
posicion[longitud].ejecuta[aux_el_ultimo].y =
posicion[longitud - 1].ejecuta[aux_el_ultimo].y;
posicion[longitud].ejecuta[aux_el_ultimo].x =
posicion[longitud - 1].ejecuta[aux_el_ultimo].x;
}
switch(posicion[longitud - 1].ejecuta[1].direccion)
{
//case 1,2,3,4
case 1:
//posicion[longitud].ejecuta[1].y = posicion[longitud - 1].ejecuta[1].y + 1;
posicion[longitud].ejecuta[1].y = posicion[longitud - 1].ejecuta[1].y + 1;
posicion[longitud].ejecuta[1].x = posicion[longitud - 1].ejecuta[1].x;
break;
case 2:
posicion[longitud].ejecuta[1].y = posicion[longitud - 1].ejecuta[1].y - 1;
posicion[longitud].ejecuta[1].x = posicion[longitud - 1].ejecuta[1].x;
break;
case 3:
posicion[longitud].ejecuta[1].y = posicion[longitud - 1].ejecuta[1].y;
posicion[longitud].ejecuta[1].x = posicion[longitud - 1].ejecuta[1].x + 1;
break;
case 4:
posicion[longitud].ejecuta[1].y = posicion[longitud - 1].ejecuta[1].y;
posicion[longitud].ejecuta[1].x = posicion[longitud - 1].ejecuta[1].x - 1;
break;
}
aux_comida_y = comida_y;
aux_comida_x = comida_x;
}
// linea de separacion
int aux_linea;
for(aux_linea=0;aux_linea<=23;aux_linea++)
{
move(aux_linea,51);
printw("|");
}
move(2,53);
printw("Comistes: %i",cantidad_comida);
refresh();
usleep(250000);
tiempo++;
//-- si esta fura de rango
if (posicion[1].ejecuta[1].y <> 23 ||
posicion[1].ejecuta[1].x <> 50)
{
fin_juego();
}
//si toca propio cuerpo
for(aux=3;aux<=longitud;aux++)
{
if (posicion[1].ejecuta[1].y == posicion[aux].ejecuta[1].y &&
posicion[1].ejecuta[1].x == posicion[aux].ejecuta[1].x)
{
fin_juego();
}
}
}
}
void ordena_posi_ejecutar(int aux)
{
// posicion[aux].ejecutar[0] -> tmp, swap
int n_cambio;
int ejecutable = 0;
int aux_ejecutable =1;
// ver ordenes ya que ya dispone detro de cada
while(posicion[aux].ejecuta[aux_ejecutable].direccion != 0)
{
++ejecutable;
++aux_ejecutable;
}
//cuando solo tiene una orden, recta
if (ejecutable ==1)
{
//no hace nada
}else
{
if(posicion[aux].ejecuta[1].y == posicion[aux].ejecuta[2].y &&
posicion[aux].ejecuta[1].x == posicion[aux].ejecuta[2].x)
{
for (n_cambio=1;n_cambio<=ejecutable;n_cambio++)
{
posicion[aux].ejecuta[n_cambio - 1].direccion =
posicion[aux].ejecuta[n_cambio].direccion;
posicion[aux].ejecuta[n_cambio - 1].y = posicion[aux].ejecuta[n_cambio].y;
posicion[aux].ejecuta[n_cambio - 1].x = posicion[aux].ejecuta[n_cambio].x;
}
posicion[aux].ejecuta[ejecutable].direccion = 0;
}
}
}
void dar_tecla()
{
int tecla;
tecla = getchar();
/*--------
move(10,52);
printw("%i",tecla);
refresh();
getch();
//--------- */
switch(tecla)
{
//arriba
case 119:
if(posicion[1].ejecuta[1].direccion != 2)
ordenes(posicion[1].ejecuta[1].y , posicion[1].ejecuta[1].x, longitud, 1);
break;
// abajo
case 115:
if(posicion[1].ejecuta[1].direccion != 1)
ordenes(posicion[1].ejecuta[1].y , posicion[1].ejecuta[1].x, longitud, 2);
break;
//izquierda
case 97:
if(posicion[1].ejecuta[1].direccion != 4)
ordenes(posicion[1].ejecuta[1].y, posicion[1].ejecuta[1].x, longitud, 3);
break;
//derecha
case 100:
if(posicion[1].ejecuta[1].direccion != 3)
ordenes(posicion[1].ejecuta[1].y, posicion[1].ejecuta[1].x, longitud, 4);
break;
}
}
void comida()
{
// MAX = 24 * 80 , pero usar 24 * 50
// comida y , x son aleatorio
do{
srand(time(NULL));
comida_y = rand()% 25;
srand(time(NULL));
comida_x = rand() % 51;
}while (comida_y == 0 && comida_x ==0);
move(comida_y, comida_x);
printw("*");
refresh();
}
void fin_juego()
{
move(9,52);
printw("============================");
move(10,52);
printw(" G A M E O V E R ");
move(11,52);
printw("============================");
move(13,52);
printw("Pulse una tecla para salir");
refresh();
getch();
endwin();
exit(0);
}
void bienvenida()
{
move(1,0);
printw("················································");
move(2,0);
printw("··············································");
move(3,0);
printw("············@@@@@@@@@@@·················");
move(4,0);
printw("··········@@@@@@@@@@@@@@@···············");
move(5,0);
printw("·········@@@········@@@@@@····················");
move(6,0);
printw("·······@@@@············@@@@···················");
move(7,0);
printw("······@@@@··············@@@@··················");
move(8,0);
printw("······@@@@··············@@@@··················");
move(9,0);
printw("·····@@@@·······@@······@@@@··················");
move(10,0);
printw("·····@@@@······@@@·····@@@@···················");
move(11,0);
printw("·····@@@@·······@@@@@@@@@@····················");
move(12,0);
printw("·····@@@@·········@@@@@@·························");
move(13,0);
printw("······@@@@····································");
move(14,0);
printw("······@@@@··················//················");
move(15,0);
printw("·······@@@@················//··········{}····");
move(16,0);
printw("·········@@@···············\\\\·················");
move(17,0);
printw("··········@@@···············\\\\··||··||··||····");
move(18,0);
printw("·············@@·············//··||··||··||····");
move(19,0);
printw("···············@@@·········//····\\\\//···||····");
move(20,0);
printw("········································");
refresh();
int aux_linea;
for(aux_linea=0;aux_linea<=23;aux_linea++)
{
move(aux_linea,51);
printw("|");
}
refresh();
move(4,52);
printw("Game: SNAKE");
move(6,52);
printw("Autor: Sui Zhao");
move(7,52);
printw("Fecha: 24-05-09");
move(9,52);
printw("============================");
move(10,52);
printw(" S T A R T T H E G A M E ");
move(11,52);
printw("============================");
move(13,52);
printw(" Pulse una tecla");
move(14,52);
printw(" para empezar...");
refresh();
getch();
}
/***************** kbhit ********************/
void changemode(int dir)
{
static struct termios oldt, newt;
if ( dir == 1 )
{
tcgetattr( STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
}
else
tcsetattr( STDIN_FILENO, TCSANOW, &oldt);
}
int kbhit (void)
{
struct timeval tv;
fd_set rdfs;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&rdfs);
FD_SET (STDIN_FILENO, &rdfs);
select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &rdfs);
}
/*********************************************/
=== EOF ====
Saludos, Good Luck!!