Dedicado a mis proyectos en Gambas ,un lenguaje de programación parecido al Visual Basic + Java pero ampliamente mejorado y...¡¡para gnu/linux!!.La potencia del gnu/linux sumada a la facilidad del Basic



Consultas, Desarrollo de programas y petición de presupuestos:



Mostrando entradas con la etiqueta negamax. Mostrar todas las entradas
Mostrando entradas con la etiqueta negamax. Mostrar todas las entradas

domingo, 19 de octubre de 2014

Juego: Tres en linea, ejemplo de algoritmo con negamax con poda

Juego:

Tres en linea, ejemplo de algoritmo con negamax con poda



Os dejo aquí un nuevo juego, para los más pequeños. Se trata de una variante del 3 en raya, llamada 3 en linea. El juego va por turnos y tiene 2 fases, la primera colocar las 3 piezas (gatitos o perritos), e intentar hacer 3 en raya. Luego, si no hemos conseguido las 3 en raya, movemos las fichas, hasta logarlo o hacer tablas.

Podemos jugar contra humano-humano, o humano-ordenador, y tenemos 3 tableros disponibles con variación de los caminos en cada tablero.

Descarga del código fuente e instalador .deb: enlace de drive google

En próximas entradas iré explicando el código del programa.

Saludos

viernes, 4 de octubre de 2013

Juego Conecta 4: Paso a Paso (5) El módulo de Inteligencia Artificial. Algoritmo Negamax

Juego Conecta 4:

 Paso a Paso (5) 

El módulo de Inteligencia Artificial. Algoritmo Negamax



La inteligencia artificial de este programa consiste en evaluar las posiciones que se producen con las distintas jugadas (tantos las de un jugador como las del otro,  ordenandolas por niveles) y elegir la que más nos beneficie. Basicamente, consiste, en ver cuales jugadas puedo hacer, evaluar las que podria hacer el contrario, volver a evaluar mi respuesta a la del contrario, y asi hasta cierto nivel o profundad.

Por lo tanto vemos que hay dos partes bien diferenciada:
-La parte de evaluar el "arbol" de las distintas jugadas y sus respuestas, y elegir entre ellas la que más nos beneficie.
-La evaluación de la jugada, osea del tablero que queda cuando ejecuto esa jugada.
Código del negamax


Cosas que hace este código por orden:
1) Obtiene el numero de jugadas posibles del tablero que recibe
2) Crea un tablero auxiliar que es copia del que recibe
3) Entra en un bucle que se repite tantas veces como numero de jugadas posibles se puedan hacer
4) Hace una jugada (inserta una ficha en el tablero auxiliar)
5) Comprueba si es GamerOver o la profundidad del análisis es 0,
5.1) Si es así, evalúa la jugada y retorna su valor.
5.2) Sino:
5.2.1) vuelve a llamar a la funcion negamax, pasandole el nuevo tablero, el jugador contrario (lo multiplica por -1), una profundidad menor, y dos valores -beta, y -alfa_local, que sirven para "podar el arbol de opciones"
5.2.2) Evalúa la puntuación que se obtiene
5.2.2.1) Si es mayor su puntuación a la máxima puntuación, la jugada es elegida como posible mejor jugada
5.2.2.2) Sino, si es igual, de elige aleatoriamente a una de ellas. Esto se hace para que el juego sea un poco aleatorio, al no elegir siempre la misma jugada que tenga la misma puntuación que otras.
5.2.3) Hace una poda alfa-beta, para dejar de revisar jugadas, si superan el valor de beta.

Código del EvaluaJugadaMov

Evaluar una posición de las fichas del  tablero producido por una jugada, consiste en averiguar cuantas veces se han formado grupos de 2, 3 o 4 fichas del mismo color en horizontal, vertical o diagonal (esto se hace usando el método comprueba_linea del objeto tablero).
En principio el valor viene dado por la formula:
 valor_jugada = (4 * n2 + 9 * n3 + 100000 * n4)
Siendo:
n2: numero de grupo de 2 fichas del mismo color en horizonta, vertical o diagonal
n3: numero de grupo de 2 fichas del mismo color en horizonta, vertical o diagonal
n4: numero de grupo de 2 fichas del mismo color en horizonta, vertical o diagonal

