diff --git a/azar.c b/azar.c new file mode 100644 index 0000000..fd47323 --- /dev/null +++ b/azar.c @@ -0,0 +1,27 @@ +// Este fichero se le da al alumno +#include <time.h> // time() +#include <stdlib.h> // rand(), srand() +#include <stdio.h> // printf() +#include "azar.h" + +/* + * inicializar_azar() se tiene que ejecutar una vez al principio del main + * para inicializar la generación de números aleatorios + */ +//void inicializar_azar() { + /* + * Para que la sequencia de numeros aleatorios sea igual en cada + * ejecucion usad el srand (0) en lugar del srand(time). + */ + //srand(0); +// srand( (unsigned)time( NULL ) ); +//} + +/* + * numero_al_azar(max) devuelve un número entero al azar entre 0 y max-1 + */ +int numero_al_azar(int max) { + srand(time(NULL)); + return ( rand() % max); +} + diff --git a/azar.h b/azar.h new file mode 100644 index 0000000..b535198 --- /dev/null +++ b/azar.h @@ -0,0 +1,9 @@ +// Este fichero se le da al alumno +#ifndef AZAR_H +#define AZAR_H + +void inicializar_azar(); +int numero_al_azar(int max); + +#endif /* AZAR_H */ + diff --git a/duerme.c b/duerme.c new file mode 100644 index 0000000..9347255 --- /dev/null +++ b/duerme.c @@ -0,0 +1,47 @@ +// Este fichero se le da al alumno +#include <time.h> +#include "duerme.h" + +#define UN_RATO_SEGUNDOS 1 // 1 segundo +#define UN_RATO_NANOSEGUNDOS 500000000 // 0.5 segundos + +/* + * Hace que la ejecucion del programa se detenga durante + * el numero de segundos que se le pasa por parametro + */ +void duerme_n_segundos(long segundos) { + struct timespec tim, tim2; + tim.tv_sec = segundos; + tim.tv_nsec = 0; + + nanosleep(&tim , &tim2); +} + +/* + * Hace que la ejecucion del programa se detenga durante + * el numero de nanosegundos que se le pasa por parametro + */ +void duerme_n_nanosegundos(long nanosegundos) { + struct timespec tim, tim2; + tim.tv_sec = 0; + tim.tv_nsec = nanosegundos; + + nanosleep(&tim , &tim2); +} + +/* + * Hace que la ejecucion del programa se detenga durante + * un numero de segundos predeterminado + */ +void duerme_un_rato() { + duerme_n_segundos(UN_RATO_SEGUNDOS); +} + +/* + * Hace que la ejecucion del programa se detenga durante + * un numero de nanosegundos predeterminado + */ +void duerme_un_nano_rato() { + duerme_n_nanosegundos(UN_RATO_NANOSEGUNDOS); +} + diff --git a/duerme.h b/duerme.h new file mode 100644 index 0000000..c3024d0 --- /dev/null +++ b/duerme.h @@ -0,0 +1,11 @@ +// Este fichero se le da al alumno +#ifndef DUERME_H +#define DUERME_H + +void duerme_n_segundos(long segundos); +void duerme_n_nanosegundos(long nanosegundos); +void duerme_un_rato(); +void duerme_un_nano_rato(); + +#endif /* DUERME_H */ + diff --git a/ficha.c b/ficha.c new file mode 100644 index 0000000..4998af2 --- /dev/null +++ b/ficha.c @@ -0,0 +1,37 @@ +#include <stdio.h> +typedef struct{ + int num1, num2; +}t_ficha; + +void inicializar_ficha (t_ficha *ficha, int i, int j); +void imprimir_ficha (t_ficha f, int visible); +void girar_ficha (t_ficha *ficha); +int doble(); + +void imprimir_ficha(t_ficha ficha, int visible){ + + printf("%d:%d|", ficha.num1, ficha.num2); +} + +void girar_ficha(t_ficha *ficha){ // num1 es canvia per num2 i al contrari + int aux, i; + + aux=ficha->num1; + ficha->num1=ficha->num2; + ficha->num2=aux; + +} + +int doble() +{ t_ficha ficha[28]; + int i; + + if(ficha[i].num1==ficha[i].num2) //Si es un doble num1=num2 + return(1); + else return(0); +} + +void inicializar_ficha (t_ficha *ficha, int i, int j) { + ficha->num2=j; + ficha->num1=i; + } diff --git a/ficha.h b/ficha.h new file mode 100644 index 0000000..f2cf234 --- /dev/null +++ b/ficha.h @@ -0,0 +1,18 @@ +#ifndef FICHA_H +#define FICHA_H + +#define FALSE 0 +#define TRUE 1 + +#define NUM_FICHAS_DOMINO 28 + +typedef struct{ + int num1, num2; +}t_ficha; + +void inicializar_ficha(t_ficha *p_f, int a, int b); +void girar_ficha(t_ficha *p_f); +void imprimir_ficha(t_ficha f, int visible); + +#endif // FICHA_H + diff --git a/jugador.c b/jugador.c new file mode 100644 index 0000000..ad04bc7 --- /dev/null +++ b/jugador.c @@ -0,0 +1,112 @@ +#include "ficha.h" +#include <stdio.h> + +#define MIN_JUGADORES 2 +#define MAX_JUGADORES 4 + +#define T_HUMANO 1 +#define T_ROBOT 2 + +#define TRUE 1 +#define FALSE 0 + +typedef struct +{ + int n_fichas; + t_ficha f[NUM_FICHAS_DOMINO]; // Fichas que tiene + int tipo; + int peso; +} t_jugador; + +typedef struct +{ + int n_jugadores; + int un_humano; // TRUE or FALSE + int turno; + t_jugador j[MAX_JUGADORES]; // Fichas que tiene y otras cosas +} t_jugadores; + +void imprimir_jugador(t_jugador j, int visible); +void imprimir_jugadores(t_jugadores js, int visible); +void que_jugador_tiene_doble_mas_alto(t_jugadores js, int *p_nj, int *p_nf); +void pasar_turno(t_jugadores *p_js); +void imprimir_turno(t_jugadores _js); + +void imprimir_jugador(t_jugador j, int visible) +{ + int i; + t_ficha f; + + if (j.tipo == T_ROBOT) + { // Robot + if (visible == FALSE) + { // Omnisciencia apagada + for (i = 0; i < j.n_fichas; i++) + { + printf("?:?|"); + } + } + else + { // Omnisciencia encendida + for (i = 0; i < j.n_fichas; i++) + { + printf("%d:%d|", j.f[i].num1, j.f[i].num2); + } + } + } + else + { // Humano + for (i = 0; i < j.n_fichas; i++) + { + printf("%d:%d|", j.f[i].num1, j.f[i].num2); + } + } +} +void imprimir_jugadores(t_jugadores js, int visible) +{ + int i; + for (i = 0; i < js.n_jugadores; i++) + { //Ejecuta el codigo para cada jugador + printf("J%d ", i); + imprimir_jugador(js.j[i], visible); + if (js.j[i].tipo == T_ROBOT) + { //Robot + printf("Robot\n"); + } + else + { //Humano + printf("Humano\n"); + } + } +} +void que_jugador_tiene_doble_mas_alto(t_jugadores js, int *p_nj, int *p_nf) +{ + int i, j, max = 0, encontrado = 0; + + for (i = 0; i < js.n_jugadores; i++) + { //Comprueba que jugador tiene el doble mas alto + for (j = 0; j < js.j[i].n_fichas; j++) + { + if (js.j[i].f[j].num1 == js.j[i].f[j].num2 && js.j[i].f[j].num1 > max) + { + max = js.j[i].f[j].num1; + *p_nj = i; + *p_nf = j; + encontrado = 1; + } + } + } + if (encontrado == 0) + { + *p_nj = 0; + *p_nf = 0; + } +} +void pasar_turno(t_jugadores *p_js) +{ + p_js->turno = ((p_js->turno) + 1) % (p_js->n_jugadores); // Suma 1 al turno a menos que sea máximo, entonces vuelve al inicial (0) +} +void imprimir_turno(t_jugadores js) +{ + printf("Turno: %d\n", js.turno); +} diff --git a/jugador.h b/jugador.h new file mode 100644 index 0000000..78766ee --- /dev/null +++ b/jugador.h @@ -0,0 +1,33 @@ +#ifndef JUGADOR_H +#define JUGADOR_H + +#include "ficha.h" + +#define MIN_JUGADORES 2 +#define MAX_JUGADORES 4 + +#define T_HUMANO 1 +#define T_ROBOT 2 + +typedef struct { + int n_fichas; + t_ficha f[NUM_FICHAS_DOMINO]; // Fichas que tiene + int tipo; + int peso; +} t_jugador; + +typedef struct { + int n_jugadores; + int un_humano; // TRUE or FALSE + int turno; + t_jugador j[MAX_JUGADORES]; // Fichas que tiene y otras cosas +} t_jugadores; + +void imprimir_jugador(t_jugador j, int visible); +void imprimir_jugadores(t_jugadores js, int visible); +void que_jugador_tiene_doble_mas_alto(t_jugadores js, int *p_nj, int *p_nf); +void pasar_turno(t_jugadores *p_js); +void imprimir_turno(t_jugadores _js); + +#endif // JUGADOR_H + diff --git a/main b/main new file mode 100644 index 0000000..9bef283 Binary files /dev/null and b/main differ diff --git a/main.c b/main.c new file mode 100644 index 0000000..e0c3a22 --- /dev/null +++ b/main.c @@ -0,0 +1,21 @@ +#include "partida.h" +//incloure totes les llibreries + +#define TRUE 1 +#define FALSE 0 + +int main(){ + int acabado; + t_partida partida; + inicializar_partida(&partida); + realizar_jugada(&partida); + acabado=FALSE; // Inicialitzem "acabado" a 0 perque la partida comença i ha d'entrar al while + while(acabado==FALSE) // Entra sempre que es pugui seguint jugar + { + imprimir_estado_partida(partida); + realizar_jugada(&partida); + acabado=se_ha_acabado_la_partida(partida); + } + + imprimir_estado_final_partida(partida); // Printf de la partida en la jugada final +} diff --git a/mesa.c b/mesa.c new file mode 100644 index 0000000..51e21c9 --- /dev/null +++ b/mesa.c @@ -0,0 +1,98 @@ +#include <stdio.h> +#include "ficha.h" +#define NUM_FICHAS_DOMINO 28 + +typedef struct +{ + int n_fichas; + t_ficha f[NUM_FICHAS_DOMINO]; +} t_mesa; + +void inicializar_mesa(t_mesa *p_m) +{ + p_m->n_fichas = 0; // Inicialmente no hay fichas en la mesa +} + +void imprimir_mesa(t_mesa m, int dim) +{ + int i, pos2; + + printf("\nMesa: "); + if (dim == FALSE) + { //sense 2d + for (i = 0; i < m.n_fichas; i++) + printf("%d:%d|", m.f[i].num1, m.f[i].num2); + } + else + { //con 2d + printf("\n"); + + for (i = 0; i < m.n_fichas; i++) + { + if (m.f[i].num1 == m.f[i].num2) + { //es doble, poner vertical + printf("%d|", m.f[i].num1); + } + else + { + printf("___ "); + } + } + printf("\n"); + for (i = 0; i < m.n_fichas; i++) + { + if (m.f[i].num1 == m.f[i].num2) + { //es doble, poner vertical + printf("-|"); + } + else + { + printf("%d:%d|", m.f[i].num1, m.f[i].num2); //es normal, se imprime normal + } + } + printf("\n"); + for (i = 0; i < m.n_fichas; i++) + { + if (m.f[i].num1 == m.f[i].num2) + { //es doble, poner vertical + printf("%d|", m.f[i].num1); + } + else + { + printf(" "); + } + } + printf("\n"); + } +} + +void pon_en_mesa_por_la_derecha(t_mesa *p_m, t_ficha f) +{ + int i; + + p_m->f[p_m->n_fichas] = f; // Posición de la derecha: n_fichas porque es la primera posición vacia en el vector + p_m->n_fichas++; +} +void pon_en_mesa_por_la_izquierda(t_mesa *p_m, t_ficha f) +{ + int i; + p_m->n_fichas++; + for (i = p_m->n_fichas; i > 0; i--) + { // Desplaza toda la mesa un lugar a la derecha + p_m->f[i] = p_m->f[i - 1]; + } + p_m->f[0] = f; // Introduce en la posición 0 la nueva ficha +} + +int extremo_izquierdo_mesa(t_mesa m) +{ + int izquierdo; + izquierdo = m.f[0].num1; + return (izquierdo); +} +int extremo_derecho_mesa(t_mesa m) +{ + int derecho; + derecho = m.f[m.n_fichas - 1].num2; + return (derecho); +} diff --git a/mesa.h b/mesa.h new file mode 100644 index 0000000..6fc068e --- /dev/null +++ b/mesa.h @@ -0,0 +1,20 @@ +#ifndef MESA_H +#define MESA_H + +#include "ficha.h" + +typedef struct { + int n_fichas; + t_ficha f[NUM_FICHAS_DOMINO]; +} t_mesa; + +void inicializar_mesa(t_mesa *p_m); +void imprimir_mesa(t_mesa m, int dim); + +void pon_en_mesa_por_la_derecha(t_mesa *p_m, t_ficha f); +void pon_en_mesa_por_la_izquierda(t_mesa *p_m, t_ficha f); + +int extremo_izquierdo_mesa(t_mesa m); +int extremo_derecho_mesa(t_mesa m); + +#endif // MESA_H diff --git a/partida.c b/partida.c new file mode 100644 index 0000000..693a7e1 --- /dev/null +++ b/partida.c @@ -0,0 +1,327 @@ +#include <stdio.h> +#include <string.h> +#include "jugador.h" +#include "mesa.h" +#include "pila.h" +#include "tirada.h" +#include "preguntas.h" +#include "duerme.h" +#include "azar.h" + +#define TRUE 1 +#define FALSE 0 +typedef struct +{ + t_jugadores js; + t_mesa m; // Fichas jugadas + t_pila pi; // Fichas no jugadas y que no tiene nadie + int visible; // Pila y fichas de robots visibles + int dim; // Ver mesa en 2D (versus 1D) + // visible y mesa_2d pueden valer TRUE o FALSE + int pasadas; // Veces consecutivas que un jugador pasa + // si pasadas == n_jugadores se acaba el juego. +} t_partida; + +void inicializar_partida(t_partida *p_pa); +void imprimir_estado_partida(t_partida pa); +void realizar_jugada(t_partida *p_pa); +int se_ha_acabado_la_partida(t_partida pa); + +void inicializar_partida(t_partida *p_pa) +{ + int i, j, p, k, nj, nf; + char s1[50] = "¿Numero de jugadores?", s2[50] = "¿Un jugador humano?", s3[50] = "¿Quieres omnisciencia?", s4[50] = "¿Quieres ver la mesa en 2D?"; + + p_pa->pasadas = 0; + + p_pa->js.n_jugadores = preguntar_n_en_rango(&s1[0], 2, 4); //Realizamos las preguntas + p_pa->js.un_humano = preguntar_si_o_no(&s2[0]); + p_pa->visible = preguntar_si_o_no(&s3[0]); + p_pa->dim = preguntar_si_o_no(&s4[0]); + printf("\n"); + + inicializar_pila(&(p_pa->pi)); + + for (i = 0; i < p_pa->js.n_jugadores; i++) //Repartir fichas aleatoriamente + for (j = 0; j < 7; j++) + p_pa->js.j[i].f[j] = coger_ficha_de_la_pila(&(p_pa->pi)); + + if (p_pa->js.un_humano == TRUE) + { // Inicializamos los jugadores + p_pa->js.j[0].tipo = T_HUMANO; + p_pa->js.j[0].n_fichas = 7; + for (i = 1; i < p_pa->js.n_jugadores; i++) + { + p_pa->js.j[i].tipo = T_ROBOT; + p_pa->js.j[i].n_fichas = 7; + } + } + else + { + for (i = 0; i < p_pa->js.n_jugadores; i++) + { + p_pa->js.j[i].tipo = T_ROBOT; + p_pa->js.j[i].n_fichas = 7; + } + } + que_jugador_tiene_doble_mas_alto(p_pa->js, &nj, &nf); // Que jugador empieza la partida + + inicializar_mesa(&(p_pa->m)); + imprimir_pila(p_pa->pi, p_pa->visible); + + pon_en_mesa_por_la_izquierda(&(p_pa->m), p_pa->js.j[nj].f[nf]); + imprimir_mesa(p_pa->m, p_pa->dim); + printf("\n"); + + for (i = nf; i < p_pa->js.j[nj].n_fichas; i++) + p_pa->js.j[nj].f[i] = p_pa->js.j[nj].f[i + 1]; + p_pa->js.j[nj].n_fichas--; + + p_pa->js.turno = nj; + imprimir_jugadores(p_pa->js, p_pa->visible); + pasar_turno(&(p_pa->js)); + imprimir_turno(p_pa->js); +} + +void imprimir_estado_partida(t_partida pa) +{ + int i; + imprimir_pila(pa.pi, pa.visible); + //POSAR MESA EN NEGRETA + imprimir_mesa(pa.m, pa.dim); + printf("\n"); + imprimir_jugadores(pa.js, pa.visible); + imprimir_turno(pa.js); +} +void imprimir_estado_final_partida(t_partida pa) +{ // Printf de la partida en el momento del final de la partida + int i; + duerme_un_rato(10); + printf("\tESTADO FINAL DE PARTIDA:\n\n"); + pa.visible = TRUE; + + imprimir_pila(pa.pi, pa.visible); + //POSAR MESA EN NEGRETA + imprimir_mesa(pa.m, pa.dim); + printf("\n"); + imprimir_jugadores(pa.js, pa.visible); + printf("\n"); +} + +void realizar_jugada(t_partida *p_pa) +{ + int tirada = -1, i, v; + t_tiradas ts; + + ts = calcular_tiradas_posibles(p_pa->js.j[p_pa->js.turno], p_pa->m); //Calculamos si hay tiradas posibles + + while (ts.n_tiradas == 0 && p_pa->pi.n_fichas != 0) + { // Si no puede tirar tiene que robar ficha + p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas] = coger_ficha_de_la_pila(&(p_pa->pi)); + + if (p_pa->visible == TRUE) + { // Omnisciencia activada + if (p_pa->js.j[p_pa->js.turno].tipo == T_HUMANO) // Si es humano muestra la ficha + printf("Vas a la pila! Pillas un %d:%d ;P\n", p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas].num1, p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas].num2); + else + printf("Va a la pila! Pilla un %d:%d ;)\n", p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas].num1, p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas].num2); // Si es robot muestra la ficha + p_pa->js.j[p_pa->js.turno].n_fichas++; + ts = calcular_tiradas_posibles(p_pa->js.j[p_pa->js.turno], p_pa->m); + } + if (p_pa->visible == FALSE) + { + if (p_pa->js.j[p_pa->js.turno].tipo == T_HUMANO) //Si es humano muestra la ficha + printf("Vas a la pila! Pillas un %d:%d ;P\n", p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas].num1, p_pa->js.j[p_pa->js.turno].f[p_pa->js.j[p_pa->js.turno].n_fichas].num2); + else + printf("Va a la pila! ;)\n"); //Si es robot no muestra la ficha + p_pa->js.j[p_pa->js.turno].n_fichas++; + ts = calcular_tiradas_posibles(p_pa->js.j[p_pa->js.turno], p_pa->m); + } + } + + imprimir_tiradas(ts, p_pa->js.j[p_pa->js.turno]); + + if (p_pa->js.j[p_pa->js.turno].tipo == T_HUMANO) + { //tira humano + if (ts.n_tiradas == 0 && p_pa->pi.n_fichas == 0) + { //HUMANO no puede tirar y pasa turno + printf("Pasas! :(\n\n"); + p_pa->pasadas++; + } + + if (ts.n_tiradas > 0) + { + p_pa->pasadas = 0; + if (ts.cont_dobles > 1) + v = ts.n_tiradas; //Si se dobledobla cuenta esa tirada como extra + else + v = ts.n_tiradas - 1; + printf("¿Que tirada juegas[0-%d]?: ", v); + scanf("%d", &tirada); + while (tirada < 0 || tirada > v) + { + printf("¡%d no es una opcion!\n", tirada); + printf("¿Que tirada juegas[0-%d]?: ", v); + scanf("%d", &tirada); + } + printf("\n"); + if ((ts.cont_dobles > 1) && (tirada == ts.n_tiradas)) + { //Se dobledobla cuando el contador tiene 2 tiradas con dobles y el jugador la escoje + pon_en_mesa_por_la_derecha(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[ts.dobleizquierda].n_ficha]); //Doble por la derecha + pon_en_mesa_por_la_izquierda(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[ts.doblederecha].n_ficha]); //Doble por la izquierda + for (i = ts.t[ts.doblederecha].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) // Eliminar un doble del vector de fichas del jugador + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + if (ts.t[ts.dobleizquierda].n_ficha > ts.t[ts.doblederecha].n_ficha) + { // Eliminar el otro doble del vector de fichas dependiendo de donde se encuentre respecto al primer doble + for (i = ts.t[ts.dobleizquierda - 1].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + } + else + { + for (i = ts.t[ts.dobleizquierda - 1].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + } + } + if (tirada != ts.n_tiradas) + { //Si no se dobledobla + if (ts.t[tirada].girada == TRUE) //Gira la ficha si debe hacerlo + girar_ficha(&(p_pa->js.j[p_pa->js.turno].f[ts.t[tirada].n_ficha])); + if (ts.t[tirada].extremo == 'd') + { + pon_en_mesa_por_la_derecha(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[tirada].n_ficha]); //Coloca por la derecha + } + else + { + pon_en_mesa_por_la_izquierda(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[tirada].n_ficha]); //Coloca por la izquierda + } + for (i = ts.t[tirada].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + } + } + } + else + { /*TIRA UN ROBOT*/ + if (ts.n_tiradas == 0 && p_pa->pi.n_fichas == 0) + { + printf("Pasa! :)\n\n"); //Si no puede tirar pasa turno + p_pa->pasadas++; + } + //Robot no puede tirar y pasa turno + + if (ts.n_tiradas > 0) + { + p_pa->pasadas = 0; + if (ts.cont_dobles > 1) + ts.n_tiradas++; // Dobledoblarse cuenta como una tirada más + tirada = numero_al_azar(ts.n_tiradas); // Escoge una tirada al azar + if ((ts.cont_dobles > 1) && (tirada == ts.n_tiradas)) + { //Se dobledobla cuando el contador tiene 2 tiradas con dobles y el jugador la escoje + pon_en_mesa_por_la_derecha(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[ts.dobleizquierda].n_ficha]); // Doble por la derecha + pon_en_mesa_por_la_izquierda(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[ts.doblederecha].n_ficha]); // Doble por la izquierda + for (i = ts.t[ts.doblederecha].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) // Eliminar un doble del vector de fichas del robot + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + if (ts.t[ts.dobleizquierda].n_ficha > ts.t[ts.doblederecha].n_ficha) + { //Eliminar el otro doble dependiendo de su posición respecto al primero + for (i = ts.t[ts.dobleizquierda - 1].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + } + else + { + for (i = ts.t[ts.dobleizquierda - 1].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + } + } + else + { + if (ts.t[tirada].girada == TRUE) //Gira la ficha si debe hacerlo + girar_ficha(&(p_pa->js.j[p_pa->js.turno].f[ts.t[tirada].n_ficha])); + imprimir_tirada(ts.t[tirada], p_pa->js.j[p_pa->js.turno]); + if (ts.t[tirada].extremo == 'd') + { + pon_en_mesa_por_la_derecha(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[tirada].n_ficha]); //Coloca por la derecha + } + else + { + pon_en_mesa_por_la_izquierda(&(p_pa->m), p_pa->js.j[p_pa->js.turno].f[ts.t[tirada].n_ficha]); //Coloca por la izquierda + } + for (i = ts.t[tirada].n_ficha; i < p_pa->js.j[p_pa->js.turno].n_fichas - 1; i++) //Elimina la ficha del vector + p_pa->js.j[p_pa->js.turno].f[i] = p_pa->js.j[p_pa->js.turno].f[i + 1]; + p_pa->js.j[p_pa->js.turno].n_fichas--; + } + duerme_un_rato(4); + } + } + + pasar_turno(&(p_pa->js)); +} + +int se_ha_acabado_la_partida(t_partida pa) +{ + int aux = FALSE, minpeso = 200, i, j, jugminpeso, empate = FALSE; + + if (pa.js.turno > 0) // Como se_ha_acabado_la_partida se coloca despues de pasar_turno, pa.js.turno debe ser un numero menos + pa.js.turno = pa.js.turno - 1; + + else // NO puede ser -1, asi que vuelve a n_jugadores-1 (maximo) + pa.js.turno = pa.js.n_jugadores - 1; + + if (pa.js.j[pa.js.turno].n_fichas == 0) + { // Condición de ganador + if (pa.js.j[pa.js.turno].tipo == T_HUMANO) + { // Gana el humano + printf("===>>> HAS GANADO! :) <<<===\n\n"); + } + else + { //Gana el robot + printf("===>>> HA GANADO EL J%d! :/ <<<===\n\n", pa.js.turno); + } + aux = TRUE; + return (aux); + } + else if (pa.pasadas >= pa.js.n_jugadores) + { //Ganador en bloqueo + printf("===>>> JUEGO BLOQUEADO <<<===\n\n"); + aux = TRUE; + for (i = 0; i < pa.js.n_jugadores; i++) + { // Calcula el peso de las fichas + pa.js.j[i].peso = 0; + for (j = 0; j < pa.js.j[i].n_fichas; j++) + { + pa.js.j[i].peso = pa.js.j[i].peso + pa.js.j[i].f[j].num1 + pa.js.j[i].f[j].num2; + } + printf("Peso J%d=%d\n", i, pa.js.j[i].peso); + } + for (i = 0; i < pa.js.n_jugadores; i++) + { //Peso minimo con su jugador + if (minpeso > pa.js.j[i].peso) + { + minpeso = pa.js.j[i].peso; + jugminpeso = i; + } + } + for (i = 0; i < pa.js.n_jugadores; i++) + { // Caso de empate (tablas) + if (minpeso == pa.js.j[i].peso && i != jugminpeso) + { + empate = TRUE; + } + } + if (empate == TRUE) + { // Tablas + printf("\n===>>> TABLAS ENTRE J%d Y J%d CON MINIMO PESO(%d de peso) <<<===\n\n\n", jugminpeso, i, minpeso); + } + else + { // Ganador + printf("\n===>>> HA GANADO EL J%d POR MINIMO PESO(%d de peso) <<<===\n\n\n", jugminpeso, minpeso); + } + } + else + return (aux); +} diff --git a/partida.h b/partida.h new file mode 100644 index 0000000..e58e5f5 --- /dev/null +++ b/partida.h @@ -0,0 +1,27 @@ +#ifndef PARTIDA_H +#define PARTIDA_H + +#include "jugador.h" +#include "mesa.h" +#include "pila.h" +#include "tirada.h" + +typedef struct +{ + t_jugadores js; + t_mesa m; // Fichas jugadas + t_pila pi; // Fichas no jugadas y que no tiene nadie + int visible; // Pila y fichas de robots visibles + int mesa_2d; // Ver mesa en 2D (versus 1D) + // visible y mesa_2d pueden valer TRUE o FALSE + int pasadas; // Veces consecutivas que un jugador pasa + // si pasadas == n_jugadores se acaba el juego. +} t_partida; + +void inicializar_partida(t_partida *p_pa); +void imprimir_estado_partida(t_partida pa); +void imprimir_estado_final_partida(t_partida pa); +void realizar_jugada(t_partida *p_pa); +int se_ha_acabado_la_partida(t_partida pa); + +#endif // PARTIDA_H diff --git a/pila.c b/pila.c new file mode 100644 index 0000000..77aa00d --- /dev/null +++ b/pila.c @@ -0,0 +1,74 @@ +#include <stdio.h> +#include "azar.h" +#include "ficha.h" +#define NUM_FICHAS_DOMINO 28 +#define FALSE 0 +#define TRUE 1 + +typedef struct +{ + int n_fichas; + t_ficha f[NUM_FICHAS_DOMINO]; +} t_pila; + +void imprimir_pila(t_pila pi, int visible); +void inicializar_pila(t_pila *pi); +int esta_la_pila_vacia(t_pila pi); +t_ficha coger_ficha_de_la_pila(t_pila *pi); + +void inicializar_pila(t_pila *pi) +{ + int i = 0, j, k; + + pi->n_fichas = NUM_FICHAS_DOMINO; // Al inicio todas las fichas estan en la pila + for (j = 0; j < 7; j++) + for (k = j; k < 7; k++) + { + inicializar_ficha(&pi->f[i], j, k); //Inicializa las 28 fichas + i++; + } +} + +void imprimir_pila(t_pila pi, int visible) +{ + int i; + + if (visible == TRUE) + { // Omnisciencia activada + printf("Pila:\t"); + for (i = 0; i < pi.n_fichas; i++) + imprimir_ficha(pi.f[i], visible); + } + + else + { // Omnisciencia apagada + printf("Pila:\t"); + for (i = 0; i < pi.n_fichas; i++) + printf("?:?|"); + } + if (pi.n_fichas == 0) + printf("La pila esta vacia"); +} + +int esta_la_pila_vacia(t_pila pi) +{ + if (pi.n_fichas == 0) + return (TRUE); + + else + return (FALSE); +} + +t_ficha coger_ficha_de_la_pila(t_pila *pi) +{ + int i, pos; + t_pila aux; + pos = numero_al_azar(pi->n_fichas); // Escoge una ficha aleatoria + aux.f[pos] = pi->f[pos]; // Guarda esta ficha aleatoria en un auxiliar + for (i = pos; i < (pi->n_fichas - 1); i++) + { // Elimina la ficha robada del vector de la pila + pi->f[i] = pi->f[i + 1]; + } + pi->n_fichas--; + return (aux.f[pos]); // El return devuelve la ficha robada +} diff --git a/pila.h b/pila.h new file mode 100644 index 0000000..1b15937 --- /dev/null +++ b/pila.h @@ -0,0 +1,17 @@ +#ifndef PILA_H +#define PILA_H + +#include "ficha.h" + +typedef struct +{ + int n_fichas; + t_ficha f[NUM_FICHAS_DOMINO]; +} t_pila; + +void inicializar_pila(t_pila *pi); +void imprimir_pila(t_pila pi, int visible); +t_ficha coger_ficha_de_la_pila(t_pila *pi); +int esta_la_pila_vacia(t_pila pi); + +#endif // PILA_H diff --git a/preguntas.c b/preguntas.c new file mode 100644 index 0000000..a5911f8 --- /dev/null +++ b/preguntas.c @@ -0,0 +1,42 @@ +// Este fichero se le da al alumno +#include <stdio.h> + +int fuera_de_rango(int n, int min, int max) +{ + return ((n < min) || (n > max)); +} + +void convertir_a_minusculas(char *c) +{ + if ((*c >= 'A') && (*c <= 'Z')) + { + *c = *c - 'A' + 'a'; + } +} + +int preguntar_n_en_rango(char *s, int min, int max) +{ + int n; + + do + { + printf("%s [%d-%d]: ", s, min, max); + scanf("%d%*c", &n); + } while (fuera_de_rango(n, min, max)); + + return n; +} + +int preguntar_si_o_no(char *s) +{ + char c; + + do + { + printf("%s [s/n]: ", s); + scanf("%c%*c", &c); + convertir_a_minusculas(&c); + } while (c != 's' && c != 'n'); + + return (c == 's'); +} diff --git a/preguntas.h b/preguntas.h new file mode 100644 index 0000000..2cc6da6 --- /dev/null +++ b/preguntas.h @@ -0,0 +1,15 @@ +// Este fichero se le da al alumno +#ifndef PREGUNTAS_H +#define PREGUNTAS_H + +#include <stdio.h> + +#define TRUE 1 +#define FALSE 0 + +int fuera_de_rango(int n, int min, int max); +void convertir_a_minusculas(char *c); +int preguntar_n_en_rango(char *s, int min, int max); +int preguntar_si_o_no(char *s); + +#endif // PREGUNTAS_H diff --git a/tirada.c b/tirada.c new file mode 100644 index 0000000..ce398d8 --- /dev/null +++ b/tirada.c @@ -0,0 +1,122 @@ +#define TIRADA_H + +#include <stdio.h> +#include "ficha.h" +#include "jugador.h" +#include "mesa.h" + +#define MAX_TIRADAS_JUGADOR NUM_FICHAS_DOMINO + +typedef struct +{ + int n_ficha; // numero de ficha en el vector de fichas del jugador + char extremo; // IZQUIERDA o DERECHA (de n_ficha(1)) + int girada; // TRUE o FALSE + int dobledobla; +} t_tirada; + +typedef struct +{ + int n_tiradas; + t_tirada t[MAX_TIRADAS_JUGADOR]; + int cont_dobles, dobleizquierda, doblederecha; + +} t_tiradas; + +void imprimir_tirada(t_tirada t, t_jugador j) +{ //Siempre es visible independiente de omnisciencia + int aux; + aux = t.n_ficha; + if (j.tipo == T_ROBOT) + printf("Tira: %c|%d:%d|\n\n", t.extremo, j.f[aux].num1, j.f[aux].num2); +} + +void imprimir_tiradas(t_tiradas ts, t_jugador j, int visible) +{ + int i; + + if ((visible == TRUE && j.tipo == T_ROBOT) || j.tipo == T_HUMANO) + { // Muestra si omnisciencia está activada o el jugador es humano + printf("Tiradas posibles: "); + if (ts.n_tiradas > 0) + { // Si puede tirar + for (i = 0; i < ts.n_tiradas; i++) + { + printf("%d(%c%d:%d) ", i, ts.t[i].extremo, j.f[ts.t[i].n_ficha].num1, j.f[ts.t[i].n_ficha].num2); + } + + if ((ts.cont_dobles > 1) && (j.f[ts.t[ts.dobleizquierda].n_ficha].num1 != j.f[ts.t[ts.doblederecha].n_ficha].num2)) + { + i = ts.n_tiradas; + printf("%d(%c%d:%d|%c%d:%d) ", i, ts.t[ts.dobleizquierda].extremo, j.f[ts.t[ts.dobleizquierda].n_ficha].num1, j.f[ts.t[ts.dobleizquierda].n_ficha].num2, ts.t[ts.doblederecha].extremo, j.f[ts.t[ts.doblederecha].n_ficha].num1, j.f[ts.t[ts.doblederecha].n_ficha].num2); + } + printf("\n"); + } + else + printf("No hay tiradas posibles!!\n"); // Si no puede tirar + } +} + +t_tiradas calcular_tiradas_posibles(t_jugador j, t_mesa m) +{ + t_tiradas ts; + int izq, der, i, k = 0, doble; + izq = extremo_izquierdo_mesa(m); // Calcula el extremo izquierdo de la mesa + der = extremo_derecho_mesa(m); // Calcula el extremo derecho de la mesa + ts.cont_dobles = 0; + for (i = 0; i < j.n_fichas; i++) + { + doble = 0; + if (j.f[i].num1 == j.f[i].num2) + doble = TRUE; // Comprueba si es un doble + + if (j.f[i].num2 == izq) + { // Tirada por la izquierda sin girar + if (doble == TRUE) + { + ts.cont_dobles++; + ts.dobleizquierda = k; + } + ts.t[k].n_ficha = i; + ts.t[k].extremo = 'i'; + ts.t[k].girada = 0; + k++; + } + if (j.f[i].num1 == izq) + { // Tirada por la izquierda girando + if (doble == FALSE) + { + ts.t[k].n_ficha = i; + ts.t[k].extremo = 'i'; + ts.t[k].girada = 1; + k++; + } + } + if (j.f[i].num1 == der) + { // Tirada por la derecha sin girar + if (doble == TRUE) + { + ts.cont_dobles++; + ts.doblederecha = k; + } + ts.t[k].n_ficha = i; + ts.t[k].extremo = 'd'; + ts.t[k].girada = 0; + k++; + } + if (j.f[i].num2 == der) + { // Tirada por la derecha girando + if (doble == FALSE) + { + ts.t[k].n_ficha = i; + ts.t[k].extremo = 'd'; + ts.t[k].girada = 1; + k++; + } + } + + ts.n_tiradas = k; // Numero de tiradas + } + + return (ts); +} diff --git a/tirada.h b/tirada.h new file mode 100644 index 0000000..c13c7f6 --- /dev/null +++ b/tirada.h @@ -0,0 +1,29 @@ +#ifndef TIRADA_H +#define TIRADA_H + +#include "ficha.h" +#include "jugador.h" +#include "mesa.h" + +#define MAX_TIRADAS_JUGADOR NUM_FICHAS_DOMINO + +typedef struct +{ + int n_ficha; // numero de ficha en el vector de fichas del jugador + char extremo; // IZQUIERDA o DERECHA (de n_ficha(1)) + int girada; // TRUE o FALSE + int dobledobla; +} t_tirada; + +typedef struct +{ + int n_tiradas; + t_tirada t[MAX_TIRADAS_JUGADOR]; + int cont_dobles, doblederecha, dobleizquierda; +} t_tiradas; + +void imprimir_tirada(t_tirada ts, t_jugador j); +void imprimir_tiradas(t_tiradas ts, t_jugador j); +t_tiradas calcular_tiradas_posibles(t_jugador j, t_mesa m); + +#endif // TIRADA_H