PRACTICA 2: SIMULACION DEL JUEGO DE LA VIDA 1.- Explicación del desarrollo del programa: El programa comienza con un menú en el que se pide si se quiere salir del programa y más datos necesarios para el transcurso del juego como los turnos, las celdas del tablero, el número de células con las que deben cambiar o mantener el estado, aunque esto es opcional, ya que se pueden cargar por defecto y el modo de ejecución. Una vez seleccionado todo lo necesario, se muestra un tablero en el que las células vivas aparecen con una V en azul, y las muertas con una M en rojo. Las células en función de el estado inicial, creado al azar, van formando patrones que pueden ser estáticos o dinámicos, éstos pueden moverse en el mismo espacio y otros desplazarse por el tablero tomando otras formas. 2.- Explicación de los vectores y módulos: - Vector de registros ‘células’: se trata de un vector con dos posiciones de vector de la 4 a la 24, consiguiendo de esta manera mayor facilidad para representar un tablero cuadrado, es del tipo TCelulas, definido en ‘TYPE’, por lo que le da tres registros por posición de vector: 1º: actual: en él, solo se pueden almacenar los valores 0 o 1, que indicarán muerta o viva respectivamente. En él se almacenara el valor mas actual de las células para luego actualizar al registro ‘anterior’. 2º: anterior: como en actual, se almacena 1 o 0. Se utiliza para comparar las células vecinas y almacenar otra viva en el vector ‘proximo’, es como si existiesen dos tableros el actual y el anterior, ya que si se compara con el actual, no se puede confiar en que nos almacenará bien el número de células vecinas, ya que van cambiando antes de analizar todo el casillero. 3º: proximo: en el se almacena primero un número aleatorio y después el número de células vecinas para determinar si debe estar viva o muerta. - Bienvenido: es un procedimiento que cuando es llamado únicamente desde el procedimiento MenuInicial se encarga de borrar la pantalla y dar un mensaje de que el programa se encuentra en el menú. Su finalidad es que el menú se desarrolle con más limpieza, ello se ha conseguido con la función clrscr que proporciona el comando uses crt. - MenuInicial: es un procedimiento construido para la captación de los datos obligatorios del juego. Se ha creado con estructuras repeat para controlar que los datos que entren estén en los cánones que marcan las reglas y con {$I-}, {$I+} para controlar la detección de errores de entrada, por lo que en momento en el que está desactivado, mediante un while se chequea el IOResult para no tomar ningún dato erróneo, y mediante una estructura if se toman los valores para x, z , y personalmente o por defecto. - GenerarMundoAleatorio: procedimiento que recrea un mundo de células de manera aleatoria. Esto se consigue mediante el uso doble de la función de crt, randomize. La primera almacena en la variable prob, un número aleatorio. A continuación y siempre que se quiera utilizar el vector de registros, se utilizarán dos estructuras for encadenadas. Mediante un if se considerarán muertas todas las casillas que pertenezcan al marco del tablero y las que no pertenezcan al marco, se volverá a realizar otro random, y con ese dato se comprará con el almacenado en prob y si es mayor o igual se tomará esta como viva, sino como muerta. En el primer random se han tomado los valores del 0 al 7 este incluido y en el segundo del 0 al 8 este también incluido. Se han tomado de esta manera, ya que el máximo de células vecinas son ocho, por ello el valor de segundo, y hasta el 7 en el primero para que haya variedad de mundos aleatorios, que por lo menos exista una posibilidad de que exista un mundo que no estén todas las células muertas (entre 7 y 8). - ActualizarEstadosCelulas: la función de este procedimiento es principalmente actualizar los registros del vector, ya que para el correcto desarrollo del juego se debe testear las células del tablero anterior para conseguir el siguiente, una vez comparados es necesario actualizar el casillero anterior con el actual. Esto se consigue recorriendo el vector con dos for encadenados y copiando los valores ‘actual’ del vector con el ‘anterior’. Además también se inicializará el ‘proximo’ para que no de errores por almacenamiento no deseado en éste. - MostarMarco: este procedimiento se encarga de mostrar el marco donde no puede haber vida, esto se consigue mediante dos for encadenados y con un salto de línea que controlando que se escriba una M roja de célula muerta en los bordes, se consigue un cuadrado, del tamaño del vector con el marco muerto. Se representará cada vez que se presente el tablero con el desarrollo de las células, obteniendo así que sea imposible la vida en el contorno. - MostrarTableroInicial: este procedimiento muestra, mediante dos for encadenados, recorriendo el vector y testeando el estado actual, el tablero inicial. Además, después del primer for, mueve la posición a escribir según la línea que le toque mediante una sencilla ecuación. - MostrarRonda: con este procedimiento se muestran los turnos a terminar el juego, y cuando termina se muestra un mensaje de finalización. La finalidad de este procedimiento es acortar el programa principal. - MostrarTablero: procedimiento que muestra los tableros después de sufrir, al menos, un avance de juego, mediante dos for encadenados que recorren el vector despreciando la primera y ultima fila y columna, lo que seria el marco de éste. Cuando se llega a una posición a representar, se compara el estado ‘proximo’ donde están almacenadas el número de células vecinas vivas y se compara con los valores de x, y , z, para determinar si debe estar muerta o viva. A continuación se representa o no, según la selección del modo de ejecución en el menú. - CalculosDeLasCelulas: este procedimiento se encarga de contar el número de células vecinas vivas y almacenarlo en ‘proximo’ del vector en la posición que le corresponde. Esto se consigue mediante dos for encadenados dentro de otros dos for encadenados. Los dos primeros indican la posición que se va a comparar (i, j), y con los dos segundos se testean los vecinos. Si imaginamos que i se refiere al eje vertical, y j al horizontal copiamos estos dos datos, le creamos un recorrido desde una posición inferior a i o j, hasta una posición superior a éstas y las empleamos en las dos segundas estructuras for (k, l), con esto se consigue recorrer las posiciones vecinas de la posición (i, j) y mediante un if excluimos testear la posición (i, j), obteniendo así una manera eficaz, sencilla y corta de realizar esta función. A la vez que se recorren se van almacenando en ‘proximo’ el número de células vecinas encontradas. 3.- Explicación del funcionamiento del programa: El programa se ha realizado de manera modular, con algunos encadenados y otros que son llamados de manera secuencial desde el programa principal. El programa principal comienza realizando una llamada a MenuInicial que se encargará de tomar los datos para el desarrollo normal del juego y los mandará como salida al programa principal. La opción de salir del programa se ha resuelto con la función exit, que saldrá inmediatamente del módulo y después en el programa principal se volverá a repetir esta función saliendo definitivamente del programa. Una vez tomados los datos se llama a CrearMundoAleatorio, al que se le pasarán y utilizará como entrada la variable casillas y como entrada y salida al vector de registros células. En este procedimiento se cargará en el vector células, aleatoriamente un estado de vivo o muerto. Después se mostrará el tablero con las posiciones aleatorias mediante los procedimientos: - MostrarMarco: se encarga de mostrar marco y utilizará como entrada la variable casillas para determinar el contorno. - MostrarTableroInicial: mostrará las posiciones centrales aleatorias sin contar con lo que seria el marco, se le pasará como argumento casillas y el vector células, el primero será de entrada para determinar las posiciones a recorrer y el segundo como salida. A continuación se realizará un repeat que repetirá las siguientes funciones según el número de turnos que se exigieron: - CalculosDeLasCelulas: contará las células vecinas vivas y las guardará el `proximo` del vector de registros en la posición de su célula. Para ello se mandan los datos de casillas, x, y, z, ejecución, turnos y células. No todos son utilizados por este procedimiento, los otros que son enviados es porque a partir de aquí los procedimientos van encadenados y son necesarios para hacer las demás llamadas. Solo se tomará de salida el vector células y se emplearán en este procedimiento las variables casillas ejecución (ejec) y turnos. Una vez contadas todas las células vecinas hay que determinar por su número almacenado en ‘proximo’ cuales estarán vivas y cuales muertas, esto se realizará en el procedimiento MostrarTablero, pero antes hay que mostrar el marco en MostrarMarco. Antes de hacer el llamamiento a marco se tendrá en cuenta que el usuario no ha marcado la opción de ‘solo resultados’, si es así no se mostrará el marco hasta el último turno. Pero si la opción es paso a paso, se mostrará el marco, se llamará a MostarTablero y de esta manera se representará todo el casillero. Después se mostrará la ronda en la que se encuentra el programa mediante MostrarRonda, al que se le mandará como argumentos a turnos y ejec, cuya misión será mostrar los turnos o el comentario final de manera apropiada. El último paso es quitarle un turno a la variable turnos para que cuando sea cero, regrese al MenuInicial mediante un repeat que abarca todo el programa principal, con una condición que no se puede cumplir, por lo que la única manera de salir del programa es mediante la función exit. Los nombres de los argumentos pasados a los módulos coinciden con la variable, ya que de esta manera es más fácil de programar y entender salvo cuando se pasa la variable ejecutar, la cual se ha cambiado a ejec, con el único fin de dar a conocer que se entiende el manejo de los pasos de datos a los módulos. El vector células se ha tomado como entrada y salida en todos los módulos, ya que en todos modifica su valor, excepto en MostrarTableroIncial que si no se toma como salida da error de desbordamiento de pila, que se puede configurar desactivando la opción star cheking, pero por se acaso se ha dejado como entrada y salida. David Bardají Castel g.03 puesto 4. ---------------------------- (añadido tras someter) ---------------------------- 19:30:41 11/12/09 -> Segun los datos introducidos los ficheros son: G03P04D2 -> Los autores del trabajo son: Bardaji Castel, David Diez Sainz, Felix Nombres originales de los archivos entregados -> juego de la vida.PAS, memoria juego de la vida.txt