Se ha simplificado un poco el algoritmo de cálculo, ya que si se forma un grupo de 4 fichas,  es un tablero ganador, y por lo tanto, no hace falta calcular los otros grupos (n2 ni n3).

En la próxima entradas explicaremos como se ha realizado los formularios (el modo gráfico)





martes, 1 de octubre de 2013

Juego Conecta4: Paso a Paso (1) Estructura del Proyecto

Juego Conecta4: Paso a Paso (1)

Estructura del Proyecto


Como dije en la primera entrada de Conecta4 ( enlace ), vamos a desmembrar el código fuente para estudiarlo y explicarlo como funciona.

En primer lugar vamos a ver la estructura del código fuente del proyecto, en la siguiente imagen:
Como veis tenemos:
A) Clases:
ClassJugador (clase "padre") y ClassJugdorHumano y ClassJugadorOrdenador "que heredan de de la clase ClassJugador"
ClassJugador: Es la clase "padre" de las que van a heredar la clase ClassJugadorHumano y ClassJugadorOrdenador.
Estas últimas clases, tiene el método "juega" que se comparta de manera muy diferente si pertenece a una u otra clase. En el caso de ClassJugadorHumano, el método "juega" va a esperar que se el jugador humano pulse sobre una columna del tablero, para realizar el movimiento (si es posible) en el tablero.
Sin embargo en la clase ClassJugadorOrdenador, el método "juega", usa la función negamax del módulo "ia", para elegir la jugada a realizar.

ClassPartida:
En la versión 0.0.3, es una simple clase que se usa para iniciar una nueva partida, usando el formulario FormInicio. En principio preveo en próximas versiones, añadirle la opción de guardar y abrir partidas.

ClassTablero:
Es la clase más importante, ya que contiene:
- Propiedades:
La propiedad "casillas": Posee la información de la situación de las fichas de los jugadores (representados por 1,-1 ó 0 si esta vacía) en el tablero,  es un array integer de 2 dimensiones (7x7).
- Métodos:
New: inicia un tablero y es aprovechado para iniciar las casillas con valor "0"
Muestra: devuelve una copia del array casillas (información de fichas y jugador al que perteneces), para que sea usado en las subrutinas de dibujar el tablero. En versiones anteriores, mostraba en la consola el tablero.
Copia: devuelve una copia del array casillas, que será usado para crear tableros auxiliares.
InsertaFicha: es la función que se usa para modificar el tablero cuando se inserta una ficha. En el caso que devuelva el valor "False", se debe a que no se puede introducir una ficha en la columna que se ha indicado, y si devuelve "True", se ha colocado  correctamente y sin problemas la ficha en el tablero.
GameOver(): Comprueba si se ha producido tablas o ha ganado alguien (con la función ganador).
ganador: Comprueba si un jugador tiene 4 fichas juntas (en fila,columna o diagonal) en el tablero
comprueba_linea: Funcione que devuelve el numero de lineas de fichas que hay en el tablero de un jugador
comprueba_linea_Cuatro(): comprueba si se han formado conjunto de 4 fichas en Filas/Columnas/o Diagonal.
comparaCuaternaElemento(): Compara elementos de una array con otro, para ver si son iguales todos o no.
jugadasPosibles(): devuelve una array de las posibles jugadas que se pueden realizar. Esto significa que devuelve las columnas que no están llenas y por lo tanto podemos insertar una ficha.


B) Formularios:
FormInicio:
Simple formulario que nos muestras los iconos de gambas y conecta4, con un botón que es el que inicia una partida.

FormJugadores:
Este formulario es usado para dar a elegir el tipo de jugadores Humano o Ordenador, y si es Ordenador, indicar el nivel de inteligencia del jugador. Devuelve estos datos elegidos por el usuario, que serán usados para pasárselos al Formulario FmainTablero, para configurar asi el nuevo juego.


FmainTablero: Es el formulario donde mostraremos los datos de la partida: el tablero propiamente dicho, las fichas, el listado de jugadas que se ha realizado e información sobre la clase de jugadores (humano/ordenador / nivel). Además es donde el jugador humano interactua con el dibujo del tablero para indicar en que columna coloca su ficha.




