RYG: árbol de juego – algunas mejoras

Hace unas pocas entradas, en la versión 7 del proyecto, desarrollamos la rutina “aplicaJugadaGatoHijo”. El ratón tendrá una rutina equivalente un poco más adelante.

Esta rutina permite aplicar una jugada de un gato a un tablero. Pero, en vez de modificar directamente ese tablero, genera un tablero hijo. De este modo, permite ir generando el árbol de juego que hace falta para que el C64 decida su jugada.

Pues bien, entonces decíamos que esta rutina hacía:

<<

  • Saca una copia del tablero de entrada (ahora la raíz del árbol) en un nuevo tablero que será el hijo. Para esto hace falta una nueva rutina de apoyo “copiaTablero” en el fichero “Tableros.asm”.
  • Actualiza el puntero a la memoria libre (libreLo – libreHi), puesto que hemos creado un nuevo tablero en el árbol.
  • Sobre el tablero hijo, aplica el movimiento.
  • Más adelante, enlazará el tablero padre con el tablero hijo, y viceversa, aunque en esta fase del proyecto esto todavía no está implementado.
  • A modo de depuración, y de forma temporal, imprime el tablero hijo.

>>

Lo anterior admite varias mejoras, a saber:

Copia del tablero padre en el hijo:

La rutina “copiaTablero” copia el tablero origen en el destino tal cual. Ahora bien, hay campos del tablero origen, como los hijos, que no tienen sentido en el tablero de destino.

Podemos esperar a que el programa vaya “machacando” esos campos, y dándoles nuevos valores con sentido o, para no crear confusión, inicializarlos en el hijo desde el comienzo.

Por esto último se desarrolla la rutina de apoyo “copiaTableroSinHijos” (fichero “Tableros.asm”), que en el fondo es igual que “copiaTablero” pero inicializando los hijos del destino.

Incrementar nivel y turno:

Más ejemplos de campos que no tiene sentido copiar tal cual del padre al hijo son los campos “nivel” y “turno”. El nivel hay que incrementarlo en uno del padre al hijo. Y el turno hay que ir alternándolo entre ratón y gatos.

Estas modificaciones se podrían hacer en la de rutina de copia (ya sea la original “copiaTablero” o la nueva “copiaTableroSinHijos”). Pero como también hay que hacerlas cuando se aplica una jugada directamente a un tablero, sin dar lugar a un tablero hijo (por ejemplo, cuando el humano decide su jugada y hay que aplicarla al tablero actual), estos cambios se llevan a las rutinas “aplicaJugadaGato” y “aplicaJugadaRaton”.

Ahora estas dos rutinas incluyen una llamada a la nueva rutina de apoyo “incrementaNivelYTurno” (fichero “Tableros.asm”). Como esta rutina no tiene mucho misterio, no abundaremos más en ella.

Vincular padre e hijos:

Para construir un árbol de verdad no sólo hay que generar tableros. Además, hay que vincular el padre con los hijos y al revés.

Vincular un hijo con su padre es fácil porque, como dicen, “padre no hay más que uno” (en realidad, se dice de las madres que es con las que no hay duda 😉 ). Simplemente, se trata de poner la dirección del padre (de momento la raíz) en el campo “padre” de todos los hijos. Para ello se utiliza la rutina de apoyo “fijaPadre”.

Vincular a un padre con sus hijos ya es más complicado, puesto que un padre puede tener varios hijos (hasta ocho). Y algunos hijos estarán “ocupados” y otros no. Por tanto, tampoco resulta muy práctico usar la rutina “fijaHijo”, puesto que esta rutina exige saber qué número de hijo (primero, segundo, …) es el que se quiere fijar.

Por ello, resulta de utilidad desarrollar una nueva rutina “fijaHijoLibre” que, simplemente, va analizando los hijos de un padre hasta dar con el primero libre (valor $0000) y, una vez localizado su número de orden, guarda en él la información del hijo con “fijaHijo”. Ver fichero “Tableros.asm”.

Pintado de tableros con dirección:

Para depurar el árbol vamos a hacer dos cosas:

Y puesto que los padres identifican a sus hijos por sus direcciones, y al revés también, no hay nada más lógico que empezar pintando los tableros por su dirección. Por ello, se mejora la rutina “pintaTablero” (fichero “PintaTableros.asm”) con un nuevo paso “jsr pintaDireccion”.

Resultado final:

Tras todas estas mejoras, si ejecutamos la versión 8 del proyecto, el resultado es:

Primer nivel

Es decir, se van generando las siete jugadas válidas de los gatos, y cada una de ellas se aplica a un tablero hijo, que queda identificado mediante su dirección (ej. $197c), y que queda enlazado con su tablero padre ($1714) que, de momento, y al tener sólo un nivel, es la raíz del árbol.

La ejecución en VICE se puede ir parando si se va pinchando con el ratón sobre la barra de menú de VICE, y se pueden ir comprobando todos los tableros hijo.

También es posible usar el depurador de CBM prg Studio, ejecutar el programa, irse con el visor de memoria a la zona de memoria del entorno de la raíz ($1714), y comprobar que están los tableros:

Primer nivel 2

Si se hace esto, hay que tener cuidado con las impresiones por pantalla porque el depurador de CBM prg Studio no incluye por defecto en su mapa de memoria las rutinas del Kernal como “chrout”. Por ejemplo, se pueden comentar o saltar.


Código del proyecto: RYG08

Un comentario en “RYG: árbol de juego – algunas mejoras”

  1. Hola.

    En teoría hay una forma de cargar la ROM del C64 en el depurador de CBM prg Studio, y de este modo usar rutinas del Kernal como “chrout”.

    Se supone que es así (consultado directamente al soporte de CBM prg Studio):

    1- Desde VICE: Con VICE recién arrancado, hacer un snapshot con la opción Snapshot > Save snapshot imagen… Se generará un archivo *.vsf de unos 70 KBytes.

    2- Desde CBM prg Studio: Ir a la opción Tools > Options > Debugger > External files y activar “Load external files when debugger starts” y seleccionar el archivo *.vsf desde “Manage”. No hace falta indicar dirección de carga.

    Al hacer lo anterior, abrir un proyecto (ej. RYG08), y ejecutar el debugger, se debería cargar la ROM del C64 exportada desde VICE. Sin embargo, si con el visor de memoria vamos a la entrada de la rutina “chrout” ($ffd2) no vemos contenido con sentido.

    Sin embargo, si en 2- usamos “Use overlay file” y seleccionamos el fichero *.vsf, tras ir al debugger y el visor de memoria, en $ffd2 ya vemos contenido con sentido (la jump table del Kernal).

    No obstante, ni siquiera así he conseguir depurar programas que llaman a rutinas del Kernal. Una pena… Siempre tengo que comentar las llamadas o evitarlas al depurar paso a paso.

    Si alguien conoce la solución, agradezco mucho la información 🙂 .

    Saludos.

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s