Generación de jugadas II

Ahora que ya sabemos cómo generar los movimientos (con las direcciones de movimiento, las tablas de movimientos de ratón y gatos, y la tabla “move_list”), vamos a ello:

Lo primero es definir un nuevo fichero “Gen.asm”, que va a contener las rutinas relativas a la generación de movimientos:

  • Rutina “gen” para generar los movimientos de ratón o gatos, según de quién sea el turno (“side”).
  • Rutina “genMouse” para generar un movimiento del ratón a partir de una posición de origen y una dirección de movimiento.
  • Rutina “genCat” para generar un movimiento de un gato a partir de una posición de origen y una dirección de movimiento.
  • Rutina “addMove” para añadir un movimiento a “move_list”.

Además de lo anterior, vamos a definir una nueva rutina “displayMoves” en el fichero “Display.asm” y un nuevo programa principal.

Rutina “gen”:

La rutina “gen” tiene esta pinta:

Lo primero que hace tiene un poco de truco. Si vamos a generar los movimientos a profundidad “ply”, los movimientos de esa profundidad se almacenarán empezando en first_move(ply) y terminando en first_move(ply+1). En realidad, first_move(ply+1) ya es el primer movimiento de la profundidad siguiente. Por tanto, lo primero que hace es la asignación first_move(ply+1) := first_move(ply), es decir, viene a decir que la lista de movimientos del nivel “ply” nace vacía. A partir de ahí irá incrementando el final de la lista first_move(ply+1) con cada nuevo movimiento que genere.

A partir de ahí:

  • Recorre el tablero “board” con el índice X.
  • Analiza quién mueve (“side”), si ratón o gatos.
  • Si mueve el ratón y la pieza en el índice X es un ratón, llama a “genMouse” para las cuatro direcciones.
  • Si mueven los gatos y la pieza en el índice X es un gato, llama a “genCat” para las dos direcciones permitidas.
  • Continúa hasta terminar el tablero.

Rutinas “genMouse” y “genCat”:

Por su parte, las rutinas “genMouse” y “genCat” son muy parecidas, por lo que sólo analizaremos la primera:

Esta rutina hace lo siguiente:

  • Partiendo de la casilla de origen, la multiplica por cuatro (asl + asl). Recordemos que la tabla de movimientos del ratón tiene cuatro movimientos por casilla de origen, aunque algunos pueden ser inválidos.
  • Tras multiplicar por cuatro, le suma la dirección.
  • Usando ese valor (origen * 4 + dirección) como índice Y, accede a la tabla de movimientos “mouse_moves” y obtiene la casilla de destino.
  • Si la casilla de destino es -1 = $ff, la dirección de movimiento no es válida para esta casilla origen y termina.
  • Si la casilla de destino no está vacía (PIECE_EMPTY), la dirección de movimiento tampoco es válida y termina.
  • En el resto de casos, llama a “addMove” pasando la casilla origen y la casilla destino.

Rutina “addMove”:

Por último, la rutina “addMove” hace lo siguiente tanto para los movimientos del ratón como de los gatos:

Es decir:

  • Determina el primer movimiento libre para el nivel “ply”, que es el apuntado por first_move(ply+1).
  • En esa posición libre almacena el movimiento (origen, destino).
  • Incrementa first_move(ply+1), es decir, incrementa el final de la lista de movimientos para el nivel “ply”.

Rutina “displayMoves”:

Tanto para probar la generación de movimientos como para más adelante, cuando el programa esté más avanzado, nos interesa imprimir por pantalla los movimientos generados. Esto lo hacemos con la rutina “displayMoves” de “Display.asm”:

Se puede hacer una rutina que imprima los movimientos generados para una profundidad dada, o que imprima todos los movimientos desde la profundidad 0 hasta la profundidad “ply”. Pero en general, es suficiente con conocer sólo los movimientos de la siguiente jugada, es decir, los movimientos almacenados en “move_list” desde first_move(0) hasta first_move(1).

Y eso es lo que hace “displayMoves”:

  • Toma como primer movimiento el almacenado en first_move(0).
  • Toma como último movimiento el almacenado en first_move(1). En realidad, este movimiento ya no se imprimirá.
  • Recorre esos movimientos, es decir, va leyendo origen (“move_list_start”) y destino (“move_list_dest”), y los imprime con la rutina “algebraic”.

La rutina “algebraic”, por su parte, es una rutina sencilla que convierte una posición en su notación algebraica. Por ejemplo, la casilla 0 se imprime como A1, y la casilla 63 se imprime como H8. Está definida en “Init.asm”.

Nuevo programa principal:

Por último, desarrollamos un nuevo programa principal que nos permite probar todo lo desarrollado hasta el momento. Queda así:

Es decir:

  • Inicializa el tablero y lo pinta.
  • Configura que mueve el ratón, genera sus movimientos, y los imprime.
  • Configura que mueven los gatos, genera sus movimientos, y los imprime.

Y el resultado es como sigue:

Por tanto, parece que ya sabemos mover…


Código del proyecto: RYG3-02

Deja una respuesta

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. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s