Skip to content

Instantly share code, notes, and snippets.

@parzibyte
Created May 19, 2021
Embed
What would you like to do?
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
____________________________________
/ 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