RYG: árbol de juego – memoria #Programación retro del Commodore 64

Hasta ahora sólo teníamos el "tablero actual", es decir, la estructura de datos que lleva control de en qué situación (en qué tablero) se encuentra el juego. Esto lo hacíamos así en el fichero "Arbol.asm":

Tablero actual

Puede parecer un poco tonto definir una etiqueta "tableroActual" y no hacer nada más, pero no lo es. Usando tableroActual (parte "hi") se puede definir un puntero a esa zona de la memoria y, mediante rutinas como "inicializaTablero" se puede configurar ahí un tablero (85 bytes) en su situación inicial:

Rutina incializaTableroActual

A partir de ese momento, se puede trabajar con ese "tablero actual", generando los movimientos del ratón, preguntando al usuario cuál desea, aplicando ese movimiento al tablero, generando los movimientos para los gatos, etc.

Aquí podemos ver con el debugger el contenido de la memoria a partir de la etiqueta "tableroActual", que en la versión 6 del proyecto es la dirección $1346:

Tablero actual debugger

Mirando con atención se pueden identificar el nivel ($00), el turno ($01), el valor ($00), el padre ($0000), los hijos ($0000, …, $0000) y, finalmente, el tablero propiamente dicho, donde están los gatos ($ff) y el ratón ($01).

Y todo ello con el objetivo de llevar el control de la situación actual de la partida.

Pero ahora tenemos otro objetivo: generar un árbol de juego. Y ese árbol de juego va a consistir en una serie de tableros (bloques de 85 bytes) ubicados uno a continuación del otro, y enlazados entre sí usando los punteros de padre e hijos. Esquemáticamente sería así:

Tableros en memoria

Por tanto, necesitamos varias cosas:

  • Reservar 85 bytes para el tablero actual, asegurándonos de que no son pisados por nadie.
  • Una zona de memoria en la que meter tableros (bloques de 85 bytes) enlazados entre sí mediante punteros y conformando un árbol.
  • La zona de memoria del árbol debe poder crecer según se vayan generando más tableros. Y no debe pisar zonas del sistema como el intérprete de BASIC (a partir de $a000).
  • Y, una vez tomada una decisión de juego por el C64, la zona de memoria del árbol debe poder reutilizarse para las jugadas siguientes.

Esto lo logramos con un nuevo fichero "Arbol.asm" así:

Tablero actual y árbol

Es decir:

  • Reservamos 85 bytes de forma expresa para el tablero actual. Antes no había una reserva expresa; estaba implícita.
  • Reservamos dos bytes para un puntero libreLo – libreHi, que nos va a indicar cuál es el primer byte de memoria que está libre para almacenar nuevos tableros que se vayan generando.
  • Tras el puntero libreLo – LibreHi viene la raíz del árbol, es decir, el primer tablero del árbol de juego. La raíz la copiaremos desde el tablero actual al comienzo de generar el árbol.

Por tanto, la memoria irá evolucionando así:

Tableros en memoria 2

Es decir:

  • Primero el código del juego, que empieza en $801.
  • Luego el tablero actual con la situación de la partida.
  • Luego el puntero a la memoria libre, que se irá actualizando según se generan tableros.
  • Luego la raíz del árbol de juego, que se copiará desde el tablero actual al empezar a conformar el árbol.
  • Luego los tableros hijo, los tableros nieto, etc., así hasta el nivel de profundidad establecido.
  • Por último, la memoria libre, que irá decreciendo según se van generando tableros, y volverá a crecer cuando el C64 tome una decisión de juego.

Por esta estructura de tableros se puede navegar de padres a hijos, siguiendo cualquiera de los ocho punteros a los hijos que tiene cada tablero. También se puede navegar de hijos a padres, siguiendo el puntero al padre que tiene cada tablero. De hecho, tendremos que navegar por ella para aplicar el procedimiento minimax.


Código del proyecto: RYG07


Editar

Josepzin

No hay comentarios:

Publicar un comentario