-
-
Save parzibyte/1434b4dcd1f6a2d5a8a4ed6218d4750b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
____ _____ _ _ _ | |
| _ \ | __ \ (_) | | | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___ | |
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \ | |
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/ | |
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___| | |
__/ | __/ | | |
|___/ |___/ | |
____________________________________ | |
/ Si necesitas ayuda, contáctame en \ | |
\ https://parzibyte.me / | |
------------------------------------ | |
\ ^__^ | |
\ (oo)\_______ | |
(__)\ )\/\ | |
||----w | | |
|| || | |
Creado por Parzibyte (https://parzibyte.me). | |
------------------------------------------------------------------------------------------------ | |
| IMPORTANTE | | |
Si vas a borrar este encabezado, considera: | |
Seguirme: https://parzibyte.me/blog/sigueme/ | |
Y compartir mi blog con tus amigos | |
También tengo canal de YouTube: https://www.youtube.com/channel/UCroP4BTWjfM0CkGB6AFUoBg?sub_confirmation=1 | |
Twitter: https://twitter.com/parzibyte | |
Facebook: https://facebook.com/parzibyte.fanpage | |
Instagram: https://instagram.com/parzibyte | |
Hacer una donación vía PayPal: https://paypal.me/LuisCabreraBenito | |
------------------------------------------------------------------------------------------------ | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#define ARQUERO_J1 '1' | |
#define ARQUERO_J2 '2' | |
#define ARBOL 'X' | |
#define ESPACIO_VACIO ' ' | |
#define DIRECCION_IZQUIERDA 'L' | |
#define DIRECCION_DERECHA 'R' | |
#define DIRECCION_ARRIBA 'U' | |
#define DIRECCION_ABAJO 'D' | |
#define OPCION_MOVER 'm' | |
#define OPCION_DISPARAR 'd' | |
#define DISTANCIA_MAXIMA_DISPARO 5 | |
#define ROUNDS_PARA_PERDER 2 | |
/* | |
* Ajustes del juego | |
* */ | |
int medidaGlobalBosque; // La medida del bosque | |
/* | |
* Datos del juego | |
* Llevar control de ubicación de arqueros y de los flechazos recibidos | |
* */ | |
int coordenada_y_jugador_1 = 0, | |
coordenada_x_jugador_1 = 0, | |
coordenada_y_jugador_2 = 0, | |
coordenada_x_jugador_2 = 0, | |
flechazos_recibidos_jugador_1 = 0, | |
flechazos_recibidos_jugador_2 = 0; | |
/* | |
* Funciones que componen al juego | |
* */ | |
// Devuelve un número aleatorio entre minimo y maximo, incluyendo a minimo y maximo | |
int aleatorio_en_rango(int minimo, int maximo) { | |
return minimo + rand() / (RAND_MAX / (maximo - minimo + 1) + 1); | |
} | |
void limpiar_bosque(char bosque[medidaGlobalBosque][medidaGlobalBosque]) { | |
for (int y = 0; y < medidaGlobalBosque; y++) { | |
for (int x = 0; x < medidaGlobalBosque; x++) { | |
bosque[y][x] = ESPACIO_VACIO; | |
} | |
} | |
} | |
void colocar_arboles_en_bosque(char bosque[medidaGlobalBosque][medidaGlobalBosque]) { | |
int contador = 0; | |
while (contador < medidaGlobalBosque) { | |
int x = aleatorio_en_rango(0, medidaGlobalBosque - 1); | |
int y = aleatorio_en_rango(0, medidaGlobalBosque - 1); | |
// Colocar árboles solo si no hay nada (en especial no debemos colocarlos en donde haya jugadores) | |
if (bosque[y][x] == ESPACIO_VACIO) { | |
bosque[y][x] = ARBOL; | |
contador++; | |
} | |
} | |
} | |
void colocar_jugadores_en_bosque(char bosque[medidaGlobalBosque][medidaGlobalBosque]) { | |
bosque[coordenada_y_jugador_1][coordenada_x_jugador_1] = ARQUERO_J1; | |
bosque[coordenada_y_jugador_2][coordenada_x_jugador_2] = ARQUERO_J2; | |
} | |
void imprimir_bosque(char bosque[medidaGlobalBosque][medidaGlobalBosque]) { | |
int contador = 0; | |
// Un separador | |
printf("\n\n"); | |
while (contador < medidaGlobalBosque) { | |
printf("_____"); | |
contador++; | |
} | |
printf("\n"); | |
// Letras | |
printf("| "); | |
char c = 'A'; | |
contador = 0; | |
while (contador < medidaGlobalBosque) { | |
printf("| %c ", c); | |
c++; | |
contador++; | |
} | |
printf("|\n"); | |
for (int y = 0; y < medidaGlobalBosque; y++) { | |
printf("| %d |", y + 1); | |
for (int x = 0; x < medidaGlobalBosque; x++) { | |
printf(" %c |", bosque[y][x]); | |
} | |
printf("\n"); | |
} | |
} | |
int jugador_puede_moverse(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador, char direccion) { | |
int x, y; | |
if (jugador == ARQUERO_J1) { | |
x = coordenada_x_jugador_1; | |
y = coordenada_y_jugador_1; | |
} else { | |
x = coordenada_x_jugador_2; | |
y = coordenada_y_jugador_2; | |
} | |
if (direccion == DIRECCION_ABAJO) { | |
y++; | |
} else if (direccion == DIRECCION_ARRIBA) { | |
y--; | |
} else if (direccion == DIRECCION_DERECHA) { | |
x++; | |
} else if (direccion == DIRECCION_IZQUIERDA) { | |
x--; | |
} else { | |
// Si no es ninguna dirección válida, regresamos false | |
return 0; | |
} | |
// Luego de modificar las coordenadas, vemos si son válidas. Comprobamos si están dentro del tablero | |
if (x < 0 || x >= medidaGlobalBosque || y < 0 || y >= medidaGlobalBosque) { | |
printf("Posicion fuera del tablero\n"); | |
return 0; | |
} | |
// Y comprobamos si no es un árbol u otro jugador | |
if (bosque[y][x] == ESPACIO_VACIO) { | |
return 1; | |
} else { | |
printf("Espacio no vacio\n"); | |
return 0; | |
} | |
} | |
void mover(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador, char direccion) { | |
printf("El jugador %c elige moverse hacia ", jugador); | |
int xOriginal, yOriginal; | |
if (jugador == ARQUERO_J1) { | |
xOriginal = coordenada_x_jugador_1; | |
yOriginal = coordenada_y_jugador_1; | |
} else { | |
xOriginal = coordenada_x_jugador_2; | |
yOriginal = coordenada_y_jugador_2; | |
} | |
int nuevaX = xOriginal, nuevaY = yOriginal; | |
if (direccion == DIRECCION_ABAJO) { | |
printf(" abajo\n"); | |
nuevaY++; | |
} else if (direccion == DIRECCION_ARRIBA) { | |
printf(" arriba\n"); | |
nuevaY--; | |
} else if (direccion == DIRECCION_DERECHA) { | |
printf(" la derecha\n"); | |
nuevaX++; | |
} else if (direccion == DIRECCION_IZQUIERDA) { | |
printf(" la izquierda\n"); | |
nuevaX--; | |
} | |
// Limpiamos la posición anterior | |
bosque[yOriginal][xOriginal] = ESPACIO_VACIO; | |
// Y movemos al personaje | |
bosque[nuevaY][nuevaX] = jugador; | |
// Guardamos las coordenadas | |
if (jugador == ARQUERO_J1) { | |
coordenada_x_jugador_1 = nuevaX; | |
coordenada_y_jugador_1 = nuevaY; | |
} else { | |
coordenada_x_jugador_2 = nuevaX; | |
coordenada_y_jugador_2 = nuevaY; | |
} | |
} | |
void consumir_nueva_linea(void) { | |
int c; | |
do { | |
c = getchar(); | |
} while (c != EOF && c != '\n'); | |
} | |
char solicitarMovimientoJugador(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador) { | |
char direccion = DIRECCION_IZQUIERDA; | |
while (1) { | |
printf("%c - Arriba\n%c - Abajo\n%c - Derecha\n%c - Izquierda\nJugador %c. Ingrese la direccion para moverse: ", | |
DIRECCION_ARRIBA, DIRECCION_ABAJO, DIRECCION_DERECHA, DIRECCION_IZQUIERDA, jugador); | |
scanf("%c", &direccion); | |
consumir_nueva_linea(); | |
if (jugador_puede_moverse(bosque, jugador, direccion)) { | |
return direccion; | |
} else { | |
printf("No se puede mover hacia esa direccion. Intente de nuevo\n"); | |
} | |
} | |
} | |
int esDireccionValida(char direccion) { | |
if (direccion == DIRECCION_ARRIBA || direccion == DIRECCION_DERECHA || direccion == DIRECCION_ABAJO || | |
direccion == DIRECCION_IZQUIERDA) { | |
return 1; | |
} | |
return 0; | |
} | |
char solicitarDireccionDisparo(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador) { | |
char direccion = DIRECCION_IZQUIERDA; | |
while (1) { | |
printf("%c - Arriba\n%c - Abajo\n%c - Derecha\n%c - Izquierda\nJugador %c. Ingrese la direccion para disparar: ", | |
DIRECCION_ARRIBA, DIRECCION_ABAJO, DIRECCION_DERECHA, DIRECCION_IZQUIERDA, jugador); | |
scanf("%c", &direccion); | |
consumir_nueva_linea(); | |
if (esDireccionValida(direccion)) { | |
return direccion; | |
} else { | |
printf("No puede disparar en esa direccion. Intente de nuevo\n"); | |
} | |
} | |
} | |
char oponente_de(char jugador) { | |
if (jugador == ARQUERO_J1) { | |
return ARQUERO_J2; | |
} else { | |
return ARQUERO_J1; | |
} | |
} | |
int dispararIzquierda(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador) { | |
int x, y; | |
if (jugador == ARQUERO_J1) { | |
x = coordenada_x_jugador_1; | |
y = coordenada_y_jugador_1; | |
} else { | |
x = coordenada_x_jugador_2; | |
y = coordenada_y_jugador_2; | |
} | |
int metrosAvance = 0; | |
while (metrosAvance < DISTANCIA_MAXIMA_DISPARO && x > 0) { | |
x--; | |
metrosAvance++; | |
// La flecha impactó con un árbol, así que no llegó al objetivo | |
if (bosque[y][x] == ARBOL) { | |
printf("Flecha impacta con un arbol"); | |
return 0; | |
} else if (bosque[y][x] == oponente_de(jugador)) { | |
// Significa que le ha disparado al oponente | |
printf("Flecha impacta al jugador %c\n", oponente_de(jugador)); | |
return 1; | |
} | |
} | |
// La flecha acabó su recorrido y no chocó con un árbol ni con el oponente | |
printf("Flecha ha terminado su recorrido"); | |
return 0; | |
} | |
int dispararDerecha(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador) { | |
int x, y; | |
if (jugador == ARQUERO_J1) { | |
x = coordenada_x_jugador_1; | |
y = coordenada_y_jugador_1; | |
} else { | |
x = coordenada_x_jugador_2; | |
y = coordenada_y_jugador_2; | |
} | |
int metrosAvance = 0; | |
while (metrosAvance < DISTANCIA_MAXIMA_DISPARO && x < medidaGlobalBosque - 1) { | |
x++; | |
metrosAvance++; | |
// La flecha impactó con un árbol, así que no llegó al objetivo | |
if (bosque[y][x] == ARBOL) { | |
printf("Flecha impacta con un arbol"); | |
return 0; | |
} else if (bosque[y][x] == oponente_de(jugador)) { | |
// Significa que le ha disparado al oponente | |
printf("Flecha impacta al jugador %c\n", oponente_de(jugador)); | |
return 1; | |
} | |
} | |
// La flecha acabó su recorrido y no chocó con un árbol ni con el oponente | |
printf("Flecha ha terminado su recorrido"); | |
return 0; | |
} | |
int dispararArriba(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador) { | |
int x, y; | |
if (jugador == ARQUERO_J1) { | |
x = coordenada_x_jugador_1; | |
y = coordenada_y_jugador_1; | |
} else { | |
x = coordenada_x_jugador_2; | |
y = coordenada_y_jugador_2; | |
} | |
int metrosAvance = 0; | |
while (metrosAvance < DISTANCIA_MAXIMA_DISPARO && y > 0) { | |
y--; | |
metrosAvance++; | |
// La flecha impactó con un árbol, así que no llegó al objetivo | |
if (bosque[y][x] == ARBOL) { | |
printf("Flecha impacta con un arbol"); | |
return 0; | |
} else if (bosque[y][x] == oponente_de(jugador)) { | |
// Significa que le ha disparado al oponente | |
printf("Flecha impacta al jugador %c\n", oponente_de(jugador)); | |
return 1; | |
} | |
} | |
// La flecha acabó su recorrido y no chocó con un árbol ni con el oponente | |
printf("Flecha ha terminado su recorrido"); | |
return 0; | |
} | |
int dispararAbajo(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador) { | |
int x, y; | |
if (jugador == ARQUERO_J1) { | |
x = coordenada_x_jugador_1; | |
y = coordenada_y_jugador_1; | |
} else { | |
x = coordenada_x_jugador_2; | |
y = coordenada_y_jugador_2; | |
} | |
int metrosAvance = 0; | |
while (metrosAvance < DISTANCIA_MAXIMA_DISPARO && y < medidaGlobalBosque - 1) { | |
y++; | |
metrosAvance++; | |
// La flecha impactó con un árbol, así que no llegó al objetivo | |
if (bosque[y][x] == ARBOL) { | |
printf("Flecha impacta con un arbol"); | |
return 0; | |
} else if (bosque[y][x] == oponente_de(jugador)) { | |
// Significa que le ha disparado al oponente | |
printf("Flecha impacta al jugador %c\n", oponente_de(jugador)); | |
return 1; | |
} | |
} | |
// La flecha acabó su recorrido y no chocó con un árbol ni con el oponente | |
printf("Flecha ha terminado su recorrido"); | |
return 0; | |
} | |
int disparar(char bosque[medidaGlobalBosque][medidaGlobalBosque], char jugador, char direccion) { | |
printf("El jugador %c dispara la flecha ", jugador); | |
int acertado; | |
switch (direccion) { | |
case DIRECCION_IZQUIERDA: | |
printf("a la izquierda\n"); | |
acertado = dispararIzquierda(bosque, jugador); | |
break; | |
case DIRECCION_DERECHA: | |
printf("a la derecha\n"); | |
acertado = dispararDerecha(bosque, jugador); | |
break; | |
case DIRECCION_ARRIBA: | |
printf("hacia arriba\n"); | |
acertado = dispararArriba(bosque, jugador); | |
break; | |
case DIRECCION_ABAJO: | |
default: | |
printf("hacia abajo\n"); | |
acertado = dispararAbajo(bosque, jugador); | |
break; | |
} | |
// Si acertó, entonces aumentamos el conteo de flechas recibidas para el oponente | |
if (acertado) { | |
if (oponente_de(jugador) == ARQUERO_J1) { | |
flechazos_recibidos_jugador_1++; | |
} else { | |
flechazos_recibidos_jugador_2++; | |
} | |
} | |
// Y devolvemos el estado por si nuestro invocador lo requiere | |
return acertado; | |
} | |
int es_ganador(char jugador) { | |
if (jugador == ARQUERO_J1) { | |
return flechazos_recibidos_jugador_2 >= ROUNDS_PARA_PERDER; | |
} else { | |
return flechazos_recibidos_jugador_1 >= ROUNDS_PARA_PERDER; | |
} | |
} | |
void reiniciar_posicion_arqueros() { | |
coordenada_x_jugador_1 = 0; | |
coordenada_y_jugador_1 = medidaGlobalBosque - 1; | |
coordenada_x_jugador_2 = medidaGlobalBosque - 1; | |
coordenada_y_jugador_2 = 0; | |
} | |
void preparar_nuevo_round(char bosque[medidaGlobalBosque][medidaGlobalBosque]) { | |
limpiar_bosque(bosque); | |
reiniciar_posicion_arqueros(); | |
colocar_jugadores_en_bosque(bosque); | |
colocar_arboles_en_bosque(bosque); | |
} | |
void preparar_nueva_partida(char bosque[medidaGlobalBosque][medidaGlobalBosque]) { | |
preparar_nuevo_round(bosque); | |
flechazos_recibidos_jugador_1 = 0; | |
flechazos_recibidos_jugador_2 = 0; | |
} | |
int solicitarMedida() { | |
int medida; | |
while (1) { | |
printf("Ingrese la medida del bosque. Puede ser de 5, 7 o 9: "); | |
scanf("%d", &medida); | |
consumir_nueva_linea(); | |
if (medida == 5 || medida == 7 || medida == 9) { | |
return medida; | |
} else { | |
printf("La medida no es correcta\n"); | |
} | |
} | |
} | |
char solicitar_jugador() { | |
char jugador = ARQUERO_J1; | |
while (1) { | |
printf("%c - Arquero 1\n%c - Arquero 2. Seleccione quien empieza la partida: ", ARQUERO_J1, ARQUERO_J2); | |
scanf("%c", &jugador); | |
consumir_nueva_linea(); | |
if (jugador == ARQUERO_J1 || jugador == ARQUERO_J2) { | |
return jugador; | |
} else { | |
printf("Jugador incorrecto\n"); | |
} | |
} | |
} | |
char solicitar_eleccion(char jugador) { | |
char eleccion = ' '; | |
while (1) { | |
printf("%c - Mover\n%c - Disparar. Jugador %c seleccione una opcion: ", OPCION_MOVER, OPCION_DISPARAR, jugador); | |
scanf("%c", &eleccion); | |
consumir_nueva_linea(); | |
if (eleccion == OPCION_MOVER || eleccion == OPCION_DISPARAR) { | |
return eleccion; | |
} else { | |
printf("La opcion no es correcta\n"); | |
} | |
} | |
} | |
void imprimir_estados_salud() { | |
printf("Jugador %c. Flechazos recibidos: %d\n", ARQUERO_J1, flechazos_recibidos_jugador_1); | |
printf("Jugador %c. Flechazos recibidos: %d\n", ARQUERO_J2, flechazos_recibidos_jugador_2); | |
} | |
void iniciar_nueva_partida() { | |
char bosque[medidaGlobalBosque][medidaGlobalBosque]; | |
preparar_nueva_partida(bosque); | |
char jugador = solicitar_jugador(); | |
while (1) { | |
colocar_jugadores_en_bosque(bosque); | |
imprimir_bosque(bosque); | |
char eleccion = solicitar_eleccion(jugador); | |
if (eleccion == OPCION_DISPARAR) { | |
char direccion_del_disparo = solicitarDireccionDisparo(bosque, jugador); | |
int acertado = disparar(bosque, jugador, direccion_del_disparo); | |
// Si ha acertado, marcamos nuevo round | |
if (acertado) { | |
printf("El flechazo es acertado!. Inicia nuevo round\n"); | |
imprimir_estados_salud(); | |
preparar_nuevo_round(bosque); | |
} | |
} else if (eleccion == OPCION_MOVER) { | |
char direccion_del_movimiento = solicitarMovimientoJugador(bosque, jugador); | |
mover(bosque, jugador, direccion_del_movimiento); | |
} | |
if (es_ganador(jugador)) { | |
printf("El jugador %c gana!\n", jugador); | |
// Con el return terminamos el juego | |
return; | |
} | |
jugador = oponente_de(jugador); | |
} | |
} | |
void jugar() { | |
srand(getpid()); | |
char eleccion = 's'; | |
while (eleccion == 's') { | |
medidaGlobalBosque = solicitarMedida(); | |
iniciar_nueva_partida(); | |
printf("Jugar de nuevo? [s/n]: "); | |
scanf("%c", &eleccion); | |
consumir_nueva_linea(); | |
} | |
} | |
int main() { | |
jugar(); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment