#include #include #include #include #define I_VEL_T 6 // m/s #define I_VEN_T 4 // segundos #define I_APU_T 3 // segundos #define I_CPU_T 1 // segundos #define I_VEL_L 2 // m/s #define I_APU_L1 4 // segundos #define I_APU_L2 2 // segundos #define I_VEL_H 4 // m/s #define I_VEN_H 3 // segundos #define I_APU_H 5 // segundos #define ACC_COR 0 #define ACC_APU 1 #define ACC_CPU 2 #define ACC_VEN 3 typedef struct { int y, x; // coordenadas en el mapa del zombi int ay, ax; // coordenadas puerta/ventana char acc; // acción que está realizando int blo; // hasta segundo está bloqueado por una acción int oy, ox; // coordenadas anteriores char oc; // contenido del mapa para la posición anterior char tip; // tipo de zombi } ZOMBI; char mapa[30][100]= { "sssssssssssssssssssssssssssssssssss\x0", "s.................................s\x0", "s.................................s\x0", "s.................................s\x0", "s.................................s\x0", "s............##P##############....s\x0", "s............#...............#....s\x0", "s............#...............#....s\x0", "s............#...............#....s\x0", "s............##P##########...V....s\x0", "s............#...........#...#....s\x0", "s............#...........#...#....s\x0", "s............#...........#...#....s\x0", "s....####V####...........P...#....s\x0", "s....#.......#...........#...#....s\x0", "s....#.......#.......#########....s\x0", "s....#.......#.......#.......#....s\x0", "s....V.......P.......P.......#....s\x0", "s....#.......#.......#.......#....s\x0", "s....#.......#.......#.......#....s\x0", "s....#################.......#....s\x0", "s....#...#...........#.......#....s\x0", "s....V...P.....T.....P.......#....s\x0", "s....#...#...........#.......#....s\x0", "s....########V#####V######P###....s\x0", "s.................................s\x0", "s.................................s\x0", "s.................................s\x0", "s.................................s\x0", "sssssssssssssssssssssssssssssssssss\x0" }; int seg=0; int mt=I_VEL_T; ZOMBI b[10]; int nb; int by, bx; void pinta_mapa(void); void tecla(char c); void inc_seg(void); int valid_pos(int y, int x, char tip, int dist); void camino(int y, int x, char tip); int main(int argc, char *argv[]) { int buc; char c = 0; char actu_seg; // jugador b[0].y = 22; b[0].x = 15; b[0].tip = 'T'; b[0].acc = ACC_COR; b[0].blo = -1; b[0].oc = '.'; // zombis b[1].y = 25; b[1].x = 19; b[1].tip = 'L'; b[1].acc = ACC_COR; b[1].blo = -1; b[1].oc = '.'; mapa[b[1].y][b[1].x] = b[1].tip; b[2].y = 17; b[2].x = 4; b[2].tip = 'L'; b[2].acc = ACC_COR; b[2].blo = -1; b[2].oc = '.'; mapa[b[2].y][b[2].x] = b[2].tip; b[3].y = 4; b[3].x = 15; b[3].tip = 'L'; b[3].acc = ACC_COR; b[3].blo = -1; b[3].oc = '.'; mapa[b[3].y][b[3].x] = b[3].tip; b[4].y = 25; b[4].x = 13; b[4].tip = 'H'; b[4].acc = ACC_COR; b[4].blo = -1; b[4].oc = '.'; mapa[b[4].y][b[4].x] = b[4].tip; b[5].y = 22; b[5].x = 4; b[5].tip = 'H'; b[5].acc = ACC_COR; b[5].blo = -1; b[5].oc = '.'; mapa[b[5].y][b[5].x] = b[5].tip; b[6].y = 12; b[6].x = 9; b[6].tip = 'H'; b[6].acc = ACC_COR; b[6].blo = -1; b[6].oc = '.'; mapa[b[6].y][b[6].x] = b[6].tip; // nº de zombis nb = 6; system("stty -echo"); system("stty cbreak"); printf ("\nHorror en el parque acuático\n\n"); printf ("Teclas:\n"); printf (" W - Arriba\n"); printf (" A - Izquierda\n"); printf (" S - Abajo\n"); printf (" D - Derecha\n\n"); printf (" X - No mover\n"); printf (" P - Abrir/cerrar puerta\n\n"); printf (" Q - Salir\n\n"); printf ("Intro para comenzar...\n\n"); getchar(); pinta_mapa(); while(c!='Q') { // entrada teclado solamante cuando esta corriendo if (b[0].acc == ACC_COR) { c = getchar(); if (c>='a') c='A'+(c-'a'); tecla(c); } actu_seg = 1; // jugador // si está corriendo y aun tiene movimientos no incrementar segundos if (b[0].acc == ACC_COR && mt != 0) actu_seg = 0; // si está corriendo y no tiene movimientos incrementar segundos if (b[0].acc == ACC_COR && mt == 0) mt = I_VEL_T; // liberar acciones terminadas jugador y zombis for (buc=0; buc<=nb; buc++) { if (b[buc].acc != ACC_COR && b[buc].blo == seg) { if (b[buc].acc == ACC_APU) mapa[b[buc].ay][b[buc].ax] = 'p'; if (b[buc].acc == ACC_CPU) mapa[b[buc].ay][b[buc].ax] = 'P'; b[buc].acc = ACC_COR; b[buc].blo = 0; if (b[buc].tip == 'T') mt = I_VEL_T; } } // incrementar segundos y movimentos zombis if (actu_seg) inc_seg(); // actualizar pantalla pinta_mapa(); // si te han cazado for (buc=1; buc<=nb; buc++) { if (b[buc].y == b[0].y && b[buc].x == b[0].x) { mapa[b[0].y][b[0].x] = 'X'; pinta_mapa(); printf ("*** MUERTO ***\n\n"); c = 'Q'; } } // si te has salvado if (mapa[b[0].y][b[0].x+1] == 's' || mapa[b[0].y][b[0].x-1] == 's' || mapa[b[0].y+1][b[0].x] == 's' || mapa[b[0].y-1][b[0].x] == 's') { mapa[b[0].y][b[0].x] = '.'; pinta_mapa(); printf ("*** SALVADO ***\n\n"); c = 'Q'; } } system("stty echo"); system("stty -cbreak"); } void tecla(char c) { char actu_pos; int actu_dy, actu_dx; // indicador de si debe actualizar posición o no actu_pos = 0; // parado if (c=='X') { mt--; } if (c=='P') { if (mapa[b[0].y][b[0].x-1]=='P') { b[0].acc = ACC_APU; b[0].blo = seg + I_APU_T; b[0].ay = b[0].y; b[0].ax = b[0].x-1; } if (mapa[b[0].y][b[0].x-1]=='p') { b[0].acc = ACC_CPU; b[0].blo = seg + I_CPU_T; b[0].oy = b[0].y; b[0].ox = b[0].x-1; } if (mapa[b[0].y][b[0].x+1]=='P') { b[0].acc = ACC_APU; b[0].blo = seg + I_APU_T; b[0].ay = b[0].y; b[0].ax = b[0].x+1; } if (mapa[b[0].y][b[0].x+1]=='p') { b[0].acc = ACC_CPU; b[0].blo = seg + I_CPU_T; b[0].ay = b[0].y; b[0].ax = b[0].x+1; } if (mapa[b[0].y+1][b[0].x]=='P') { b[0].acc = ACC_APU; b[0].blo = seg + I_APU_T; b[0].ay = b[0].y+1; b[0].ax = b[0].x; } if (mapa[b[0].y+1][b[0].x]=='p') { b[0].acc = ACC_CPU; b[0].blo = seg + I_CPU_T; b[0].ay = b[0].y+1; b[0].ax = b[0].x; } if (mapa[b[0].y-1][b[0].x]=='P') { b[0].acc = ACC_APU; b[0].blo = seg + I_APU_T; b[0].ay = b[0].y-1; b[0].ax = b[0].x; } if (mapa[b[0].y-1][b[0].x]=='p') { b[0].acc = ACC_CPU; b[0].blo = seg + I_CPU_T; b[0].ay = b[0].y-1; b[0].ax = b[0].x; } } if (c=='A') { if (mapa[b[0].y][b[0].x-1]=='V') { b[0].acc = ACC_VEN; b[0].blo = seg + I_VEN_T; actu_pos = 1; actu_dy = 0; actu_dx = -1; } if (mapa[b[0].y][b[0].x-1]=='.' || mapa[b[0].y][b[0].x-1]=='p') { actu_pos = 1; actu_dy = 0; actu_dx = -1; } } if (c=='D') { if (mapa[b[0].y][b[0].x+1]=='V') { b[0].acc = ACC_VEN; b[0].blo = seg + I_VEN_T; actu_pos = 1; actu_dy = 0; actu_dx = 1; } if (mapa[b[0].y][b[0].x+1]=='.' || mapa[b[0].y][b[0].x+1]=='p') { actu_pos = 1; actu_dy = 0; actu_dx = 1; } } if (c=='S') { if (mapa[b[0].y+1][b[0].x]=='V') { b[0].acc = ACC_VEN; b[0].blo = seg + I_VEN_T; actu_pos = 1; actu_dy = 1; actu_dx = 0; } if (mapa[b[0].y+1][b[0].x]=='.' || mapa[b[0].y+1][b[0].x]=='p') { actu_pos = 1; actu_dy = 1; actu_dx = 0; } } if (c=='W') { if (mapa[b[0].y-1][b[0].x]=='V') { b[0].acc = ACC_VEN; b[0].blo = seg + I_VEN_T; actu_pos = 1; actu_dy = -1; actu_dx = 0; } if (mapa[b[0].y-1][b[0].x]=='.' || mapa[b[0].y-1][b[0].x]=='p') { actu_pos = 1; actu_dy = -1; actu_dx = 0; } } if (actu_pos) { mapa[b[0].y][b[0].x] = b[0].oc; b[0].oc = mapa[b[0].y+actu_dy][b[0].x+actu_dx]; mapa[b[0].y+actu_dy][b[0].x+actu_dx] = 'T'; b[0].y += actu_dy; b[0].x += actu_dx; mt--; } } void pinta_mapa(void) { int buc; system("clear"); for(buc=0; buc<30; buc++) { printf("%s\n", mapa[buc]); } printf("\nSegundo: %i Pasos: %i\n", seg, mt); printf("\nJugador: %c (%02i:%02i) ", b[0].tip, b[0].y, b[0].x); if (b[0].acc != ACC_COR) { if (b[0].acc == ACC_VEN) { printf("[VENTANA] "); } if (b[0].acc == ACC_APU || b[0].acc == ACC_CPU) { printf("[PUERTA] "); } } else { printf("[CORRIENDO] "); } printf ("Seg. fin: %i\n\n", b[0].blo); // mostrar acciones zombis for (buc=1; buc<=nb; buc++) { printf (" Zombi: %c (%02i:%02i) ", b[buc].tip, b[buc].y, b[buc].x); if (b[buc].acc == ACC_COR) printf ("[CORRIENDO] "); if (b[buc].acc == ACC_APU) printf ("[PUERTA] "); if (b[buc].acc == ACC_VEN) printf ("[VENTANA] "); printf ("Seg. fin: %i\n", b[buc].blo); } printf("\n"); } void inc_seg(void) { int q, dx, dy; int lb; // incrementar segundos seg++; // tratamiento zombis for (lb=1; lb<=nb; lb++) { if (b[lb].tip == 'L') { for (q=I_VEL_L; q > 0 && b[lb].acc == ACC_COR; q--) { // buscar dirección a tomar camino(b[lb].y, b[lb].x, b[lb].tip); // restaurar posición antigua mapa[b[lb].y][b[lb].x] = b[lb].oc; // abrir puerta if (mapa[b[lb].y+by][b[lb].x+bx] == 'P') { b[lb].acc = ACC_APU; if (b[lb].blo == -1) { // primera puerta b[lb].blo = seg + I_APU_L1; } else { // siguientes b[lb].blo = seg + I_APU_L2; } b[lb].ay = b[lb].y + by; b[lb].ax = b[lb].x + bx; by = 0; bx = 0; } // actualizar nueva posición b[lb].oc = mapa[b[lb].y+by][b[lb].x+bx]; mapa[b[lb].y+by][b[lb].x+bx]=b[lb].tip; b[lb].y += by; b[lb].x += bx; // refrescar pantalla pinta_mapa(); printf ("[MONSTRUOS]\n"); usleep(100*1000); } } if (b[lb].tip == 'H') { for (q=I_VEL_H; q > 0 && b[lb].acc == ACC_COR; q--) { // buscar dirección a tomar camino(b[lb].y, b[lb].x, b[lb].tip); // restaurar posición antigua mapa[b[lb].y][b[lb].x] = b[lb].oc; // abrir puerta if (mapa[b[lb].y+by][b[lb].x+bx] == 'P') { b[lb].acc = ACC_APU; b[lb].blo = seg + I_APU_H; b[lb].ay = b[lb].y + by; b[lb].ax = b[lb].x + bx; by = 0; bx = 0; } // ventana if (mapa[b[lb].y+by][b[lb].x+bx] == 'V') { b[lb].acc = ACC_VEN; b[lb].blo = seg + I_VEN_H; } // actualizar nueva posición b[lb].oc = mapa[b[lb].y+by][b[lb].x+bx]; mapa[b[lb].y+by][b[lb].x+bx]=b[lb].tip; b[lb].y += by; b[lb].x += bx; // refrescar pantalla pinta_mapa(); printf ("[MONSTRUOS]\n"); usleep(100*1000); } } } } // camino directo sin tener en cuenta tiempo para abrir puertas o pasar ventanas void camino(int y, int x, char tip) { int cola[1000][3]; int i, ti, c, s; int ty, tx; char desc, fin; memset(cola, 0, sizeof(cola)); // origen: posición jugador cola[0][0] = b[0].y; cola[0][1] = b[0].x; cola[0][2] = 0; i = 0; ti = 1; fin = 0; // toda la lista tratada o llegada al destino: posición zombi while (i