JUEGO MANCALA CON ALGORITMO MINIMAX REALIZADO CON INTERFAZ GRÁFICA EN JAVA Lucia Ruiz Ruiz Artem Motsarenko Jose Angel Leon Calvo Universidad Carlos III de Madrid [email protected] Universidad Carlos III de Madrid [email protected] Universidad Carlos III de Madrid [email protected] Inteligencia en Redes de Comunicaciones Ingeniería Sup. en Telecomunicación Quinto curso, 1º cuatrimestre ABSTRACT juego y elegir la mejor jugada en un momento determinado, sin tener que examinar todas las posibles jugadas. En este documento vamos a realizar un juego basado en Mancala usando como algoritmo Minimax con poda alfa-beta y dos niveles de búsqueda. Estará realizado con lenguaje de programación Java y una interfaz gráfica para que el usuario pueda jugar contra un usuario programado. La motivación para el estudio de este tipo de juegos viene de lo explicado en clase de Inteligencia en redes de comunicación y especialmente de la parte de juegos con algoritmo Minimax [1]. Descriptores de los métodos En nuestra implementación no hemos llevado a cabo todas las reglas que existen para Mancala, sino que hemos hecho una implementación con las reglas básicas. [Java]: public Movimiento MiniMaxAB(int [][] tableroActual,int turno, int prof) 2. HISTORIA DE MANCALA [2] Este es el método fundamental del algoritmo Minimax que detallaremos más adelante. Mancala es el nombre de una familia de juegos de tablero muy extendidos por toda África. Este juego se practicaba ya en el antiguo Egipto, pues se han encontrado tableros en la pirámide de Keops, y de allí debió extenderse a otros países de África y Asia. [Java]: public class JugadorTotal{public static void main(String[] args) { Esta es la clase que tiene el metodo main, esto es la que usaremos para ejecutar el Mancala. Términos Generales Algorithms, Design, Reliability, Human Factors, Languages, Theory. Keywords Mancala, Minimax, Java, GUI, poda alfa-beta, Juegos de mesa, 1. INTRODUCCIÓN Se desea implementar un jugador para una variante de la familia de juegos Mancala. En nuestro caso, tendremos dos jugadores que realizarán movimientos en turnos alternados. En cada uno de ellos el jugador redistribuye (siembra) las piezas (semillas) de un hoyo con el objetivo de capturar las piezas de su oponente. El tablero del juego está formado por 2 filas de 6 hoyos cada una y un contenedor. Una fila pertenece a un jugador y la otra a su oponente. Una característica de este juego es que el número total de semillas en el tablero permanece constante, y que cada jugador sólo siembra en su fila. Por tanto, si un jugador captura semillas del otro jugador está obligado a sembrar de nuevo estas semillas en sus hoyos. Para el desarrollo del algoritmo, se utilizará el procedimiento minimax y una mejora de éste conocida como poda alfa-beta, el cual permite generar un árbol de búsqueda para representar el Forma parte desde tiempos muy remotos de la tradición cultural de muchos pueblos y tribus, principalmente de África, y su práctica ha estado ligada a diferentes hechos, como a ritos funerarios, con motivo de mantener entretenido al espíritu del difunto; a ceremonias nupciales, para asegurar la fertilidad de la unión; y además, en casi todos los pueblos ha sido objeto de adivinación. Hoy, sin embargo, se juega sobre todo por placer y se ha convertido en el juego nacional de muchos países africanos, donde es conocido bajo diversas denominaciones, conociéndose casi doscientas variantes del juego, aunque todas ellas poseen características comunes. Los tableros varían ligeramente en cuanto material de construcción en función de la zona a la que pertenecen, pero todos cuentan con las dos filas de seis huecos, llamados pits de juego, cada una, y las dos cavidades mayores, que se denominan Kalahs, que sirven de depósito de las fichas capturadas por los jugadores. El número de fichas con los que se comienza a jugar varía mucho en función de la variante jugada, aunque lo más normal es comenzar con 3 ó 4 fichas por hoyo de juego. Las reglas del juego también varían en función de la variante jugada, aunque todas ellas tienen una base común [3]. Las versiones de Mancala más corrientes en Europa, son el Awale (también llamado Wari), el Kakua, el Mweso o Hus (que se juega con 64 fichas en un tablero de 32 huecos), el Oware, que es una de las variantes más sencilla, y el Kalah, Kalaha o conocido simplemente como Mancala, que es la variante egipcia, la más extendida y conocida en Occidente, y es la implementada en este proyecto. La filosofía en que se basa el Mancala es la siguiente: [4] Las tiradas se desarrollan en 2 fases: sembrar y cosechar. Se juega sobre un tablero con doce de agujeros, 6 por cada jugador. Los agujeros es donde se siembra y donde se cosecha. Las fichas del Mancala (normalmente semillas) son indiferenciadas, todas iguales. Y no pertenecen a ningún jugador. Se aplica el dicho “Las semillas son de quien las necesita. Quién mejor siembra, mejor cosechará”. En el Mancala hay 2 normas sagradas: “No se puede eliminar al adversario”. Se entiende que cuando se destruye al adversario, también se destruye la tierra que él cultiva. Quien lo hiciera por error, perdería la partida. Se aplica el dicho “Quien destruye la tierra donde cosecha, no podrá cosechar nunca más”. “No se puede dejar pasar hambre al adversario”. Esto significa que si nuestro rival se queda sin semillas, debemos ceder de las nuestras para que pueda seguir jugando. 3. ASPECTOS MATEMÁTICOS EN MANCALA [5] Los juegos de la familia Mancala son visto como algo simple ya que son del tipo determinista (no influye el azar en forma de dado u otro elemento aleatorio), tenemos información perfecta (excepto por la dificultad de recordar todos los elementos del juegos) y no hay demasiadas elecciones en cada movimiento, normalmente no tenemos más posibilidades que el número de hoyos en una fila. Sin embargo, el hecho que un solo movimiento tiene efecto en el contenido de todos los hoyos del tablero, hace complicado ver las consecuencias a largo a plazo o simplemente unos cuantos movimientos hacia adelante. Una propiedad matemática que nos permite ver la complejidad de juegos como el Mancala es el número de posibles posiciones. Una posición en Mancala consiste en un cierta distribución de las semillas en los hoyos del tablero, pero también incluimos un contador para las semillas que se pueden capturar o las que mantenemos en nuestro poder sino tenemos nada que capturar. El número de posibles posiciones depende del número de hoyos en nuestro tablero y del número de semillas que tengamos en cada uno. Este número, p, puede ser obtenido usando la siguiente fórmula de combinatoria: p =k*( ) En este formula k, es el número de jugadores, m es el número total de semillas y n es tanto el número total de hoyos y semillas juntas o el número total de hoyos incrementado con el número total de jugadores, sino almacenamos nada. El número p se incrementa muy rápido con el incremento de hoyos y semillas. En la tabla siguiente podemos ver el número de posibles posiciones en un tablero de Mancala con dos filas de seis hoyos y dos semillas para dos jugadores: Tabla 1: Número de posibles movimientos en Mancala Podemos ver como el número de posibles posiciones decrece, cuando solo nos fijamos en las semillas que hay en el tablero. Como podemos intuir solo un cierto número de estas posibles posiciones aparecen durante el juego, ya que, esto depende de la posición inicial del juego y de las normas que estemos usando. En una variación del Mancala, el Kalah, solo un 5% de estas posibles posiciones aparecen en un juego real [6]. 4. INTELIGENCIA ARTIFICIAL EN MANCALA Inteligencia Artificial (IA) es una rama de la informática que pretende que un ordenador pueda realizar lo que normalmente se considera como inteligente o simular el comportamiento humano. Hay dos motivos principales por las que se realiza esta investigación: el primero es evitar esfuerzos a humanos con la ayuda del ordenador. La segunda motivación es tratar de entender cómo la inteligencia humana u operaciones mentales trabajan a través de la simulación por ordenador. Los juegos han jugado un papel importante en la inteligencia artificial, porque para jugar a estos se considera como una tarea típicamente inteligente, pero también porque los juegos casi siempre forman un ambiente cerrado con posibilidades limitadas y reglas claramente definidas. Esto último hace que para los investigadores en IA sea mucho más fácil tratar con juegos que tratar, por ejemplo, con el mercado de valores, pues este último está sometido a múltiples variables y no se comporta según un conjunto de reglas cerradas. El resultado más famoso de la IA en los juegos es, por supuesto, el hecho de que en los ordenadores hoy en día se puede jugar al ajedrez a nivel de gran maestro e incluso derrotando el ex campeón del mundo. En la carrera competitiva entre ordenadores capaces de jugar al ajedrez mediante programas, las técnicas se han desarrollado mucho y se están aplicando actualmente estas técnicas otras áreas de la IA y la informática. Se podría decir que los juegos (y en especial el ajedrez) son la Fórmula 1 de la informática. La familia de juegos Mancala se ha introducido en Inteligencia Artificial relativamente pronto, aunque la mayor parte de investigación se limita a sólo dos juegos: Kalah y Awari. Las instancias más pequeñas de Kalah fueron resueltos al considerar todas las posiciones que en realidad pueden surgir durante una partida de Kalah. Las bases de datos se han creado en que cada posición y su valor de teoría de juegos se almacenan. Los casos más grandes de Kalah se resolvieron mediante la búsqueda de juegos de árbol (mismo mecanismo que usaremos nosotros en nuestra implementación). Para estos casos, sólo se conoces una estrategia ganadora partiendo de una posición inicial en concreto. El programa es, sin embargo, capaz de encontrar una estrategia óptima para cada posición que pueda ocurrir durante un juego de Kalah. Esto significa que Kalah no es de interés para los investigadores ya que la IA desea que el equipo para jugar el juego de Kalah como sustitutos o de forma superior a los humanos. Sin embargo, para los investigadores de la IA del juego y psicólogos que estén interesados en el aspecto humano del juego de los resultados que se obtuvieron siguen haciendo de Kalah algo muy útil. 5. APLICACIONES EDUCATIVAS DE MANCALA [7] Los juegos basados en Mancala ofrecen la oportunidad de ver fácilmente cómo se puede mejorar con la práctica, y por lo tanto ayudan a aprender a trabajar en algo para obtener una meta. Estos juegos de mesa también enseñan a los niños a seguir instrucciones, a acatar las reglas, jugar limpio y hacer frente a las derrotas. Ayudan con la interacción cara a cara, la cooperación y la competencia, y a mejorar las habilidades sociales. Su herencia multicultural va en contra de las actitudes racistas y enseña la cooperación. También aumentan la conciencia y el respeto hacia su propio patrimonio cultural, en particular entre los jugadores de África y Asia. El Mancala se ha considerado una herramienta pedagógica muy útil en la educación de niños y adultos durante siglos. El juego Mancala mejora la capacidad de observación, los jugadores tienen que desarrollar habilidades cognitivas para distinguir buenos movimientos de los malos y posiciones favorables del tablero frente a las desfavorables. Son ejercicios que fortalecen la memoria y la concentración. Mancala enseña el pensamiento analítico, ya que los jugadores deben aprender a planificar y desarrollar estrategias, para ser un jugador ganador tienen que prever lo que va a pasar varios movimientos por adelantado. El juego obliga a los jugadores a anticipar los próximos movimientos de su oponente. Tienen que ponerse en la posición de otra persona, ya que de lo contrario pueden ser derrotados fácilmente. También ayuda con el pensamiento matemático, ya que para empezar, uno tiene que mantener un registro del número de piedras en cada agujero. Ellos ayudan con las habilidades básicas de cálculo, pero también ofrecen grandes retos para los matemáticos y científicos informáticos. Una variación moderna llamada Aritmética fue diseñada específicamente para enseñar aritmética en las escuelas primarias. Mancala también han sido utilizados por las escuelas en los EE.UU. para ayudar a los niños con discalculia (dificultad en el aprendizaje de las matemáticas). Los juegos de Mancala desarrollan la motricidad fina., estas incluyen el seguimiento visual, la coordinación mano-ojo, y la capacidad de manipular objetos pequeños mediante la transferencia en un proceso conocido como "siembra" (poner las semillas en el tablero). 6. INTRODUCCIÓN ALGORITMO MINIMAX CON PODA ALFA-BETA La idea principal del algoritmo es tomar como punto de partida una posición y utilizar un generador de movimientos para generar un conjunto de posiciones de posibles sucesores, por lo que se aplica una función de evaluación estática y se selecciona el mejor movimiento obteniendo el valor. Los pasos que usaremos son los siguientes [1]: Generar el árbol de juego, alternando movimientos de MAX y MIN y asignándoles los valores apropiados (MAX>0, MIN<0). Calcular la función de utilidad de cada nodo final, recorriendo recursivamente los nodos hasta el estado inicial. Elegir como jugada a realizar aquel primer movimiento que conduce al nodo final con mayor función de utilidad. En el desarrollo de los juegos de dos jugadores, a uno se le denominará MAX y al otro MIN, cada uno con su turno correspondiente Esta búsqueda realizada se puede definir en base a: un Estado Inicial, Movimientos Posibles (Sucesores, luego de aplicar la Función de evaluación), un Estado Final, Valor o Función de Utilidad; los mismos que a su vez vienen a definir un árbol de juego y donde se desarrollará primero una búsqueda en profundidad, para nuestro caso profundidad limitada. Usualmente se puede decir en una búsqueda cualquiera, que la estrategia óptima se logra alcanzar cuando tras un conjunto de movimientos posibles se llega a la meta u objetivo que viene a ser el estado ganador; sin embargo, la estrategia óptima que aquí vamos a implementar no va por ese camino, sino más bien consideramos que tras la realización de una jugada MAX, viene una jugada MIN y tras la misma viene otra MAX y puede ser vista en el árbol de juego (generado dado una cierta profundidad), evaluando la función de valor Mínimax en cada nodo. Debido a que uno de los problemas que tiene implícito el algoritmo es el gran uso que hace de la memoria, realizaremos una poda alfa-beta que nos permitirá no expandir todo los caminos posibles, sino solo aquellos que mejoran el camino por el que vamos, donde alfa y beta representan, respectivamente, las cotas inferior y superior de los valores que se van a ir buscando en la parte del subárbol que queda por explorar. Si alfa llega a superar o igualar a beta, entonces no será necesario seguir analizando las ramas del subárbol. En pseudocódigo el algoritmo Minimax para el juego de Mancala sería [8]: Entrada: nodoJuego (Mancala), Profundidad, turnoPC, Alfa (inicialmente -inf), Beta (inicialmente +inf) Salida: el nodo (Mancala) a Jugar 1. Si el estado del nodoJuego es un final (Juego Terminado) o la profundidad de análisis restante es cero, 1.1. Devolver nodoJuego cuyo valor sea el valor calculado mediante la función de Evaluación respectiva. 1.2. En caso contrario, hacer 1.2.1 Calcular los SUCESORES del nodoJuego 1.2.2 Si la lista de SUCESORES es vacía 1.2.2.1 Devolver nodoJuego cuyo valor sea el valor calculado mediante la función de Evaluación respectiva. 1.2.2.2 En caso contrario, si el jugador del nodoJuego es MAX 1.2.2.2.1 Devolver el nodo de la lista de SUCESORES obtenido con la función MAXIMIZADOR-A-B 1.2.2.2.2 Sino Devolver el nodo de la lista de SUCESORES obtenido con la función MINIMIZADOR-A-B 7. REGLAS DEL JUEGO [9] El juego consiste en recolocar o redistribuir las semillas de un hoyo en otros hoyos de la misma fila con el objetivo de capturar el mayor número posible de semillas al oponente. El juego termina cuando uno de los dos jugadores consiga que su oponente posea una o ninguna semilla en su fila, en tal caso es el ganador de la partida. Figura 2: Estado de captura por jugador humano (parte inferior) Como vemos en la figura 2, el jugador 2 tiene la posibilidad de realizar una captura de las 2 semillas que tiene el oponente en el cubilete 2 de su lado del tablero, por lo que realizando este conseguirá 3 semillas más para su marcador (1 bola suya + las 2 que captura) Cede semillas y cambio de turno: Si cae en un hoyo con 3 o más semillas que no cualifica para captura, y si el contario tiene una o dos pero menos de 3 semillas en su hoyo opuesto (en ambos casos, antes de depositar la nueva), se ceden al hoyo contrario todas las semillas del hoyo de última semilla y se pasa el turno al oponente. Cambio de turno: En cualquier otro caso, se termina la jugada y se pasa el turno al oponente. 7.1 Estado inicial Se selecciona un hoyo que contenga semillas, y que preferiblemente permita hacer una captura. Se siembran las semillas del hoyo seleccionado en los sucesivos hoyos, yendo de izquierda a derecha (relativas al jugador situado frente a su fila), y depositando una semilla en cada hoyo. En el caso de que se llegara sembrando al final de la fila (hoyo 5) se continúa sembrando desde el principio (hoyo 1) y en la misma fila del jugador. 7.3 Fin de turno Un jugador finaliza su turno cuando se da alguno de los siguientes casos: después de la siembra inicial o captura, la última semilla cae en un hoyo de su fila sin semillas. cuando después de una captura no se puede realizar otra captura. cuando tiene que ceder semillas al contrario. Figura 1. Estado inicial del tablero Mancala 7.2 Captura/cesión Se da sólo cuando tras la siembra, la última semilla se deposita en un hoyo que ya tenía semillas (hoyo de última siembra) y en el hoyo opuesto del otro jugador también tiene semillas. En este caso, se pueden dar las siguientes alternativas: Captura semillas: Si cae en un hoyo con un número impar de semillas (antes de depositar la nueva) y el contrario en el hoyo opuesto también tiene un número impar de semillas, se capturan las semillas del hoyo opuesto y se siembran en la fila del jugador, comenzando a sembrar a partir del siguiente hoyo a la derecha del de última siembra. Tras la nueva siembra, volverá a analizarse el nuevo hoyo de última siembra para comprobar si de nuevo hay captura (en cuyo caso se repetiría todo el proceso hasta que finalicen las capturas) o cesión. Figura 4. Estado del tablero Mancala cuando ha terminado el turno del jugador 2 Si un usuario mete su última semilla en su recogedor puede repetir turno como en el caso siguiente: 8.1 Estado inicial Estado Inicial Figura 5. Estado del tablero Mancala antes de jugar el Jugador 2 Figura 8: Representación estado inicial del tablero de Mancala El jugador 2 pulsará en el cubilete con 4 semillas por lo que podrá volver a pulsar en otro sin tener que ceder el turno al contrincante Representaremos como uno de los posibles estados del tablero de juegos con un nodo del árbol y por medio de flechas evaluaremos con la función de evaluación los distintos escenarios posibles. El árbol estará formado por nodos ordenados en niveles de profundidad en los cuales cada uno pertenecerá respectivamente a nuestro turno y el siguiente al jugador adversario. Figura 6. Estado del tablero Mancala cuando ha terminado el turno del jugador 2 y sigue en su turno 8.2 Representación de los dos niveles de búsqueda 7.4 Fin del juego Existen dos posibilidades de fin de juego: por victoria de uno de los jugadores o por tablas. Un jugador gana la partida cuando consigue que su oponente tenga en su fila una o ninguna semilla o cuando el oponente abandona o si su función de evaluación comete algún error, por ejemplo abortando. Otro factor que hace que un jugador gane es que tenga mayor número de semillas que el contrario, en nuestro caso si tiene más de 24 semillas en su contenedor, el jugador ganará la partida. Figura 9: Representación árbol con profundidad 2 La figura que hemos dibujado representa la búsqueda en dos niveles (aunque para simplificar el dibujo simplemente hemos expandido el árbol en un nodo). Esta búsqueda como vemos tiene el problema de ser muy costosa en términos de memoria, ya que la búsqueda en términos computacionales sería del orden de: Figura 7: Estado final del tablero de Mancala 8. ALGORITMO MINIMAX PARA MANCALA Para la representación del algoritmo de Mancala usaremos una representación en forma de árbol, que es la más usada para este tipo de algoritmos, ya que nos permite clasificar el algoritmo según el número de niveles que tenemos que recorrer y dar un valor a cada una de las ramas de un nodo: Complejidad = 6!*6! = 518400 posibilidades lo que resulta ser un número bastante elevado y simplemente estamos expandiendo en dos niveles. Si realizamos una búsqueda en más niveles obtenemos los siguientes datos: 3 niveles 3733248000 4 niveles 268738560000 5 niveles 193491763200000 Tabla 2: Número de movimientos en el árbol Minimax Como podemos observar si aumentamos el número de niveles, los valores se vuelven en términos computacionales y de memoria imposibles de manejar, por lo que además de reducir el número de niveles que vamos a manejar, también aplicaremos la poda alfabeta que nos ayudará a no tener que manejar todas las posibilidades del árbol, sino quedarnos con únicamente las que mejoran el camino. Estamos realizando una búsqueda en profundidad (DFS) que puede mejorar su eficiencia usando una técnica de ramificación y acotación, con la cual una solución parcial se abandona cuando se comprueba que es peor que otra solución conocida o umbral. Por lo tanto, la estrategia de poda del algoritmo Minimax usaremos es la llamada poda alfa-beta, puesto que dado existen dos jugadores maximizador y minimizador, existen valores umbral alfa y beta para acotar la búsqueda de cada respectivamente. El valor alfa representa la cota inferior del puede asignarse en último término a maximizante. El valor beta representa la cota superior del puede asignarse en último término a minimizante. que que dos uno valor que un nodo valor que un nodo En un nivel dado, el valor de umbral alfa o beta según corresponda, debe actualizarse cuando se encuentra un umbral mejor. Aparte de este algoritmo que sería una implementación básica, existe otros métodos para refinar el algoritmo y conseguir mejores resultados La efectividad del procedimiento alfa-beta depende en gran medida del orden en que se examinen los caminos. Si se examinan primero los peores caminos no se realizará ningún corte. Pero, naturalmente, si de antemano se conociera el mejor camino no necesitaríamos buscarlo. La efectividad de la técnica de poda en el caso perfecto ofrece una cota superior del rendimiento en otras situaciones. Según Knuth y Moore (1975), si los nodos están perfectamente ordenados, el número de nodos terminales considerados en una búsqueda de profundidad d con alfa-beta es el doble de los nodos terminales considerados en una búsqueda de profundidad d/2 sin alfa-beta. Esto significa que en el caso perfecto, una búsqueda alfa-beta nos da una ganancia sustancial pudiendo explorar con igual costo la mitad de los nodos finales de un árbol de juego del doble de profundidad. Describimos ahora otras modificaciones del procedimiento MINIMAX que también mejoran su rendimiento. La poda de inutilidades es la finalización de la exploración de un subárbol que ofrece pocas posibilidades de mejora sobre otros caminos que ya han sido explorado Espera del reposo: Cuando la condición de corte de la recursión del algoritmo MINIMAX está basada sólo en la profundidad fija del árbol explorado, puede darse el llamado efecto horizonte. Esto ocurre cuando se evalúa como buena o mala una posición, sin saber que en la siguiente jugada la situación se revierte. La espera del reposo ayuda a evitar el efecto horizonte. Una de las condiciones de corte de recursión en el algoritmo MINIMAX debería ser el alcanzar una situación estable. Si se evalúa un nodo de un árbol de juego y este valor cambia drásticamente al evaluar el nodo después de realizar la exploración de un nivel más del árbol, la búsqueda debería continuar hasta que esto dejara de ocurrir. Esto se denomina esperar el reposo y nos asegura que las medidas a corto plazo, por ejemplo un intercambio de piezas, no influyen indebidamente en la elección. Búsqueda secundaria: Otra manera de mejorar el procedimiento MINIMAX es realizar una doble comprobación del movimiento elegido, para asegurarnos que no hay una trampa algunos movimientos más allá de los que exploró la búsqueda inicial. Luego de haber elegido un movimiento en concreto con un procedimiento MINIMAX que explora n niveles, la técnica de búsqueda secundaria realiza una búsqueda adicional de d niveles en la única rama escogida para asegurar que la elección sea buena. Uso de movimientos de libro: La solución ideal de un juego sería seleccionar un movimiento consultando la configuración actual en catálogo y extrayendo el movimiento correcto. Naturalmente en juegos complicados esto es imposible de realizar, pues la tabla sería muy grande y además nadie sabría construirla. Sin embargo, este enfoque resulta razonable para algunas partes de ciertos juegos. Se puede usar movimientos de libro en aperturas y finales, combinando con el uso de búsqueda MINIMAX para la parte central de la partida, mejorando el rendimiento del programa. Por ejemplo, las secuencias de apertura y los finales del ajedrez están altamente estudiados y pueden ser catalogados. Búsqueda sesgada: Una forma de podar un árbol de juegos es hacer que el factor de ramificación varíe a fin de dirigir más esfuerzo hacia las jugadas más prometedoras. Se puede realizar una búsqueda sesgada clasificando cada nodo hijo, quizás mediante un evaluador estático rápido y luego utilizando la siguiente fórmula: R(hijo) = R(padre) - r(hijo) donde R es el número de ramas de un nodo y r es el lugar que ocupa un nodo entre sus hermanos ordenados según la evaluación estática rápida. Una variante respecto a la que hemos estudiado es tener en cuenta la inteligencia del adversario, esto es, que pueda obtener algún movimiento que este en alguna capa más profunda que la que estudia nuestro algoritmo. Aun suponiendo que el algoritmo siempre explora a una mayor profundidad que el adversario, éste último puede equivocarse y no elegir el camino óptimo. La consecuencia es que el algoritmo elige el movimiento basándose en una suposición errada. Ante una situación de derrota, según sugiere Berliner (1977), podría ser mejor asumir el riesgo de que el oponente puede cometer un error. Análogamente, cuando se debe elegir entre dos movimientos buenos, uno ligeramente mejor que el otro, podría resultar mejor elegir el menos mejor si al asumir el riesgo de que el oponente se equivoque nos conduce a una situación muchos más ventajosa. Para tomar esta clase de decisiones correctamente, el algoritmo debería modelar el estilo de juego de cada oponente en particular. Esto permitiría estimar la probabilidad de que cometa distintos errores. Sin lugar a dudas, esto es muy difícil de lograr y se necesita contar con técnicas de aprendizaje para que el algoritmo obtenga conocimiento sobre su oponente a lo largo del juego. System.out.println("Empate"); return 3; } 9. ALGORITMO MINIMAX IMPLEMENTADO Vamos a describir la implementación que hemos realizado para nuestro juego de Mancala empezando por la función de evaluación: La función de evaluación que se ha implementado es muy sencilla, el jugador automático elegirá como movimiento optimo el que le permite depositar más semillas en su contenedor, sin verificar ningún otro parámetro. Hemos elegido esta estrategia por simplicidad en la ejecución y porque es la que más se parece a un jugador novato o con poca experiencia en este tipo de juegos. Una forma de mejorar esta función de evaluación sería que el jugador también tuviese en cuenta el número de semillas que puede capturar con su movimiento o que jugase de una forma defensiva, esto es, en vez de intentar llenar su contenedor mover de tal forma que el oponente estuviera bloqueado y no pudiese rellenar su contenedor. Una vez comentada la función de evaluación vamos a comentar como hemos realizado en Java el Mancala. Las dos filas de hoyos las hemos realizado como un array de siete columnas y dos filas (en las que incluimos también los recogedores de cada jugador) y en nuestro juego, hemos colocado como estado inicial que cada hoyo tenga 4 semillas: Vamos a explicar el algoritmo Minimax que hemos usado cuyo código es el siguiente: public Movimiento MiniMaxAB(int [][] tableroActual,int turno, int prof){ cuantasVeces++; System.out.println("MINIMAX:"+cuantasVeces); int valores[][]= tableroActual; imprimeTablero(valores); List <Movimiento> lista= PosiblesMovimientos(valores, turno); Movimiento mov= new Movimiento(); Movimiento movAux= new Movimiento(); Movimiento pulsar = new Movimiento(); System.out.println("PROFUNDIDAD = "+prof); if(prof<=0 || lista == null || lista.isEmpty()){ System.out.println("Ultimo nivel : PROFUNDIDAD = "+prof); if(lista == null || lista.isEmpty()){ System.out.println("No hay movimientos posibles");} for(int i = 0 ;i<lista.size();i++){ if(i==0)movAux= lista.get(i); mov = lista.get(i); iniciales = 4; imprimeTablero(mov.getTablero()); bolas = new int[7][2]; if(mov.getPuntos()> movAux.getPuntos()) bolas[6][0]= 0; movAux= mov; bolas[6][1]= 0; } for(int j =0;j<2;j++){ for (int i = 0;i<6;i++){ bolas[i][j]=iniciales; return movAux; } for(int i = 0 ;i<lista.size();i++){ //recorremos lista } if(turno==0)turno=1;else turno=0 } El juego termina cuando un jugador obtiene más de la mitad de las semillas que hay en el sistema completo, esto es, cuando obtiene más de 24 semillas en su contenedor: Dentro del método haGanado(): Movimiento MiniMaxAB((lista.get(i)).getTablero(),turno,prof-1); if(i==0)pulsar=m; m= (lista.get(i)).setPuntos(m.getPuntos()); if(lista.get(i).getY()==0){ if(lista.get(i).getPuntos()>pulsar.getPuntos()) pulsar= lista.get(i); if( bolas[6][0]<24 ){ } System.out.println("Ha ganado el jugador 2"); else{ return 1; }else if(bolas[6][0]>24){ System.out.println("Ha ganado el jugador 1"); return 0; if(lista.get(i).getPuntos()<pulsar.getPuntos()) pulsar= lista.get(i); }} return pulsar; } if(bolas[6][0]==24){ Esta función va hasta el nivel más profundidad dado por el valor de la profundidad (a más profundidad mayor gasto en memoria) y una vez estemas en lo más profundo del árbol, evaluamos cada una de las ramas de ese nodo. Una vez tengamos todos los nodos almacenados en una lista de posibles movimientos elegimos aquel que tenga un mayor valor (en nuestro caso aquel que permita meter un mayor número de semillas en el recogedor en el siguiente movimiento) y hacemos lo mismo con todos los nodos de este último nivel. Una vez se haya obtenido el mayor valor para este nivel, recorremos de forma inversa el árbol, realizando la misma operación con los nodos superiores, hasta llegar a la raíz de la cima con todos los nodos, hasta el nivel de profundidad correspondiente, evaluados. Nos quedamos con aquel que nos da un mayor valor neto, este es el que nos permite meter mayor número de semillas en nuestro recogedor en el siguiente movimiento y posteriores. 10. REFERENCIAS [1] Villena, Julio. Apuntes de la asignatura Inteligencia en redes de comunicación. Universidad Carlos III de Madrid [2] Recurso web: http://www.dma.fi.upm.es/docencia/primerciclo/matrecreativ a/juegos/mancala/historia.htm. [3] Recurso web: http://brainking.com/es/GameRules?tp=103 [4] Recurso web: http://aprendiendomatematicas.com/tag/mancala/ [5] Jeroen Donkers, Jos Uiterwijk and Alex de Voogt, Mancala games - Topics in Mathemathics and Artificial Intelligence [6] Irving, G., Donkers, H. H. L. M., & Uiterwijk, J. W. H. M. (2000). Solving Kalah. ICGA Journal, 23(3), 139-146. [7] Retschitzki, J. (1990). Stratégies des joueurs d’awélé. Paris: L’Harmattan [8] Recurso web: http://nineil-leissics.blogspot.com.es/2008/06/proyecto-1-unidad-juegomancala.html [9] Recurso web: http://www.bgamers.com/mancrul.htm