Función de evaluación

La función de evaluación es una rutina que recibe un tablero (tablero “board”) y devuelve un número que nos indica cómo de bueno o malo es ese tablero para ratón y gatos. Se aplica sobre las hojas del árbol de juego, y luego esas evaluaciones se hacen subir por el árbol aplicando minimax, es decir, calculando el máximo o el mínimo en función del bando que mueve:

Las funciones de evaluación pueden llegar a ser muy sofisticadas en juegos complejos como el ajedrez. Suelen tener en cuenta muchos criterios, que se suelen clasificar en:

  • Posicionales: Los que tienen que ver con la posición de las piezas.
  • Materiales: Los que tienen que ver con el número y valor de las piezas.

En el caso del ratón y el gato, como no hay capturas, las piezas son siempre las mismas y, por tanto, no hay criterios materiales. Sólo hay criterios posicionales.

Tablas de evaluación:

La función de evaluación se apoya en unas tablas llamadas “tablas de evaluación”. Estas tablas están definidas en el fichero “Init.asm”, aunque igualmente se podrían haber definido en el nuevo fichero “Eval.asm”, que tiene que ver con la evaluación.

Hay una tabla por cada tipo de pieza y, puesto que en su momento decidimos que los gatos eran cuatro piezas distintas (“PIECE_CAT1”, …, “PIECE_CAT4”), con el objeto de poder distinguirlos, eso da lugar a cinco tablas:

La tabla de evaluación “mouse_scores” nos dice cuánto vale el ratón en función de su posición (criterio posicional). Si el ratón está en la fila cero vale cero, si está en la fila uno vale uno, y así sucesivamente. Es decir, vale tanto más cuanto más cerca esté de la última fila, porque el objetivo del ratón es llegar a la última fila.

En el caso de un gato, la tabla de evaluación “cat*_scores” nos dice que vale 28 cuando está en la fila siete (fila inicial de los gatos), 27 cuando está en la fila seis, 25 cuando está en la fila cinco, y así sucesivamente. Aquí hay que observar dos cuestiones importantes:

  • De la fila siete a la seis el gato pierde un punto (28-27=1), pero de la seis a la cinco pierde dos (27-25=2), de la cinco a la cuatro pierde tres (25-22=3), y así sucesivamente. Cuanto más avanza más valor pierde.
  • Aunque el gato 1, por ejemplo, puede moverse en teoría por todo el tablero (respetando sus reglas de movimiento, claro), en la práctica, por cómo hemos diseñado su tabla de evaluación, el gato 1 va a intentar no salirse de las columnas 1 y 0. Si se saliera de ahí, lo cual está permitido por las reglas de movimiento, perdería todo su valor.

Estos dos “trucos” tienen como efecto combinado que, antes que mover un gato varias veces seguidas y romper la formación de gatos, el C64 preferirá mover los gatos en formación, es decir manteniendo la fila, y de este modo intentará impedir que el ratón los rebase, lo cual le daría la victoria.

En definitiva, las tablas de evaluación están diseñadas para que el ratón y los gatos busquen sus respectivos objetivos en el juego, que son llegar a la última fila en el caso del ratón, y acorralar al ratón en el caso de los gatos.

Rutina “eval”:

Una vez vistas las tablas de evaluación, lo que hace la función de evaluación, que es la rutina “eval” del nuevo fichero “Eval.asm”, es esto:

Es decir:

  • Define tres valores, “evMouse” con la valoración del tablero para el ratón, “evCats” con la valoración para los gatos, y “ev” que es la valoración global.
  • Inicializa los tres valores a cero.
  • Recorre el tablero “board” con el índice X.
  • Si una posición X contiene el ratón (“#PIECE_MOUSE”), usa la tabla de evaluación del ratón (“mouse_scores”) para determinar el valor de “evMouse”.
  • Si una posición X contiene un gato (“#PIECE_CAT*”), usa la tabla de evaluación de ese gato (“cat*_scores”) para determinar el valor de “evCats”. Se va sumando al valor anterior.
  • Si la posición está vacía, lógicamente se pasa a la siguiente.

Por último, queda hacer algunos cálculos:

Como se puede ver, en la parte final de “eval”, a partir de la etiqueta “evEnd”, se aplica la siguiente fórmula:

ev = $80 + evMouse – evCats

Es decir, la evaluación global “ev” es igual a $80 = 128, más la evaluación del ratón, menos la evaluación de los gatos.

Y como la evaluación máxima de los gatos es 28 x 4 = 112, eso da lugar a una evaluación mínima de 128 + 0 – 112 = 16 = $10. Esta evaluación es la que corresponde al tablero inicial. A partir de ahí, los gatos irán bajando y el ratón, en general, irá subiendo, lo que en teoría podría dar lugar a una evaluación máxima de 128 + 7 – 0 = 135 = $87.

Es decir, la evaluación global es un número que oscila entre $10 = 16 y $87 = 135. De hecho, el objetivo de sumar $80 = 128 es manejar y comparar siempre números positivos, lo cual es más fácil que manejar números positivos y negativos.

Nuevo programa principal:

Ya sólo nos queda probar todo esto para lo que, como siempre, hacemos un nuevo programa principal:

Este nuevo programa principal:

  • Inicializa el tablero y la partida con “initBoard”.
  • Inicializa las tablas aleatorias para el hash y el lock con “randomize”.
  • Inicializa el proceso de búsqueda con “newPosition”, aunque de momento todavía no vamos a buscar la mejor jugada, aunque nos vamos acercando.
  • Muestra el tablero con “displayBoard”, que ha sido mejorada para mostrar la evaluación asociada a un tablero.
  • Con “makeMove”, realiza el movimiento 4 => 13, es decir, el movimiento E1 => F2, y vuelve a mostrar el tablero.
  • Con “makeMove”, realiza el movimiento 57 => 48, es decir, el movimiento B8 => A7, y vuelve a mostrar el tablero.

Si lo ejecutamos observamos estos tres tableros:

Es decir, la evaluación empieza en $10, con el movimiento del ratón pasa a $11, y con el movimiento del gato pasa a $12.

Como podemos ver, la evaluación del tablero depende de las posiciones de las piezas. Y como el C64 elegirá como óptimos los movimientos que maximizan o minimizan la evaluación, en función del turno, en el fondo lo que tenemos es que las tablas de evaluación (“*_scores”) influyen en los movimientos que se eligen y realizan.


Código del proyecto: RYG3-06

Deja un comentario