PROGRAMACIÓN I | DPTO. INFORMÁTICA |
Como es sabido, el juego del ajedrez es originario de la India. Incluso la propia palabra ajedrez procede del término sánscrito chaturanga, que significa "el Juego de los Cuatro Reyes".
De hecho, el ajedrez se sigue jugando en la India en su forma original, que (como indica su nombre) es ligeramente distinta a la habitual. Para empezar, no se tienen sólo dos bandos sino cuatro (Amarillo, Rojo, Verde y Negro), y no existe la pieza que representa la Dama. No obstante, el resto de las figuras y el tablero de juego son iguales al del ajedrez que conocemos. La disposición inicial de las 32 piezas en el tablero es la siguiente:
A pesar de existir cuatro bandos, no es un juego de todos contra todos, sino que los bandos Amarillo y Rojo cooperan entre sí, al igual que los bandos Verde y Negro. Así sucede que, por ejemplo, las piezas del bando Amarillo no pueden comer a las piezas del bando Rojo (bando aliado) y si a las piezas de los bandos Verde y Negro (bandos contrarios).
La partida se desarrolla por turnos, comenzando a mover el bando Amarillo y continuando los bandos Verde, Rojo y Negro. Cuando es capturado (comido) el rey perteneciente a uno de los bandos, ese bando deja de jugar, y su turno pasa al siguiente bando. La partida termina, evidentemente, cuando dos bandos aliados han dejado de jugar por haber sido capturados sus dos reyes.
Otras diferencias respecto al ajedrez normal residen en el movimiento de los peones (su dirección de movimiento depende del bando) y no existen (o no se van a contemplar) el jaque, la coronación, la captura de peones en passant ni la elección de mover dos casillas los peones en la primera jugada. Tampoco existe la posibilidad de que la partida termine en tablas.
Por último, el enroque existe aunque tan sólo se va a contemplar como parte opcional.
El objetivo de la práctica es crear un programa Pascal que sirva de tablero de juego para que varias personas puedan jugar una partida de chaturanga y guardar su desarrollo en un fichero de texto. La partida podrá ser nueva o la continuación de alguna partida ya comenzada (y almacenada en un fichero de texto).
Debe quedar claro que nuestro programa no va a jugar al chaturanga, sino tan sólo servirá de interfaz para que jugadores humanos lo puedan hacer. Sus principales responsabilidades serán representar el tablero en la pantalla, leer las jugadas y detectar si son correctas o erróneas de acuerdo a las reglas del juego.
La parte principal del programa consistirá en la repetición de las siguientes tareas: leer una jugada, verificar que es válida dado el estado del tablero, realizar la jugada, y mostrar los cambios en pantalla.
Como resultado de la ejecución del programa siempre se va a obtener un fichero de texto que contendrá la lista de jugadas realizadas, a razón de una jugada por línea, y con la misma notación que usará el usuario para indicarlas. Por lo tanto, lo primero que debe hacer el programa es preguntar el nombre que queremos darle a ese fichero que va a crear:
Nombre del fichero donde se salvara la partida: _
El siguiente paso es preguntar al usuario si desea jugar una partida nueva o continuar una existente:
Desea continuar una partida? [S/N] _
Si la respuesta es N, el programa comenzará el ciclo de presentar el tablero y pedir, comprobar y realizar jugadas detallado posteriormente. Pero si la respuesta es S, el programa preguntará el nombre del fichero que almacena la partida que se va a continuar:
Nombre del fichero que almacena esa partida: _
Y a partir de ese momento, el programa leerá las jugadas almacenadas en el fichero y las procesará exactamente igual que si las introdujera el usuario. Por lo tanto, la salida por pantalla deberá ser la misma que se detalla a continuación para el caso de jugadas leídas por teclado (incluyendo el que el usuario tenga que pulsar intro para poder observar el efecto de la jugada), con la única salvedad de que ahora las jugadas se leen de un fichero.
Cuando se termine el fichero, o bien en el momento en que se detecte que alguna jugada es errónea, el programa continuará con el ciclo de presentar tablero y pedir, comprobar, y realizar jugadas pero ahora pidiéndoselas al usuario.
El aspecto del programa, en un momento dado de la ejecución, debe ser el siguiente:
Nota: La numeración de la parte superior e izquierda de la imagen no debe aparecer en pantalla, se incluye para mostrar la forma en que se accede a filas y columnas de la pantalla cuando se utilicen los procedimientos BorraFila, Cursor y Rejilla de la unidad Pantalla.
El tablero se muestra como una rejilla dentro de la cual aparecen las piezas representadas por letras del color del bando correspondiente. En la línea 20 se escribe el nombre del bando que tiene el turno y se solicita la jugada del bando al usuario (o se escribe directamente, si se están leyendo las jugadas de un fichero).
La línea 22 sirve como línea de estado, en la que se muestran mensajes referentes a la comprobación de la jugada.
Para indicar una jugada se utilizará una cadena de cinco caracteres con donde aparecerán la casilla origen (que contiene la pieza que se desea mover) y la casilla destino (que indica el lugar donde se quiere mover la pieza), separadas por un guión. Para indicar una casilla se usan dos caracteres: El primero es el número de su fila y el segundo la letra de su casilla.
En el juego de chaturanga, al igual que en el ajedrez normal, es obligatorio que el bando al que corresponde el turno mueva una y sólo una de sus piezas (excepto en el enroque, ver parte opcional). No es posible pasar el turno ni cederlo al bando aliado. Se supondrá que nunca se va a dar una situación en la que ninguna de las piezas de un bando tenga casillas donde hacer un movimiento válido.
En los ejemplos siguientes se va a suponer que la partida se encuentra en esta situación:
Alfil: El alfil se mueve en diagonal,
cualquier número de casillas, hasta que su trayectoria esté
bloqueada por otra pieza o los límites del tablero. Puede capturar cualquier
pieza enemiga que se encuentre en su trayectoria. Se representará en pantalla
por la letra A.
En la posición anterior, las siguientes jugadas serían válidas para el alfil del bando amarillo:
4D-A1, 4D-B2, 4D-C3, 4D-6B, 4D-5C, 4D-1G, 4D-2F, 4D-3E
Torre: La torre se mueve en línea recta,
horizontal o vertical,
cualquier número de casillas, hasta que su trayectoria esté
bloqueada por otra pieza o los límites del tablero. Puede capturar cualquier
pieza enemiga que se encuentre en su trayectoria. Se representará en pantalla
por la letra T.
En la posición anterior, las siguientes jugadas serían válidas para la torre del bando verde:
6D-8D, 6D-7D, 6D-5D, 6D-4D, 6D-6E, 6D-6F, 6D-6G, 6D-6H
Rey: El rey puede moverse (y capturar) a
cualquiera de las casillas contiguas. Se representará en pantalla
por la letra R.
En la posición anterior, las siguientes jugadas serían válidas para el rey del bando negro:
4B-5A, 4B-5C, 4B-4C, 4B-3C, 4B-3B, 4B-3A, 4B-4A
Caballo: Las casillas a las
que se puede mover (o capturar) un caballo se muestran en la siguiente
gráfica:
A diferencia de las otras piezas, el movimiento de un caballo no está limitado por la existencia o no de piezas contiguas: El caballo es capaz de saltar por encima de otras piezas. Se representará en pantalla por la letra C.
En la posición anterior, las siguientes jugadas serían válidas para el caballo del bando verde:
3F-4D, 3F-5E, 3F-4H, 3F-2H, 3F-1E, 3F-2D
Peón: A diferencia del
resto de las piezas, el movimiento de un peón siempre es
de avance (no puede retroceder) y depende del bando a que pertenece:
Los amarillos verticalmente hacia la fila 8, los verdes horizontalmente
hacia la columna A, los rojos verticalmente hacia la fila 1 y los negros
horizontalmente hacia la columna H.
Otra diferencia es que el movimiento es distinto dependiendo de si se captura o no: Los peones pueden moverse linealmente una casilla en la dirección de avance sólo si la casilla destino esta libre (no pueden capturar con movimiento lineal). Recíprocamente, pueden moverse diagonalmente una casilla en la dirección de avance sólo si la casilla destino esta ocupada por una pieza enemiga (es decir, sólo si capturan).
Se representarán en pantalla por la letra P.
En la posición anterior, el peón de 3B no podría moverse a ninguna casilla. En cambio las siguientes jugadas serían válidas para el peón de 3A:
3A-4B, 3A-4ALas siguientes jugadas serían válidas para el peón de 7C:
7C-8D, 7C-7DLas siguientes jugadas serían válidas para el peón de 5E:
5E-4E
Cuando se ha obtenido una jugada, ya sea procedente de un usuario o de un fichero de texto, es necesario comprobar si es válida dado el estado de la partida. Se sugiere que la validación se realice mediante las siguientes etapas:
Si la cadena es igual a Q, significa que los usuarios quieren dar por terminada la partida (independientemente de que la partida en sí haya finalizado o no). Se muestra en la línea de estado el mensaje:
Partida finalizada. Pulse Intro.
Y se termina el programa. Esta última "jugada" no se escribe en el fichero de texto.
Para que la cadena pueda ser reconocida como una jugada, debe tener una longitud de 5 caracteres, siendo el primero y el cuarto dígitos del 1 al 8 y el segundo y quinto letras de la A a la H. Cualquier cadena que no cumpla esas normas se considera incorrecta, y en la línea de estado se mostrará el mensaje:
Notacion incorrecta. Pulse Intro.
Cuando el usuario pulse la tecla intro, se borrará la línea de estado y el programa volverá a pedir que introduzca la jugada. Este comportamiento se va a seguir con el resto de situaciones erróneas que se detallan a continuación.
Si se reconoce la jugada, disponemos de las filas y columnas de la casilla de origen y la de destino. Ahora debemos comprobar que la casilla de origen no esté vacía, pues entonces no existe ninguna pieza que mover. Si la casilla está vacía se mostrará el mensaje:
Casilla vacia. Pulse Intro.
En caso contrario, se debe comprobar que la pieza de la casilla de origen pertenezca al bando a quien le corresponde jugar. Sino, se mostrará el mensaje:
No es el turno de la pieza. Pulse Intro.
Si la pieza pertenece al bando adecuado, disponemos de una pieza válida para mover, y resta comprobar que el movimiento es posible. Para ello, una primera comprobación es examinar la casilla de destino: Si contiene una pieza perteneciente a un bando aliado, entonces el movimiento no es posible puesto que no se puede "comer" a una pieza aliada. En esa situación se mostrará el mensaje:
Destino pieza aliada. Pulse Intro.
Nota: Esta situación incluye el caso (también erróneo) en que se intente "mover" una pieza a la misma casilla en que se encuentra.
Si el destino es correcto, se puede pasar a comprobar si el tipo de movimiento es posible, dada la pieza que se desea mover (es decir, si es lineal (torre), diagonal (alfil), en "L" (caballo), etc). Si la pieza no se puede mover según la trayectoria especificada por la casilla inicial y final, se mostrará el mensaje:
Movimiento no valido. Pulse Intro.
Por último, aunque el tipo de movimiento sea correcto, es posible (en el caso de la torre y del alfil) que el movimiento no sea posible debido a que una pieza se interponga en la trayectoria. En ese caso se mostrará el mensaje:
Trayectoria bloqueada. Pulse Intro.
Si la cadena pasa todos los tests anteriores, entonces se muestra el mensaje siguiente:
Jugada correcta. Pulse Intro.
Cuando el usuario pulsa intro, se realiza la jugada: la pieza se mueve a la casilla destino (desapareciendo la pieza que la ocupaba, si había alguna) y la casilla inicial queda vacía.
El turno pasa al siguiente bando (aquí se debería comprobar si como resultado de la jugada se ha capturado algún rey enemigo, en cuyo caso su bando ya no volvería a tener el turno), excepto si como consecuencia de la jugada se termina la partida: En esa situación, el programa también termina.
Si no es el caso, se redibuja el tablero para mostrar la nueva situación, y se pide la siguiente jugada.
Para facilitar las tareas de presentación de datos en la pantalla, se ha creado una unidad externa que define un conjunto de procedimientos que pueden usarse en la práctica.
La unidad se encuentra definida en el fichero pantalla.tpu y debe encontrarse en el directorio de Turbo-Pascal. Para que un programa pueda usar los procedimientos definidos en la unidad, basta que aparezca la siguiente línea tras la cabecera del programa:
uses pantalla;
Los tipos de datos y procedimientos definidos son los siguientes:
type TColor = (colAmarillo,colVerde,colRojo,colGris,colBlanco)Tipo de datos del parámetro de ColorTexto.
procedure BorraPantallaBorra la pantalla.
procedure BorraFila(Fila: integer)Borra la fila de la pantalla especificada en el parámetro. Su valor debe estar en el rango de 1 a 25.
procedure ColorTexto(Color: TColor)Establece el color con que se escribirá el texto en las subsiguientes sentencias write o writeln. El valor colBlanco representa el color normal de texto.
procedure Cursor(Fila,Columna: integer)Sitúa el cursor en una fila y columna determinada de la pantalla. Las sentencias write, writeln, read o readln escribirán o leerán texto mostrándolo a partir de esa fila y columna de la pantalla. Fila debe estar comprendido entre 1 y 25, y Columna entre 1 y 80.
procedure Rejilla(FilIni,ColIni,NumFil,NumCol: integer)Escribe una rejilla a partir de la fila FilIni y la columna ColIni de la pantalla, la cual tiene NumFil filas y NumCol columnas.
Como parte opcional se propone el tener en cuenta la jugada de enroque: En esta jugada, el rey y la torre de un mismo bando intercambian sus posiciones. Para que se pueda llevar a cabo es necesario que el rey y la torre se encuentren en su posición de inicio de la partida.
Para indicar una jugada de enroque se utilizará la misma notación que para el resto de jugadas, suponiendo la casilla origen es la ocupada por el rey y la de destino la ocupada por la torre.
Para la evaluación de la práctica, los alumnos deberán presentar:
El programa que resuelve el problema planteado, en un fichero de nombre practica.pas que cumpla las normas que se especifican en el apartado siguiente.
Una hoja donde aparezca el diagrama modular del programa realizado.
Para la evaluación de las prácticas se citará a cada subgrupo de prácticas según un horario y forma que se establecerá en su momento.
Los programas no deben presentar problemas o mensajes de error en compilación o ejecución y deberán cumplir las especificaciones del problema planteado. Un error en compilación o ejecución supone la anulación de la práctica.
Las primeras líneas del fichero practica.pas deberán especificar el nombre y grupo de los alumnos que la han realizado, ajustándose al siguiente esquema:
{ Alumno 1: Apellidos, Nombre Alumno 2: Apellidos, Nombre Grupo : A1 | A2 | A3 | B1 | B2 | C | S1 | S2 Fecha : Fecha de creación del programa }
En el programa debe existir una única zona de declaración de unidades, que debe ser exactamente:
uses pantalla;
No se permitirá la utilización de ningún tipo de datos, sentencia, estructura de control, función o procedimiento predefinido de Turbo-Pascal que no haya sido proporcionado explícitamente en la asignatura. En concreto, no se permite el uso de cualquiera de las librerías predefinidas que incluye Turbo-Pascal. En caso de duda, consultar al profesor.
Aunque las prácticas se presentan en parejas, la calificación es individual: Cada alumno debe responsabilizarse de su participación en la elaboración de las mismas.
En la evaluación de las prácticas se tendrá especialmente en cuenta la documentación interna, la calidad de la estructuración del programa en módulos y la adecuación a los contenidos teóricos vistos en la asignatura.
Se recuerda a los alumnos que es obligatorio aprobar las prácticas para poder aprobar la asignatura.
Configuración de Turbo-Pascal: Si al compilar un programa en Turbo-Pascal obtiene el mensaje "Error 14: Invalid Filename (...)", puede deberse a que los directorios de trabajo de Turbo-Pascal no estén correctamente configurados. Para solucionarlo, pulse en el siguiente enlace:
Elija guardarlo en el directorio de Turbo-Pascal (C:\Archivos de Programa\Turbo), sobreescribiendo el fichero ya existente.
Fichero pantalla.tpu: Si su ordenador no dispone del fichero pantalla.tpu o desea obtener una copia para utilizarlo en otro sitio, pulse sobre el siguiente enlace:
Recuerde que este fichero debe encontrarse en el mismo directorio donde se encuentre el programa que vaya a utilizarle.
Fichero pantalla.pas: Si tiene problemas con la instalación del fichero anterior, puede probar con el fichero fuente de la unidad. Al compilar este fichero se obtiene pantalla.tpu
Nota: Este fichero sólo se debe compilar, no es posible ejecutarlo puesto que no es un programa.