//Copyright 2010 Alvaro Diaz Sanchez /*This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ /*Fichero conectan.cpp*/ /** @file conectan.cpp @author Alvaro Diaz Sanchez @brief Programa principal conectaN */ #include #include #include #include "tablero.h" #include "jugador.h" #include "graficos.h" using namespace std; /** @brief El arbitro es una estructura que guarda datos y desde el pundo de vista del concepto de Arbitro existen modulos que hacen que: sea el encargado de almacenar los datos de las partidas, leer los datos de una partida o las configuraciones guardadas y gestionar cada jugada realizada por cada uno de los jugadores (ver quien ha ganado, señalar su jugada ganadora, controlar los turnos para ver quien comienza cada vez, mostrar mensajes concernientes a la partida (turnos, mensajes de continuar, tablero lleno...), permita controlar a quien le corresponde echar y que ese jugador pueda realizar su jugada, calcula las puntuaciones de cada jugador al terminar la partida. En definitiva, se comporta como cualquier arbitro que controla un juego, imponiendo las reglas y controlando que todo se desarrolle optimamente durante la partida. */ struct Arbitro{ char dir_imagen[256]; //Directorio donde se encuentran las imagenes char tema[256]; //Apariencia del tablero int tiempo_espera; //Tiempo de espera entre cada turno en milisegundos char nombre_jugador1[256]; //Nombre del jugador 1 char nombre_jugador2[256]; //Nombre del jugador 2 char ruta[256];//Nombre de la ruta de guardado del fichero de configuracion CFG int fichas_turno; //Numero de fichas a echar en cada turno int fichas_linea; // Numero de fichas a alinear para ganar int nivel_jugador1; //Nivel del jugador 1 int nivel_jugador2; //Nivel del jugador 2 int jugador_comienza; //Jugador que comienza el juego }; /** @brief El arbitro señala mediante circulos de colores la jugada ganadora de la ronda y tiene una relacion con la biblioteca graficos para pintar los circulos sobre el tablero. @param int fila: Indica la posicion de la @c fila del tablero donde comienza la jugada ganadora. @param unsigned int columna: Indica la posicion de la @c columna del tablero donde comienza la jugada ganadora @param char orientacion: Especifica la direccion de la jugada ganadora. (h) horizontal , (v) vertica, (i) diagonal izquierda, (d) diagonal derecha. @param int linea: Numero de fichas a alinear en la partida. @param const Tablero &juego: Objeto de la clase @c Tablero para poder reflejar los sucesos en el tablero. @pre - 0 <= @c columna < @c ColumnasTablero(i) - 2 < @c linea <= (@c filas o @c columnas) @return @c void @post - Señala la jugada ganadora con circulos de colores - No MODIFICA nada */ void ArbitroAvisaJugadaGanadora (int fila, unsigned int columna, char orientacion, int linea, const Tablero &juego); /** @brief El arbitro muestra en el pie del tablero un mensaje indicando el turno del jugador que le corresponde echar. Tiene una relacion con la clase Tablero para repintar el pie de la ventana y tambien con la biblioteca graficos que muestra el mensaje del turno del jugador. @param char nombre[]: Nombre del jugador que le corresponde echar ficha. @param const Tablero &juego: Objeto de la clase @c Tablero. @return @c void @post - Muestra un mensaje en el pie del tablero del jugador que le corresponde echar ficha. - No MODIFICA nada. */ void ArbitroAvisaTurnoJugador (char nombre[], Tablero &juego); /** @brief El arbitro calcula las puntuaciones de los dos jugadores despues de finalizar la ronda. Se tiene en cuenta el tamaño del tablero, la cantidad de casillas vacias y numero de fichas a alinear. @param int tamanio: Tamanio del tablero (filas * columnas). @param int numero_vacios: Numero de casillas vacias que han quedado sin usar. (Cuanto mas casillas vacias en menos movimientos ha ganado al contricante). @param int linea: Numero de fichas a alinear para ganar. @pre - 4*4 <= tamanio < FilasTablero(i) * ColumnasTablero(i) - linea + fichas de los jugadores < numero_vacios < tamanio - 2 < @c linea <= (FilasTablero(i) o ColumnasTablero(i)) @return @c int @post - Devuelve la puntuacion para el jugador que se le ha aplicado la funcion. - No MODIFICA nada. */ int ArbitroCalculaPuntuacionRonda (int tamanio, int numero_vacios, int linea); /** @brief El arbitro cambia el turno del jugador que ha comenzado por primera vez para que en la siguiente partida empieze el otro jugador. @param bool &j1_comienza: Determina que jugador debe comenzar. @param int &j_inicio: Contabiliza el numero de partidas echadas si el numero es par empieza el primer jugador si es impar el segundo jugador. @param bool &completo: Controlador de tablero completo. @return @c void @post - Cambia el turno del primer jugador que ha comenzado para que en la siguiente partida juegue primero el segundo jugador o viceversa. - MODIFICA @c j1_comienza, @c j_inicio y @c completo */ void ArbitroCambiaTurnoNuevaRonda (bool &j1_comienza, int &j_inicio, bool &completo); /** @brief El arbitro comprueba la jugada dependiendo del color de la ficha.Llama a la funcion TableroInsertaFicha(fila, columna, valor) de la clase Tablero para que quede reflejada la jugada, comprueba si existe una jugada ganadora y finalmente observa si el tablero esta completo de fichas mediante la funcion de la clase Tablero TableroCompleto(). @param int valor: Determina mediante un numero entero sobre quien de los dos jugadores hay que realizar las operaciones (1):Jugador 1 (2): Jugador 2 @param int &fila: Es la posicion de la fila donde comienza la jugada ganadora, si existiera. @param unsigned int &columna: Es la posicion de la columna donde comienza la jugada ganadora, si existira. @param int linea: Numero de fichas a alinear para ganar. @param Tablero &juego: Objeto de la clase Tablero. @param bool &campeon: Controla si existe un ganador despues de comprobar la jugada. @param bool &completo: Controla si el tablero se ha completado de fichas. @pre - 0 <= fila < FilasTablero(i) - 0 <= columna < ColumnasTablero(i) - 2 < @c linea <= (FilasTablero(i) o ColumnasTablero(i)) @return @c char @post - Devuelve un char con un caracter que indicara si existiese una jugada ganadora la orientacion de la jugada ganadora: (h) horizontal , (v) vertica, (i) diagonal izquierda, (d) diagonal derecha. - MODIFICA @c fila, @c columna, @c juego, @c campeon y @c completo. */ char ArbitroCompruebaJugada (int valor, int &fila, unsigned int &columna, int linea, Tablero &juego, bool &campeon, bool &completo); /** @brief El arbitro comprueba si la jugada realizada por el jugador de color X, sobre el que el arbitro ha llamado a la funcion, tiene jugada ganadora y por tanto ser el ganador de la partida. @param int linea: Numero de fichas a alinear para ganar. @param int valor: Determina mediante un numero entero sobre quien de los dos jugadores hay que realizar la comprobacion (1):Jugador 1 (2): Jugador 2 @param Tablero &juego: Objeto de la clase Tablero. @param int &fila_inicio: Es la posicion de la fila donde comienza la jugada ganadora, si existiera. @param unsigned int &columna_inicio: Es la posicion de la columna donde comienza la jugada ganadora, si existira. @param char &orientacion: Especifica la direccion de la jugada ganadora. (h) horizontal , (v) vertica, (i) diagonal izquierda, (d) diagonal derecha. @pre - 0 <= fila < FilasTablero(i) - 0 <= columna < ColumnasTablero(i) - 2 < @c linea <= (FilasTablero(i) o ColumnasTablero(i)) @return @c bool @post - Devuelve un bool que nos va a determinar si existe jugada ganadora por parte del jugador de color X. - MODIFICA @c juego, @c fila_inicio, @c columna_inicio y @c orientacion. */ bool ArbitroCompruebaJugadorGanaPartida (int linea, int valor, Tablero &juego, int &fila_inicio, unsigned int &columna_inicio, char &orientacion); /** @brief El arbitro contabiliza el numero de casillas vacias al finalizar la partida para sumarlas como bonus a la puntuacion final.Mantiene una relacion con la clase Tablero para que le aporte esa informacion. @param Tablero &juego: Objeto de la clase Tablero. @return @c int @post - Devuelve un int que nos proporciona el numero de casillas vacias. - No MODIFICA nada. */ int ArbitroCuentaCasillasVacias (Tablero &juego); /** @brief El arbitro decide el jugador de inicio para comenzar la primera partida. @param bool &j1_comienza: Determina que jugador debe comenzar la primera partida. @param int &j_inicio: Contabiliza quien es el primer jugador en comenzar. Si el numero es par empieza el primer jugador si es impar el segundo jugador. @return @c void @post - Determina quien es el primer jugador en empezar para la primera partida. - MODIFICA @c j1_comienza. */ void ArbitroDecideJugadorInicio (int j_inicio, bool &j1_comienza); /** @brief El arbitro muestra por la salida estandar las puntuaciones finales de los dos jugadores. @param int puntos_jugador1: Contiene los puntos ganados por el jugador 1. @param int puntos_jugador2: Contiene los puntos ganados por el jugador 2. @param Arbitro &datos: Es un objeto de la estructura Arbitro con datos referentes a la partida. @return @c void @post - Muestra por la salida estandar las puntuaciones de los jugadores. - No MODIFICA nada. */ void ArbitroEscribePuntuacionFinal (int puntos_jugador1, int puntos_jugador2, Arbitro &datos); /** @brief El arbitro pregunta y/o guarda los datos de una partida que anteriormente se han introducido por la entrada estandar en un fichero .CFG. @param int t_filas: Numero de filas del tablero. @param int t_columnas: Numero de columnas del tablero. @param Arbitro &datos: Es un objeto de la estructura Arbitro con datos referentes a la partida y el tablero. @pre - 4 <= t_filas <= FilasTablero(i) - 4 <= t_columnas <= ColumnasTablero(i) - Debe haber suficiente espacio en disco para guardar el fichero .cfg. @return @c void @post - Pregunta si se desea guardar los datos de una partida, anteriormente introducidos por la entrada estandar, en un fichero .cfg y luego se guarda en la ruta: ./config/.cfg - No MODIFICA nada. */ void ArbitroGuardaDatosFichero (int t_filas, int t_columnas, Arbitro &datos); /** @brief El arbitro realiza una pequeña pausa en el juego entre turno y turno, con un mensaje de espera. El juego se paraliza mediante la funcion Esperar(tiempo) de la biblioteca graficos. @param int tiempo: Tiempo de pausa entre turno y turno (ms) @param Tablero &juego: Objeto de la clase Tablero. @pre - @c 0 <= tiempo (ms) @return @c void @post - Muestra por el pie de la ventana del tablero un mensaje de Espera y paraliza el juego el tiempo establecido en los datos de la partida. - No MODIFICA nada. */ void ArbitroHacePausa (int tiempo, Tablero &juego); /** @brief El arbitro inicia la partida limpiando el cajetin de fichas, si hubiera y restableciendo los controles de partida ganada y continuar en el juego. @param Tablero &juego: Objeto de la clase Tablero.Mantiene una relacion con el Arbitro. @param bool &campeon: Controlador si existe un jugador ganador, se pone a false. @param bool &continuar: Controlador si se debe continuar la partida, se pone a true. @return @c void @post - Se limpia el tablero de fichas y se restablecen los controles de ganar y seguir con la partida. - MODIFICA @c juego, @c campeon y @c continuar */ void ArbitroIniciaPartida (Tablero &juego, bool &campeon, bool &continuar); /** @brief El arbitro lee los datos de un fichero .CFG anteriormente guardado y establece esos datos en sus correspondientes lugares para posteriormente ser usados en la partida. @param const char *nombre_archivo: Nombre del fichero .cfg que contiene los datos de la partida. @param int &t_filas: Numero de filas del tablero. @param int &t_columnas: Numero de columnas del tablero. @param Arbitro &datos: Objeto de la estructura Arbitro para guardar en él los datos que se encuentran en el fichero .cfg. @pre - 4 <= t_filas <= FilasTablero(i) - 4 <= t_columnas <= ColumnasTablero(i) - El fichero .cfg debe existir y con el mismo nombre. @return @c void @post - Lee los datos de un fichero .cfg de configuracion y se guardan en sus correspondientes sitios. - MODIFICA @c t_filas, @c t_columnas y @c datos */ int ArbitroLeeConfiguracion (const char *nombre_archivo, int &t_filas, int &t_columnas, Arbitro &datos); /** @brief El arbitro lee por la entrada estandar los datos referentes a la partida: nombre y nivel de los jugadores, cantidad de fichas, linea para ganar y quien comienza primero. @param int t_filas: Numero de filas del tablero. @param int t_columnas: Numero de columnas del tablero. @param Arbitro &datos: Objeto de la estructura Arbitro para guardar en él los datos referentes a la partida. @pre - 4 <= t_filas <= FilasTablero(i) - 4 <= t_columnas <= ColumnasTablero(i) @return @c void @post - Lee por la entrada estandar los datos exclusivos de la partida y sus jugadores. - MODIFICA @c datos */ void ArbitroLeeDatosPartida (int t_filas, int t_columnas, Arbitro &datos); /** @brief El arbitro lee por la entrada estandar los datos referentes al tablero: ruta de las imagenes, apariencia y tiempo de espera entre cada turno. @param Arbitro &datos: Objeto de la estructura Arbitro para guardar en él los datos referentes al tablero y sus graficos. @return @c void @post - Lee por la entrada estandar los datos exclusivos del tablero y sus graficos. - MODIFICA @c datos */ void ArbitroLeeDatosTablero (Arbitro &datos); /** @brief El arbitro lee por la entrada estandar las dimensiones del tablero. @param int &n_filas: Numero de filas del tablero. @param int &n_columnas: Numero de columnas del tablero. @pre - 4 <= t_filas <= FilasTablero(i) - 4 <= t_columnas <= ColumnasTablero(i) @return @c void @post - Lee por la entrada estandar las dimensiones del tablero. - MODIFICA @c n_filas y @c n_columnas */ void ArbitroLeeDimensionesTablero (int &n_filas, int &n_columnas); /** @brief El arbitro permite que los jugadores participen en el juego, de manera que mantiene una relacion con la clase Jugador para poder llamar a las funciones de los tres tipos de jugadores: (0) manual, (1) automatico-aleatorio y (2) automatico-minima_inteligencia segun el jugador que le corresponda echar. Tambien se comprueba que la columna no este llena en tal caso se vuelve a pedir otra columna que este libre. @param int nivel: Nivel del jugador al que le corresponde echar. @param int linea: Numero de fichas a alinear para ganar. @param int valor: Determina mediante un numero entero sobre quien de los dos jugadores hay que realizar el permiso de echar (1):Jugador 1 (2): Jugador 2 @param Tablero &juego: Objeto de la clase Tablero. @param Jugador &participante: Objeto de la clase Jugador que nos va a permitir llamar a las funciones de los tres tipos de jugadores. @param int &columna: Posicion de la columna del tablero donde el jugador desea echar la ficha. @param int &fila: Posicion de la fila que queda indicado por las fichas que haya anteriormente en esa columna y que no se puede echar mas si esta completa la columna. @pre - 0 <= fila < FilasTablero(i) - 0 <= columna < ColumnasTablero(i) - 2 < @c linea <= (FilasTablero(i) o ColumnasTablero(i)) @return @c void @post - Se llama a las funciones de los jugadores ya establecidas en la clase Jugador. - MODIFICA @c juego , @c columna y @c fila */ void ArbitroPermiteTurnoJugador (int nivel, int linea, int valor, Tablero &juego, Jugador &participante, unsigned int &columna, int &fila); /** @brief El arbitro muestra en el pie de la ventana un mensaje advirtiendo que ha acabado la partida y pregunta si se desea echar otra ronda. @param int valor: Determina mediante un entero que tipo de mensaje debe mostrar.Si ha acabado la partida porque se ha ganado o si se ha acabado porque no hay espacio en el tablero. @param Tablero &juego: Objeto de la clase Tablero. @return @c int @post - Devuelve un entero con el codigo de la (S) o el de la (N). - No MODIFICA nada. */ int ArbitroMuestraMensajeSeguir (int valor, Tablero &juego); /** @brief El arbitro muestra en el pie de la ventana un mensaje advirtiendo que ha acabado la partida y pregunta si se desea echar otra ronda y restablece el controlador de continuar la partida a true. @param int valor: Determina mediante un entero que tipo de mensaje debe mostrar.Si ha acabado la partida porque se ha ganado o si se ha acabado porque no hay espacio en el tablero. @param bool &continuar: Controlador de continuar la partida, se pone a true si es afirmativo. @param Tablero &juego: Objeto de la clase Tablero. @return @c void @post - Muestra el mensaje y si es afirmativo se restablece continuar a true. - No MODIFICA nada. */ void ArbitroPreguntaSeguirPartida (int valor, bool &continuar, Tablero &juego); /** @brief El arbitro prepara la puntuacion de la ronda finalizada si existe un ganador y calcula la puntuacion de los jugadores. @param bool j1_ganador: Determina cual de los dos jugadores ha ganado y obtiene su puntuacion. @param int linea: Numero de fichas a alinear para ganar. @param Tablero &juego: Objeto de la clase Tablero. @param int &puntos_j1: Puntuacion del jugador 1 para la ronda finalizada. @param int &puntos_j2: Puntuacion del jugador 2 para la ronda finalizada. @return @c void @post - Prepara las puntuaciones de los jugadores si se ha ganado. - MODIFICA @c puntos_j1 y @c puntos_j2. */ void ArbitroPreparaPuntuacionRonda (bool j1_ganador, int linea, Tablero &juego, int &puntos_j1, int &puntos_j2); /** @brief El arbitro restaura el turno del siguiente jugador al que le toca echar ficha. @param bool j1_comienza: Controlador de cual es el jugador que le corresponde el turno durante la partida. @return @c void @post - Restaura el turno del jugador modificando el controlador. - MODIFICA @c j1_comienza. */ void ArbitroRestauraTurnoJugador (bool &j1_comienza); /** @brief El arbitro vacia el tablero de fichas cuando se comienza una partida de nuevo. @param Tablero &juego: Objeto de la clase Tablero. El arbitro mantiene una relacion con la clase Tablero para informar de que el tablero debe vaciarse y quitando las fichas contenidas en la anterior partida. @return @c void @post - Elimina las fichas que habia de la partida anterior. - MODIFICA @c juego. */ void ArbitroVaciaTablero (Tablero &juego); /** @brief Funcion auxiliar que comprueba si existe el fichero .cfg @param bool j1_comienza: Controlador de cual es el jugador que le corresponde el turno durante la partida. @return @c const char *nombre_archivo: Nombre del archivo sobre el que la funcion debe comprobar si existe. @post - Devuelve true si existe el fichero y false en caso contrario. - No MODIFICA nada. */ bool ExisteFichero (const char *nombre_archivo); /** @brief El arbitro guarda los datos de una partida que anteriormente se han introducido por la entrada estandar en un fichero .CFG. @param const char *nombre_archivo: Nombre del archivo .cfg que se va a guardar. @param int t_filas: Numero de filas del tablero. @param int t_columnas: Numero de columnas del tablero. @param Arbitro &datos: Es un objeto de la estructura Arbitro con datos referentes a la partida y el tablero. @pre - 4 <= t_filas <= FilasTablero(i) - 4 <= t_columnas <= ColumnasTablero(i) - Debe haber suficiente espacio en disco para guardar el fichero .cfg. @return @c void @post - Guarda los datos de una partida, anteriormente introducidos por la entrada estandar, en un fichero .cfg y luego se guarda en la ruta: ./config/.cfg - No MODIFICA nada. */ int GuardarConfiguracion (const char* nombre_archivo, int t_filas, int t_columnas, Arbitro &datos); /** @brief Realiza la ejecucion de la partida grafica. En este modo se visualiza el tablero pero siempre y cuando uno de los dos jugadores dispongan de un nivel manual, en caso contrario se visualizara por la salida estandar un aviso de porque no se ejecuta la partida grafica y poder asi rectificar. Los datos de la partida y todo el proceso se gestiona con los modulos del Arbitro. @param Arbitro &datos: Objeto de la estructura Arbitro. Contiene los datos referentes a la partida y las ubicaciones de las imagenes para que el tablero pueda gestionarlas. @param Tablero &juego: Objeto de la clase Tablero. Permite la creacion del tablero y la gestion para que se represente en el tablero lo que ocurre en cada momento sobre la partida. @pre - No haber dos jugadores con niveles automaticos. @return @c void @post - Ejecucion de la partida grafica. - No MODIFICA nada. */ void PartidaGrafica (Arbitro &datos, Tablero &juego); /** @brief Realiza la ejecucion de la partida de simulacion. En este modo no se visualizara el tablero ya que su funcion es unicamente de fines estadísticos para comprobar cual de dos jugadores automaticos dispone de mas inteligencia. Para ello se realizara un numero de partidas y se obtendran las puntuaciones totales del numero de partidas. No puede haber en este modo ningun jugador de nivel manual, en caso contrario se visualizara por la salida estandar un aviso de que jugadores disponen de un nivel manual y poder asi rectificar. Los datos de la partida y todo el proceso se gestiona con los modulos del Arbitro. @param int n_partidas: Numero de partidas a echar entre los dos jugadores automaticos. @param Arbitro &datos: Objeto de la estructura Arbitro. Contiene los datos referentes a la partida y las ubicaciones de las imagenes para que el tablero pueda gestionarlas. @param Tablero &juego: Objeto de la clase Tablero. Permite la gestion para que se sepa lo que ocurre en el tablero. @pre - No haber un jugador con nivel manual. @return @c void @post - Ejecucion de la partida en modo simulacion. - No MODIFICA nada. */ void PartidaSimulacion (int n_partidas, Arbitro &datos, Tablero &juego); /** @brief Contabilizar el numero de casillas vacias despues de ganar la partida @return @c int @post - La cantidad de casillas no usadas al terminar la partida para añadirlas a la puntuacion final que luego se usara en la clase @c Datos - No MODIFICA nada. */ int main(int argc, char **argv ) { //Declaracion de los objetos de las clases Arbitro controlador; //Declaracion de las variables locales; int filas_tablero, columnas_tablero, numero_partidas; if (argc > 3){ cerr << "Error en los parametros" << endl; cerr << "Uso: ./conectan " << endl; exit (1); } if (argc == 1){ //Leer los datos del programa ArbitroLeeDatosTablero (controlador); ArbitroLeeDimensionesTablero (filas_tablero, columnas_tablero); //Declarar el objeto Tablero Tablero cajetin (filas_tablero, columnas_tablero); ArbitroLeeDatosPartida (filas_tablero, columnas_tablero, controlador); ArbitroGuardaDatosFichero (filas_tablero, columnas_tablero, controlador); PartidaGrafica (controlador, cajetin); } if (argc == 2){ //Llamada a la funcion de lectura de ficheros. if(ArbitroLeeConfiguracion (argv[1], filas_tablero, columnas_tablero, controlador)){ //Llamada al constructor del tablero virtual Tablero cajetin(filas_tablero, columnas_tablero); //Realiza la partida grafica PartidaGrafica (controlador, cajetin); } else{ // Si falla la lectura del fichero se termina la ejecucion del conectaN cerr << "Terminando la ejecucion del programa...\n"; exit(2); } } if (argc == 3){ if (ArbitroLeeConfiguracion (argv[1], filas_tablero, columnas_tablero, controlador)){ //Llamada al constructor del tablero virtual Tablero cajetin (filas_tablero, columnas_tablero); numero_partidas = atoi(argv[2]); PartidaSimulacion (numero_partidas, controlador, cajetin); } else{ // Si falla la lectura del fichero se termina la ejecucion del conectaN cerr << "Terminando la ejecucion del programa...\n"; exit(2); } } return (0); } void ArbitroAvisaJugadaGanadora (int fila, unsigned int columna, char orientacion, int linea, Tablero &juego) { int f_iterador, c_iterador, radio, t_columnas, coordenada_x, coordenada_y, casillas_x, casilla_centrada, alto_ficha, ancho_ficha, alto_cabecera, ancho_cabecera; t_columnas = juego.ColumnasTablero(); alto_ficha = juego.GetAlturaFicha(); ancho_ficha = juego.GetAnchoFicha(); alto_cabecera = juego.GetAlturaCabecera(); ancho_cabecera = juego.GetAnchoCabecera(); casillas_x = t_columnas * ancho_ficha; radio = (alto_ficha / 2) - 1; coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); //Iluminar la linea ganadora dependiendo de su orientacion if (casillas_x >= ancho_cabecera){ coordenada_x = (alto_ficha / 2) - 1; switch (orientacion){ case 'h': coordenada_y += (alto_ficha * fila); for (f_iterador = 0; f_iterador < 3; f_iterador++){ coordenada_x += (ancho_ficha * columna); for (c_iterador = columna; c_iterador < (columna + linea); c_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_x += ancho_ficha; } coordenada_x = (ancho_ficha / 2) - 1; } break; case 'v': coordenada_x += (ancho_ficha * columna); for (c_iterador = 0; c_iterador < 3; c_iterador++){ coordenada_y += (alto_ficha * fila); for (f_iterador = fila; f_iterador < (fila + linea); f_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_y += alto_ficha; } coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); } break; case 'i': for (c_iterador = 0; c_iterador < 3; c_iterador++){ coordenada_x += (ancho_ficha * columna); coordenada_y += (alto_ficha * fila); for (f_iterador = 0; f_iterador < linea; f_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_x += ancho_ficha; coordenada_y += alto_ficha; } coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); coordenada_x = (ancho_ficha / 2) - 1; } break; case 'd': for (c_iterador = 0; c_iterador < 3; c_iterador++){ coordenada_x += (ancho_ficha * columna); coordenada_y += (alto_ficha * fila); for (f_iterador = 0; f_iterador < linea; f_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_x += ancho_ficha; coordenada_y += alto_ficha; } coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); coordenada_x = (ancho_ficha / 2) - 1; } break; } } else{ casilla_centrada = (ancho_cabecera - casillas_x) / 2; coordenada_x = casilla_centrada + ((ancho_ficha / 2) - 1); switch (orientacion){ case 'h': coordenada_y += (alto_ficha * fila); for (f_iterador = 0; f_iterador < 3; f_iterador++){ coordenada_x += (ancho_ficha * columna); for (c_iterador = columna; c_iterador < (columna + linea); c_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_x += ancho_ficha; } coordenada_x = casilla_centrada + ((ancho_ficha / 2) - 1); } break; case 'v': coordenada_x += (ancho_ficha * columna); for (c_iterador = 0; c_iterador < 3; c_iterador++){ coordenada_y += (alto_ficha * fila); for (f_iterador = fila; f_iterador < (fila + linea); f_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_y += alto_ficha; } coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); } break; case 'i': for (c_iterador = 0; c_iterador < 3; c_iterador++){ coordenada_x += (ancho_ficha * columna); coordenada_y += (alto_ficha * fila); for (f_iterador = 0; f_iterador < linea; f_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_x += ancho_ficha; coordenada_y += alto_ficha; } coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); coordenada_x = casilla_centrada + ((ancho_ficha / 2) - 1); } break; case 'd': for (c_iterador = 0; c_iterador < 3; c_iterador++){ coordenada_x += (ancho_ficha * columna); coordenada_y += (alto_ficha * fila); for (f_iterador = 0; f_iterador < linea; f_iterador++){ Circulo (coordenada_x, coordenada_y, radio, 255, 128, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 0, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio, 255, 255, 0); Esperar (150); Circulo (coordenada_x, coordenada_y, radio - 1, 255, 255, 0); Esperar (150); coordenada_x -= ancho_ficha; coordenada_y += alto_ficha; } coordenada_y = alto_cabecera + ((alto_ficha / 2) - 1); coordenada_x = casilla_centrada + ((ancho_ficha / 2) - 1); } break; } } } void ArbitroAvisaTurnoJugador (char nombre[], Tablero &juego) { char cadena[256] = "Turno de "; int coordenada_x, coordenada_y; strcat (cadena, nombre); coordenada_x = (ColumnasVentana() - 85) / 2; coordenada_y = FilasVentana() - 21 ; juego.PintarPieTablero(); //Mostrar el turno a quien le corresponde Texto (coordenada_x, coordenada_y, cadena, 255, 255, 0); } int ArbitroCalculaPuntuacionRonda (int tamanio, int numero_vacios, int linea) { int puntuacion; //Calculo de la puntuacion del jugador puntuacion = (10 * linea) + (5 * tamanio) + (2 * numero_vacios); return (puntuacion); } void ArbitroCambiaTurnoNuevaRonda (bool &j1_comienza, int &j_inicio, bool &completo) { //Dependiendo del numero de partida se cambia de turno si es par o impar. j_inicio++; ArbitroDecideJugadorInicio(j_inicio, j1_comienza); if (completo) completo = false; } char ArbitroCompruebaJugada (int valor, int &fila, unsigned int &columna, int linea, Tablero &juego, bool &campeon, bool &completo) { char colocacion; if (valor == 1){ juego.TableroInsertaFicha (fila, columna, valor); campeon = ArbitroCompruebaJugadorGanaPartida (linea, valor, juego, fila, columna, colocacion); completo = juego.TableroCompleto(); } else{ juego.TableroInsertaFicha (fila, columna, valor); campeon = ArbitroCompruebaJugadorGanaPartida (linea, valor, juego, fila, columna, colocacion); completo = juego.TableroCompleto(); } return (colocacion); } bool ArbitroCompruebaJugadorGanaPartida (int linea, int valor, Tablero &juego, int &fila_inicio, unsigned int &columna_inicio, char &orientacion) { int fila, columna, t_filas, t_columnas = juego.ColumnasTablero(), iterador = linea - 1, posicion; int cadena[t_columnas]; bool ganar = false; t_filas = juego.FilasTablero(); //Elabora la secuencia a buscar for (columna = 0; columna < linea; columna++) cadena[columna] = valor; //Busca la secuencia for (fila = t_filas - 1; fila >= 0 && !ganar; fila--){ for (columna = t_columnas - 1; columna >= 0 && !ganar; columna--){ if (juego.GetTablero (fila, columna) == cadena[iterador]) iterador--; else iterador = linea - 1; //Si la encuentra devuelve la columna de inicio y la fila de inicio donde comienza la secuencia si ha ganado if (iterador < 0){ ganar = true; fila_inicio = fila; columna_inicio = columna; //La letra marca la orientacion de la secuencia orientacion = 'h'; } } iterador = linea - 1; } iterador = linea - 1; for (columna = 0; columna < t_columnas && !ganar; columna++){ for (fila = t_filas - 1; fila >= 0 && !ganar; fila--){ if (juego.GetTablero (fila, columna) == cadena[iterador]) iterador--; else iterador = linea - 1; if (iterador < 0) ganar = true; fila_inicio = fila; columna_inicio = columna; orientacion = 'v'; } iterador = linea - 1; } iterador = linea - 1; for (fila = t_filas - 1; fila >= linea - 1 && !ganar; fila--){ for (columna = t_columnas - 1; columna >= linea - 1 && !ganar; columna--){ for (posicion = 0; posicion <= linea - 1 && !ganar; posicion++){ if (juego.GetTablero ((fila - posicion), (columna - posicion)) == cadena[iterador]) iterador--; else iterador = linea - 1; if (iterador < 0){ ganar = true; fila_inicio = fila - posicion; columna_inicio = columna - posicion; orientacion = 'i'; } } iterador = linea - 1; } iterador = linea - 1; } iterador = linea - 1; for (fila = t_filas - 1; fila >= linea - 1 && !ganar; fila--){ for (columna = 0; columna < t_columnas - (linea - 1) && !ganar; columna++){ for (posicion = 0; posicion <= linea - 1 && !ganar; posicion++){ if (juego.GetTablero((fila - posicion), (columna + posicion)) == cadena[iterador]) iterador--; else iterador = linea - 1; if (iterador < 0){ ganar = true; fila_inicio = fila - posicion; columna_inicio = columna + posicion; orientacion = 'd'; } } iterador = linea - 1; } iterador = linea - 1; } return (ganar); } int ArbitroCuentaCasillasVacias (Tablero &juego) { int numero_fichas = 0, fila, columna, t_filas, t_columnas; t_filas = juego.FilasTablero(); t_columnas = juego.ColumnasTablero(); //Contabiliza el numero de ficha de valor 0 (vacias) para despues sumarlas a la puntuacion for (fila = 0; fila < t_filas; fila++){ for (columna = 0; columna < t_columnas; columna++){ if (juego.GetTablero (fila, columna) == 0) numero_fichas += 1; } } return (numero_fichas); } void ArbitroDecideJugadorInicio (int j_inicio, bool &j1_comienza) { //Se cambia de turno si es par o impar. if (j_inicio % 2 == 0) j1_comienza = true; else j1_comienza = false; } void ArbitroEscribePuntuacionFinal (int puntos_jugador1, int puntos_jugador2, Arbitro &datos) { //Escribir en la salida estandar las puntuaciones junto con sus nombres. cout << "El juego ha finalizado con la siguiente puntuacion: \n"; cout << "\t" << datos.nombre_jugador1 << " de nivel " << datos.nivel_jugador1 << ": " << puntos_jugador1 << "\n"; cout << "\t" << datos.nombre_jugador2 << " de nivel " << datos.nivel_jugador2 << ": " << puntos_jugador2 << "\n"; } void ArbitroGuardaDatosFichero (int t_filas, int t_columnas, Arbitro &datos) { char opcion; char *nombre_archivo; const char *extension = ".cfg"; char archivo_cfg [256]; cout << "\n¿Desea almacenar la configuracion en un archivo (s/n)?: "; cin >> opcion; if (opcion == 's' || opcion == 'S'){ //Nombre del fichero de escritura cout << "Nombre del fichero de configuracion que desea almacenar: "; cin.ignore (256, '\n'); cin.getline (archivo_cfg, 256); //Colocar ruta y extension .cfg strcpy (datos.ruta, "./config/"); strcat (datos.ruta, archivo_cfg); strcat (datos.ruta, extension); //Dependiendo de la opcion se guarda o no nombre_archivo = datos.ruta; if(GuardarConfiguracion (nombre_archivo, t_filas, t_columnas, datos)) cout << "El fichero se guardo en: " << nombre_archivo << " con EXITO\n"; else cerr << "El fichero NO pudo guardarse\n"; } } void ArbitroHacePausa (int tiempo, Tablero &juego) { int coordenada_x, coordenada_y; coordenada_x = (ColumnasVentana() - 85) / 2; coordenada_y = FilasVentana() - 21 ; juego.PintarPieTablero(); //Muestra un mensaje de espera y espera tiempo Texto (coordenada_x, coordenada_y, "Espere Por Favor...", 255, 255, 0); Esperar (tiempo); } void ArbitroIniciaPartida (Tablero &juego, bool &campeon, bool &continuar) { //Se limpia el tablero de fichas virtuales. ArbitroVaciaTablero(juego); campeon = false; continuar = true; } int ArbitroMuestraMensajeSeguir (int valor, Tablero &juego) { int tecla, coordenada_x, coordenada_y; coordenada_x = (ColumnasVentana()- 170) / 2; coordenada_y = FilasVentana() - 21 ; juego.PintarPieTablero(); //Confirmar si se quiere jugar de nuevo if (valor == 1){ do{ Texto (coordenada_x, coordenada_y, "!!!GANASTES!!! Seguir? (S/N)", 255, 255, 0); tecla = ObtenerTecla(); }while (tecla !=39 && tecla !=57); } else{ do{ Texto (coordenada_x, coordenada_y, "!NADIE GANA! Seguir? (S/N)", 255, 255, 0); tecla = ObtenerTecla(); }while (tecla !=39 && tecla !=57); } return (tecla); } void ArbitroPermiteTurnoJugador (int nivel, int linea, int valor, Tablero &juego, Jugador &participante, unsigned int &columna, int &fila) { //Usar el jugador necesario segun el nivel switch (nivel){ case 0: do{ participante.JugadorManual (juego, columna); fila = juego.GetFilasRestantes (columna); }while (fila < 0); break; case 1: do{ columna = participante.JugadorAleatorio(juego); fila = juego.GetFilasRestantes (columna); }while (fila < 0); break; case 2: do{ columna = participante.JugadorInteligente (juego, linea, valor); fila = juego.GetFilasRestantes (columna); }while (fila < 0); break; } } void ArbitroPreguntaSeguirPartida (int valor, bool &continuar, Tablero &juego) { //Se pregunta si se quiere jugar otra vez. int codigo; codigo = ArbitroMuestraMensajeSeguir(valor, juego); if (codigo == 57) continuar = false; } void ArbitroPreparaPuntuacionRonda (bool j1_ganador, int linea, Tablero &juego, int &puntos_j1, int &puntos_j2) { int cantidad_vacios, tamanio; tamanio = (juego.FilasTablero() * juego.ColumnasTablero()); //Se busca que jugador ha ganado y se calcula su puntuacion if (j1_ganador){ cantidad_vacios = ArbitroCuentaCasillasVacias (juego); puntos_j1 += ArbitroCalculaPuntuacionRonda (tamanio, cantidad_vacios, linea); }else{ cantidad_vacios = ArbitroCuentaCasillasVacias (juego); puntos_j2 += ArbitroCalculaPuntuacionRonda (tamanio, cantidad_vacios, linea); } } void ArbitroRestauraTurnoJugador (bool &j1_comienza) { if (j1_comienza == false) j1_comienza = true; } int ArbitroLeeConfiguracion (const char* nombre_archivo, int &t_filas, int &t_columnas, Arbitro &datos) { ifstream fichero_entrada; int i, tamanio = 256; char ruta_fichero [256] = "./config/"; char buffer [256]; char *buffer_2; //Preparar la ruta hasta la carpeta ./config strcat (ruta_fichero, nombre_archivo); //Comprobar si existe el fichero if (!ExisteFichero(ruta_fichero)){ cerr << "\nERROR: NO se encuentra el fichero de configuracion: " << "---> " << nombre_archivo << endl; return (0); } else cout << "\nEXITO: HE encontrado el fichero: " << "---> " << nombre_archivo << endl; fichero_entrada.open (ruta_fichero); // Abrir el fichero para lectura fichero_entrada.getline (buffer, 256); // Leer cadena "magica" //Comprobar si es un fichero CFG if (strcmp ("CFG-CONECTAN", buffer)){ cerr << "ERROR: " << nombre_archivo << " no es un fichero CFG\n"; return (0); } //Salto de comentarios do{ fichero_entrada.getline (buffer, 256); }while (buffer[0] == '#'); //Extraer recursos buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio ; i++) datos.dir_imagen[i-1] = buffer_2[i]; //Salto de comentarios do{ fichero_entrada.getline (buffer, 256); }while (buffer[0] == '#'); //Extraer apariencia buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) datos.tema[i-1] = buffer_2[i]; //Salto de comentarios do{ fichero_entrada.getline (buffer, 256); }while (buffer[0]=='#'); //Extraer tiempo buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; datos.tiempo_espera = atoi(buffer); //Salto de comentarios do{ fichero_entrada.getline (buffer, 256); }while (buffer[0]=='#'); //Extraer filas y columnas buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; sscanf (buffer, "%d %d", &t_columnas, &t_filas); //Salto de comentarios do{ fichero_entrada.getline (buffer, 256); }while (buffer[0]=='#'); //Extraer el numero de fichas a alinear buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; datos.fichas_linea = atoi(buffer); //Salto de comentarios do{ fichero_entrada.getline (buffer, 256); }while (buffer[0]=='#'); //Extraer el numero de fichas por turno buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; datos.fichas_turno = atoi(buffer); //Salto de comentarios do{ fichero_entrada.getline (buffer, tamanio); }while (buffer[0]=='#'); //Extraer el nombre del jugador 1 buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) datos.nombre_jugador1[i-1] = buffer_2 [i]; //Salto de comentarios do{ fichero_entrada.getline (buffer, tamanio); }while (buffer[0]=='#'); //Extraer el nivel del jugador 1 buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; datos.nivel_jugador1 = atoi(buffer); //Salto de comentarios do{ fichero_entrada.getline (buffer, tamanio); }while (buffer[0]=='#'); //Extraer el nombre del jugador 2 buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) datos.nombre_jugador2[i-1] = buffer_2 [i]; //Salto de comentarios do{ fichero_entrada.getline (buffer, tamanio); }while (buffer[0]=='#'); //Extraer el nivel del jugador 2 buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; datos.nivel_jugador2 = atoi(buffer); //Salto de comentarios do{ fichero_entrada.getline (buffer, tamanio); }while (buffer[0]=='#'); //Extraer el jugador que comienza buffer_2 = strstr (buffer, "="); //Quitar el igual for (i=1; i <= tamanio; i++) buffer[i-1] = buffer_2 [i]; datos.jugador_comienza = atoi(buffer); //Cerrar el fichero de lectura fichero_entrada.close (); return (1); } void ArbitroLeeDatosPartida (int t_filas, int t_columnas, Arbitro &datos) { //Numero de fichas do{ cout << "\t- Fichas para linea: "; cin >> datos.fichas_linea; }while (datos.fichas_linea < 3 || datos.fichas_linea >= t_filas || datos.fichas_linea >= t_columnas); //Numero de fichas por turno do{ cout << "\t- Numero de fichas por turno: "; cin >> datos.fichas_turno; }while (datos.fichas_turno < 1 || datos.fichas_turno > datos.fichas_linea - 2); //Nombre del primer jugador cout << "\t- Nombre del primer jugador: "; cin.ignore (256, '\n'); cin.getline (datos.nombre_jugador1, 256); //Nivel del primer jugador do{ cout << "\t- Nivel del primer jugador (0 manual): "; cin >> datos.nivel_jugador1; }while (datos.nivel_jugador1 < 0 || datos.nivel_jugador1 > 2); //Nombre del segundo jugador cout << "\t- Nombre del segundo jugador: "; cin.ignore (256, '\n'); cin.getline (datos.nombre_jugador2, 256); //Nivel del segundo jugador do{ cout << "\t- Nivel del segundo jugador (0 manual): "; cin >> datos.nivel_jugador2; }while (datos.nivel_jugador2 < 0 || datos.nivel_jugador2 > 2); //Comienzo del jugador do{ cout << "\t- Jugador que comienza (0 o 1): "; cin >> datos.jugador_comienza; }while (datos.jugador_comienza != 0 && datos.jugador_comienza != 1); } void ArbitroLeeDatosTablero (Arbitro &datos) { cout << "\n|||---|||---||| CrEaR CoNfIgUrAcIoN |||---|||---|||\n" << endl; //Leer directorio de imagenes cout << "\t- Directorio de imágenes: "; cin.getline (datos.dir_imagen, 256); //Leer tema cout << "\t- Tema seleccionado: "; cin.getline (datos.tema, 255); do{ cout << "\t- Tiempo de espera (ms): "; cin >> datos.tiempo_espera; }while (datos.tiempo_espera <= -1); } void ArbitroLeeDimensionesTablero (int &t_filas, int &t_columnas) { //Dimensiones del tablero do{ cout << "\t- Dimensiones (col, fil): "; cin >> t_columnas >> t_filas; }while (t_columnas < 4 || t_filas < 4); } void ArbitroVaciaTablero (Tablero &juego) { int fila, t_filas, t_columnas; int unsigned columna; t_filas = juego.FilasTablero(); t_columnas = juego.ColumnasTablero(); //Limpia el tablero virtual (tablero) de fichas inicianizandolo todo a 0 for (fila = 0; fila < t_filas ; fila++){ for (columna = 0; columna < t_columnas; columna++) juego.SetTablero (fila, columna , 0); } //Reinicia el contador de filas for (columna = 0; columna < t_columnas; columna++) juego.SetFilasRestantes (columna, t_filas - 1); } bool ExisteFichero (const char* nombre_archivo) { ifstream fichero_entrada; bool problema; fichero_entrada.open (nombre_archivo); problema = fichero_entrada.fail(); if (!problema) fichero_entrada.close(); return ((problema) ? false : true); } int GuardarConfiguracion (const char* nombre_archivo, int t_filas, int t_columnas, Arbitro &datos) { ofstream fichero_salida; //Abrir el fichero fichero_salida.open (nombre_archivo); //Comprobar que hay permiso de escritura o espacio if (fichero_salida.fail()){ fichero_salida.close(); return (0); } //Guardar informacion en el fichero fichero_salida << "CFG-CONECTAN\n"; fichero_salida << "# Fichero de configuracion para " << datos.fichas_linea << " en raya\n"; fichero_salida << "# Directorio con las imagenes\n"; fichero_salida << "Recursos=" << datos.dir_imagen << "\n"; fichero_salida << "# Aspecto seleccionado\n"; fichero_salida << "Tema=" << datos.tema << "\n"; fichero_salida << "# Tiempo de espera\n"; fichero_salida << "Tiempo=" << datos.tiempo_espera << "\n"; fichero_salida << "# Tamaño del tablero (Columnas, Filas)\n"; fichero_salida << "Dimensiones=" << t_columnas << " " << t_filas << "\n"; fichero_salida << "# Numero de fichas a alinear\n"; fichero_salida << "Linea=" << datos.fichas_linea << "\n"; fichero_salida << "# Numero de fichas a echar en cada turno\n"; fichero_salida << "Nfichas=" << datos.fichas_turno << "\n"; fichero_salida << "# Nombre del primer jugador\n"; fichero_salida << "Jugador1=" << datos.nombre_jugador1 << "\n"; fichero_salida << "# Nivel del primer jugador (0: manual)\n"; fichero_salida << "Nivel1=" << datos.nivel_jugador1 << "\n"; fichero_salida << "# Nombre del segundo jugador\n"; fichero_salida << "Jugador2=" << datos.nombre_jugador2 << "\n"; fichero_salida << "# Nivel del segundo jugador (0: manual)\n"; fichero_salida << "Nivel2=" << datos.nivel_jugador2 << "\n"; fichero_salida << "# Jugador que comienza (0 o 1)\n"; fichero_salida << "Turno=" << datos.jugador_comienza << "\n\n\n"; //Cerrar el fichero fichero_salida.close(); } void PartidaGrafica (Arbitro &datos, Tablero &juego) { //Declaracion del objeto jugador Jugador usuario; //Declaracion de las variables locales; int fila_tablero = 0, puntos_jugador1 = 0, puntos_jugador2 = 0, cantidad_vacios, tirada , tamanio_tablero; unsigned int columna_tablero = 0; bool ganar = false, seguir, jugador1_ganador = false, jugador1_inicio, lleno = false; char colocacion; //Comprobar que no se va a jugar con niveles de simulacion. if (datos.nivel_jugador1 != 0 && datos.nivel_jugador2 !=0){ cerr << "Estos Niveles de jugadores son solo para MODO SIMULACION: \n"; cerr << "--------------------------------------------------------------------------------\n"; if (datos.nivel_jugador1 >= 1 && datos.nivel_jugador2 >= 1){ cerr <<"\t\t\t" << datos.nombre_jugador1 << " <---- AUTOMATICO\n"; cerr <<"\t\t\t" << datos.nombre_jugador2 << " <---- AUTOMATICO\n"; } cerr << "--------------------------------------------------------------------------------\n"; cerr << "Recuerde: para SIMULAR ./bin/conectaN \n"; exit (2); } tamanio_tablero = (juego.FilasTablero() * juego.ColumnasTablero()); //Ver quien empieza primero. ArbitroDecideJugadorInicio(datos.jugador_comienza, jugador1_inicio); do{ //Cargar el tablero graficamente e iniciar la partida. cout << "Cargando Graficos...\n" << "Creando Tablero...\n"; juego.PintaTablero (datos.dir_imagen, datos.tema, datos.fichas_linea); ArbitroIniciaPartida(juego, ganar, seguir); do{ if (jugador1_inicio){ //Tirada jugador 1 for (tirada = datos.fichas_turno; tirada != 0 && !ganar && !lleno; tirada--){ ArbitroAvisaTurnoJugador (datos.nombre_jugador1, juego); //Turno jugador 1 ArbitroPermiteTurnoJugador(datos.nivel_jugador1, datos.fichas_linea, 1, juego, usuario, columna_tablero, fila_tablero); //Representar graficamente la ficha de color 1. juego.TableroPintaFichaJugador (datos.dir_imagen, datos.tema, 1, fila_tablero, columna_tablero); //Procesar movimiento jugador 1 colocacion = ArbitroCompruebaJugada (1, fila_tablero, columna_tablero, datos.fichas_linea, juego, ganar, lleno); if (ganar) jugador1_ganador = true; } //Espera un tiempo entre cada turno ArbitroHacePausa (datos.tiempo_espera, juego); } //Tirada jugador 2 for (tirada = datos.fichas_turno; tirada != 0 && !ganar && !lleno; tirada--){ ArbitroAvisaTurnoJugador (datos.nombre_jugador2, juego); //Turno jugador 2 ArbitroPermiteTurnoJugador (datos.nivel_jugador2, datos.fichas_linea, 2, juego, usuario, columna_tablero, fila_tablero); //Representar graficamene la ficha de color 2. juego.TableroPintaFichaJugador (datos.dir_imagen, datos.tema, 2, fila_tablero, columna_tablero); //Procesar movimiento jugador 2 colocacion = ArbitroCompruebaJugada (2, fila_tablero, columna_tablero, datos.fichas_linea, juego, ganar, lleno); if (ganar) jugador1_ganador = false; } //Esperar un tiempo ArbitroHacePausa (datos.tiempo_espera, juego); //Restaurar turno al jugador 1 ArbitroRestauraTurnoJugador (jugador1_inicio); }while (!ganar && !lleno); //Procesar puntuacion y enfatizar jugada if (ganar){ ArbitroAvisaJugadaGanadora (fila_tablero, columna_tablero, colocacion, datos.fichas_linea, juego); ArbitroPreparaPuntuacionRonda (jugador1_ganador, datos.fichas_linea, juego, puntos_jugador1, puntos_jugador2); //Confirmar si se vuelve a echar otra partida ArbitroPreguntaSeguirPartida (1, seguir, juego); } if (lleno) //Se avisa de que nadie ha gandao por estar el tablero completo de fichas ArbitroPreguntaSeguirPartida (0, seguir, juego); if (seguir) //Cambio de turno en la nueva partida ArbitroCambiaTurnoNuevaRonda (jugador1_inicio, datos.jugador_comienza, lleno); }while (seguir); //Escribir la puntuacion total por la salida estandar ArbitroEscribePuntuacionFinal (puntos_jugador1, puntos_jugador2, datos); } void PartidaSimulacion (int n_partidas, Arbitro &datos, Tablero &juego) { //Declarcion del objeto Jugador Jugador usuario; //Declaracion de variables locales. int fila_tablero = 0, puntos_jugador1 = 0, puntos_jugador2 = 0, cantidad_vacios, tirada, tamanio_tablero, ronda; unsigned int columna_tablero = 0; bool ganar = false, seguir, jugador1_ganador = false, jugador1_inicio, lleno = false; char colocacion; //Comprobar que no se va a jugar con niveles de partida grafica if (datos.nivel_jugador1 == 0 || datos.nivel_jugador2 == 0){ cerr << "\n\t\t\t|||||||ATENCION|||||||\n"; cerr << "\t\t\tExiste un nivel manual: \n"; cerr << "----------------------------------------------\n"; if (datos.nivel_jugador1 == 0) cerr << "\t\t\t" << datos.nombre_jugador1 << " <--- Nivel MANUAL\n"; else cerr << "\t\t\t" << datos.nombre_jugador2 << " <--- Nivel MANUAL\n"; cerr << "----------------------------------------------\n"; cerr << "Recuerde: para JUGAR./bin/conectaN o ./bin/conectaN \n"; cerr << "No pueden EXISTIR niveles manuales en esta opcion.\n"; exit (3); } tamanio_tablero = (juego.FilasTablero() * juego.ColumnasTablero()); ArbitroDecideJugadorInicio(datos.jugador_comienza, jugador1_inicio); cout << "Calculando...\n"; for (ronda = 1; ronda <= n_partidas; ronda++){ //Arbitro Inicia la partida. ArbitroIniciaPartida(juego, ganar, seguir); do{ if (jugador1_inicio){ //Tirada jugador 1 for (tirada = datos.fichas_turno; tirada != 0 && !ganar && !lleno; tirada--){ //Turno jugador 1 ArbitroPermiteTurnoJugador(datos.nivel_jugador1, datos.fichas_linea, 1, juego, usuario, columna_tablero, fila_tablero); //Procesar movimiento jugador 1 colocacion = ArbitroCompruebaJugada (1, fila_tablero, columna_tablero, datos.fichas_linea, juego, ganar, lleno); if (ganar) jugador1_ganador = true; } } //Tirada jugador 2 for (tirada = datos.fichas_turno; tirada != 0 && !ganar && !lleno; tirada--){ ArbitroPermiteTurnoJugador (datos.nivel_jugador2, datos.fichas_linea, 2, juego, usuario, columna_tablero, fila_tablero); //Procesar movimiento jugador 2 colocacion = ArbitroCompruebaJugada (2, fila_tablero, columna_tablero, datos.fichas_linea, juego, ganar, lleno); if (ganar) jugador1_ganador = false; } //Restaurar turno al jugador 1 ArbitroRestauraTurnoJugador (jugador1_inicio); }while (!ganar && !lleno); //Procesar puntuacion y enfatizar jugada if (ganar){ ArbitroPreparaPuntuacionRonda (jugador1_ganador, datos.fichas_linea, juego, puntos_jugador1, puntos_jugador2); } //Cambio de turno para la nueva ronda ArbitroCambiaTurnoNuevaRonda (jugador1_inicio, datos.jugador_comienza, lleno); //Escribir la puntuacion total por la salida estandar } ArbitroEscribePuntuacionFinal (puntos_jugador1, puntos_jugador2, datos); }