C) Módulos
ia:
Contiene las funciones relacionadas con la Inteligencia Artificial del programa.
- La función negamax es la encargada de analizar el árbol de movimientos y quedarse con la mejor jugada (incluso hace las podas de jugadas no necesarias de calcular), y se usa de un modo "recursivo" (se llama a si misma).
El árbol de movimiento, se genera a partir del tablero inicial, donde se ven que movimientos son posibles, se ejecutan estos movimientos en tableros auxiliares (copias del original) y se vuelve a usar la función negamax de modo recursivo para analizar el nuevo tablero. Este proceso se repite hasta llegar al final de la profundidad a analizar del árbol o se encuentre un tablero donde se termine la partida. Al final devuelve la mejor jugada que puede realizar el jugador.
- La función EvaluaJugadaMov es la encargada de hacer la valoración un tablero según el jugador que se le pase, valorando el numero de veces que se produce en el tablero conjuntos de 2 fichas, 3 fichas o 4 fichas, que estén en el tablero de forma diagonal, horizontal o vertical.

main: 
Es el módulo de inicio del programa (indicado por el triangulo negro, junto a su nombre). Crea una instancia de la clase "ClassPartida", y usa su método ".inicio", con lo cual hace arrancar una partida. Además contiene la variable "maxinteger", que va a ser usada como variable global, (tendrán acceso todos los módulos y clases del programa).

Utilidades: 
Las funciones que incluye este formulario son de tipo "publicas" y de uso común  (osea muy usadas en otras aplicaciones). Pero realmente no se ha usado ninguna de ellas en esta aplicación.

E) Datos:
En esta carpeta tenemos alojados las dos imagenes que usamos en la aplicación, el icono de gambas3 y la imagen del juego conecta4


Nota:
¿seria necesario una clase Jugada o estructura que definiera la Jugada a realizar?
En concreto en este juego de conecta 4, las jugadas simplemente representa la columnas donde podemos insertar una ficha. Básicamente se trata de una información de una dimensión (valor de las columnas). Por lo tanto, una jugada es un número y se puede usar un array integer para contener la lista de jugadas posibles.

Sin embargo en otros juegos más complicados (por ejemplo las damas), las jugadas van a contener más información (coordenada donde empieza y coordenada donde termina, incluso coordenadas intermedias para indicar "saltos"). En este caso si sería necesario usar variables más complicadas (por ejemplo arrays de Variant, o estructuras o directamente clases ), para que pudieran manejar la información del movimiento de la ficha o pieza.

En la próxima entrada, entraremos más profundamente en el código.

Saludos

lunes, 30 de septiembre de 2013

Juego Conecta4: Inteligencia Artificial usando algoritmo negamax


Juego Conecta4:

 Inteligencia Artificial 

usando

 algoritmo NEGAMAX




Este programa esta basado en el post de "La máquina imbencible 2" publicado en el blog http://www.divertimentosinformaticos.com/ cuyo autor es Alberto García Serrano, el cual describe el algoritmo negamax y como usarlo en  el programa para jugar al conecta 4, usando el lenguaje Python.

Yo lo que he hecho  es:
- traducirlo a Gambas3
- darle un aspecto visual (ya que en Python funcionaba en modo consola),
- Añadirle la variante de poder jugar entre Humano-Computadora  y Computadora-Computadora.
- Además lo he pasado al paradigma de la Programación Orientada a Objetos, con el fin de que la estructura del programa y las clases, os sirvan para futuros planteamientos a otros juegos de este tipo (los llamados de conocimiento perfecto: damas, ajedrez, etc).


Os dejo un video del desarrollo de una partida:






En próximas entradas de este blog, iré "desmembrando" el código fuente, para explicaros como funciona el programa "paso a paso".




Aqui teneis tanto el instalador en .deb como el código fuente.
Descarga paquete .deb: enlace
Código fuente en gambas3.4.2: enlace


Nota:
Actualizacion 3/10/2013 new
Version 0.0.4: enlace codigo fuente
 -> Corregido algoritmo de negamax, ya que en algunas ocasiones la poda era erronea.


Saludos