Vistas de página en total

martes, 30 de julio de 2013

TIC_TAC_TOE (1/5)

   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.