Voy a colocar en los próximos días un nuevo juego. En
este caso el famoso Tic Tac Toe, Tres en línea, Tres en raya o Juego del gato.
Este es ya un juego mucho
más complejo por las cantidad de decisiones que puede tener y en él, practicaré
el recorrido de listas y tablas. Sobre todo, vamos a implementar una forma de
leer e interpretar un árbol de decisiones.
Al tiempo, usaré la función getmousex, getmousey, para leer la posición del ratón, y
las de activación y desactivación del cursor cursor
on y cursor off.
Aquí veréis una forma de
tomar decisiones a través de un árbol de decisión o árbol de juego. El árbol de
decisión ha sido sacado a partir de la tabla de posibilidades.
Como se recorre, es simple,
basta leer el programa. Puesto que este es muy simple y la secuencia es muy
corta, no será complicado sacarlo del programa. Hay que dejar algo para
analizar....
Esta es la pantalla
que queremos conseguir. En ella crearé una matriz para el tablero e iremos
pulsando con el ratón cada casilla, colocando una O en su posición. El
ordenador entonces analizará la jugada y colocará una X en la posición
correspondiente.
El ordenador siempre
empieza. Por desgracia solo podrás hacer tablas o perder.
Si gana
consigues hacer tablas el ordenador te muestreará un mensaje, como el de
abajo, y te invita a repetir el juego.
Comenzaré con la estructura del programa.
Para realizar el programa vemos que necesitaremos.
tic_tac_toe Esta rutina, que será la
principal, y deberá hacer en orden:
-
Dibujar el tablero
-
Tomar la posición indicada mediante el ratón por el oponente
-
Pensar una respuesta
-
Refrescar el tablero
Dibujar el tablero
Como se trata de un tablero fijo, que no varía, lo haré en las
primeras líneas del programa. No, imprimiré el tablero más que una vez, y por
lo tanto no vale la pena crear subrutina.
Tomar la posición indicada mediante el ratón por el oponente
Para ello leeré la posición del ratón y espere el flanco
positivo de pulsación. Si se pulsa corregirá la posición a coordenadas de
texto, ya que el ratón las da en coordenadas de pixel. Devolverá dicha posición
xy. Este código desarrollado para este juego, resulta muy útil en el futuro, y
por lo tanto, más adelante en el blog mostraré como implementarla en nuestra
librería para futuros programas. La programación estructurada trata de crear
elementos que sirvan como herramientas futuras y ser capaz de implementarlos
para un uso futuro. Un buen programador cuanto más programa, más poderoso es,
pues más herramientas tiene. No se debe usar copy-paste de trozos de programa.
Se debe crear herramientas para el futuro.
Pensar una respuesta
Esta el la parte más bonita del programa. En una rutina
aparte. Realizada para poder analizar esta secuencia por separado, vamos a una
rama del árbol y tomar la decisión correcta, dejando el sistema preparado para
el siguiente nivel de juego. Conviene formar subrutinas, cuando la función
puede escindirse del código madre. Es decir, cuando podemos realizar un programa
que funcione sin contar con esta parte del programa, de forma que podamos
realizar un simulación del resto del programa. Esto nos permitirá ir probando
el programa principal sin estas partes y activando posteriormente cada
subrutina, de manera que podamos ir corrigiendo defectos de forma sencilla en
el debuger.
Refrescar el tablero
Esta es una función simple como la de imprimir tablero, que
simplemente representa el estado del juego. En este caso es subrutina, porque
se va a usar muchas veces a lo largo del código. Haré una función que me sirva
por separado para imprimir el estado del oponente y de la máquina, y que pueda
usar cualquier símbolo como marca. Así me ahorro código particularizado para
oponente y máquina dado que las casillas donde imprimir son comunes.
Vamos a comenzar con lo más valioso. El MAPA DE JUEGO
MAPA DE JUEGO
Este mapa nos representa las acciones a realizar por la
máquina según el estado en que se encuentre el oponente, y nos indica si
debemos toma nueva rama de decisión o si el juego ha terminado.
En el árbol de decisión de este juego existen hasta 4
niveles. Si llegamos al nivel 4 el resultado es tablas
Al final de cada lista hemos colocado un dd 0,
como marca de fin de lista. En realidad no se necesita, pero sirve, durante la
depuración, para detener el programa en caso de no encontrar la jugada dentro
de la lista. Por ejemplo, si hemos escrito mal la secuencia de números del
árbol de decisión.(c) Jose Angel Moneo Fdez
;Mapa de juego TICTACTOC
nivel1 db 80h,20h
dw offset n2_20h
db 40h,20h
dw offset n2_20h
db 20h,80h
dw offset n2_80h
db 10h,80h
dw offset n2_80h
db 8,10h
dw offset n2_10h
db 4,80h
dw offset n2_80h
db 2,40h
dw offset n2_40h
db 1,40h
dw offset n2_40h
n2_10h db 9,40h
dw offset n3_40h
db 88h,1,0,0
db 48h,1,0,0
db 28h,1,0,0
db 0ch,1,0,0
db 0ah,1,0,0
dd 0
n2_20h db 84h,10h
dw offset n3_10h_1
db 44h,10h
dw offset n3_10h_2
db 0c0h,4,0,0
db 90h,4,0,0
db 88h,4,0,0
db 82h,4,0,0
db 81h,4,0,0
db 50h,4,0,0
db 48h,4,0,0
db 42h,4,0,0
db 41h,4,0,0
dd 0
n2_40h db 82h,10h
dw offset n3_10h_3
db 81h,4
dw offset n3_4h
db 22h,80h,0,0
db 21h,80h,0,0
db 12h,80h,0,0
db 11h,80h,0,0
db 0ah,80h,0,0
db 9,80h,0,0
db 6,80h,0,0
db 5,80h,0,0
db 3,80h,0,0
dd 0
;revisado
n2_80h db 60h,10h
dw offset n3_10h_3
db 44h,10h
dw offset n3_10h_3
db 50h,4
dw offset n3_4h
db 30h,40h,0,0
db 28h,40h,0,0
db 24h,40h,0,0
db 22h,40h,0,0
db 21h,40h,0,0
db 0ch,40h,0,0
db 18h,40h,0,0
db 14h,40h,0,0
db 12h,40h,0,0
db 11h,40h,0,0
db 6,40h,0,0
db 5,40h,0,0
dd 0
n3_4h db 70h,8
dw offset n4_8h
db 58h,20h,0,0
db 52h,20h,0,0
db 51h,20h,0,0
db 0a1h,10h,0,0
db 91h,20h,0,0
db 89h,20h,0,0
db 83h,20h,0,0
n3_10h_1 db 0c4h,8,0,0
db 85h,8,0,0
db 8ch,1,0,0
db 86h,8,0,0
dd 0
n3_10h_2 db 0c4h,8,0,0
db 4ch,1,0,0
db 86h,8,0,0
db 85,8,0,0
dd 0
n3_10h_3 db 0c4h,2,0,0
db 0c2h,1,0,0
db 0c8h,2,0,0
db 0c1h,2,0,0
db 4ch,2,0,0
db 86h,1,0,0
db 85h,2,0,0
db 8ah,4,0,0
db 83h,4,0,0
db 0a2h,4,0,0
db 61h,2,0,0
db 62h,1,0,0
db 64h,2,0,0
db 68h,2,0,0
db 46h,1,0,0
db 45h,2,0,0
dd 0
n3_40h db 89h,4,0,0
db 29h,80h,0,0
db 0dh,80h,0,0
db 0bh,80h,0,0
dd 0
n4_8h db 72h,1,1,0
db 71h,2,1,0
dd 0
VARIABLES DE JUEGO
Vamos a necesitar una serie de variables para el juego. Básicamente:
Un puntero a la lista del árbol.
Almacén de las jugadas de la máquina.
Almacén de las jugadas del oponente.
;VARIABLES TICTACTOC
(c) Jose Angel Moneo Fdez
nivel_act dw 0 ; almacen de puntero de nivel actual
maquina db 0 ; situación de la maquina
oponente db 0 ; situación del oponente
VARIABLES CONTROL DEL RATÓN
Para control del ratón usaremos estas varialbes, donde almacenamos la posición y una bandera de estado para manejar el flanco.
(c) Jose Angel Moneo Fdez
;VARIABLES TICTACTOC
estado db 0; estado partida
posx db 0 ; posicion pulsación del raton
posy db 0
raton dw 0
VARIABLES DE PANTALLA
Estas son las variables necesarias para presentar el juego y el tablero. El tablero está creado mediante los valores ASCII, para poder usar el Notepad como editor.
(c) Jose Angel Moneo Fdez
;VARIABLES TICTACTOC
titulo db "TRES EN LINEA",0
ayuda db "PULSA CON EL RATON EN LA POSICION DESEADA",0
m_gana db "Lo siento has perdido.",0
m_tablas db "Esta partida son tablas",0
m_error db " Ha surgido un error",0
tablero1 db 201,205,203,205,203,205,187,0 ; "╔═╦═╦═╗"
Tablero2 db 186,32,186,32,186,32,186,0 ; "║ ║ ║ ║"
Tablero3 db 204,205,206,205,206,205,185,0 ; "╠═╬═╬═╣"
Tablero4 db 200,205,202,205,202,205,188,0 ; "╚═╩═╩═╝
NW_intento db "Quieres intentarlo de nuevo? S/N",0
En el proximo blog pondré la rutina de como pensar la respuesta.
No hay comentarios:
Publicar un comentario
Si tienes algún comentario, duda o sugerencia, o si quieres aportar algún código creado a partir de las librerías expuestas aquí, por favor, indícamelo.