Proyecto Final de Carrera Ingenierı́a Informática Curso 2011-2012 Método de Monte-Carlo Tree Search (MCTS) para resolver problemas de alta complejidad: Jugador virtual para el juego del Go Beatriz Nasarre Embid Junio de 2012 Director: Dr. Francisco Serón Arbeloa Co-Director: Dr. Manuel González Bedia Departamento de Informática e Ingenierı́a de Sistemas Escuela de Ingenierı́a y Arquitectura Universidad de Zaragoza A todos los que hacéis cumplir mis sueños Todo aquello que hoy es una realidad, antes era sólo parte de un sueño imposible (William Blake) Agradecimientos Quiero agradecer a mis directores, Paco y Manolo su ayuda y dedicación durante estos meses. Concretamente a Paco, por darme la oportunidad de trabajar este proyecto tan interesante, por la confianza depositada en mı́ y por todos tus consejos y a Manolo por transmitirme ese interés por los sistemas cognitivos. También quiero dar las gracias a mis amigos de clase que me han ayudado año tras año, disfrutando de su compañı́a, compartiendo los buenos y malos momentos y dándome ese empujoncito cuando lo necesitaba. Gracias a todos los que formáis AEGEE por transmitirme siempre esa energı́a, cariño, motivación, trabajo e ilusión. Quiero agradecer también los Adebaneros el compartir conmigo esos buenos momentos. Finalmente, dar las gracias a mi familia, por apoyarme siempre, estar ahı́ y enseñarme a luchar por lo que quiero. Derechos de autor Los derechos de la presente obra pertenecen a Dª.Beatriz Nasarre Embid, al Dr.D.Francisco José Serón Arbolea y al Dr.D.Manuel González Bedia, del Departamento de Informática e Ingenierı́a de Sistemas de la Escuela de Ingenierı́a y Arquitectura de la Universidad de Zaragoza. Queda prohibida la reproducción total o parcial de esta obra, por cualquier medio, sin el permiso escrito de los autores. Ficha técnica Tı́tulo Método de Monte-Carlo Tree Search (MCTS) para resolver problemas de alta complejidad: Jugador virtual para el juego del Go Autora Beatriz Nasarre Embid DNI 17754254 Especialidad Informática Directores Francisco Serón Arbeloa y Manuel González Bedia Departamento Departamento de Informática e Ingenierı́a de Sistemas Centro Escuela de Ingenierı́a y Arquitectura Universidad Universidad de Zaragoza Fecha Junio 2012 i Método de Monte-Carlo Tree Search (MCTS) para resolver problemas de alta complejidad: Jugador virtual para el juego del Go RESUMEN La resolución de ciertos tipos de problemas aun supone un reto para la Inteligencia Artificial. Algunos de ellos son los problemas de juegos, donde uno o varios jugadores compiten por lograr un mismo objetivo. El Go es un juego de mesa estratégico para dos jugadores. Se originó en China y su historia se remonta hace más de 2500 años. A pesar de la simplicidad de sus reglas, el Go, supone aun un reto para la Inteligencia Artificial, incapaz de realizar mediante ordenador un jugador capaz de vencer a los humanos expertos en el juego. El método Monte-Carlo Tree Search (MCTS) estudiado, en contraste con los algoritmos clásicos, no necesita ninguna función heurı́stica de evaluación de posición, ya que realiza una exploración aleatoria del espacio de búsqueda, construyendo gradualmente en memoria un árbol de juego a través de los resultados de exploraciones anteriores. Este algoritmo resulta interesante para una gran cantidad de dominios, ha conseguido muy buenos resultados en problemas de juegos de todo tipo, especialmente en el juego del Go. En este proyecto se ha realizado la implementación del juego del Go. Para ello se ha creado una estructura lógica que permite controlar de una forma más fácil las reglas del juego. Un requisito importante del módulo del método Monte-Carlo Tree Search a implementar fue que se pudiese aplicar a distintos problemas, no solo al juego del Go. Este hecho, ha influido tanto en su estructura, diseño, como en las estrategias elegidas en el módulo implementado. Tras la realización de este proyecto se ha conseguido un módulo que implementase el método Monte-Carlo Tree Search independiente del problema y fuera usado para dotar de “inteligencia” al juego del Go, permitiendo que el usuario se enfrentase a un jugador virtual. La aplicación creada permite realizar este enfrentamiento de forma gráfica e interactiva gracias a su interfaz. La “inteligencia” del juego aun sin poder medirse puede apreciarse en las jugadas realizadas por el mismo, siendo todo un reto para personas no expertas en el juego. El módulo MCTS desarrollado pretende usarse en alguno de los campos de trabajo en los que está trabajando el Grupo de Informática Gráfica Avanzada (GIGA) de la Universidad de Zaragoza. Uno de ellos es el campo de los videojuegos, en el cual la Inteligencia Artificial está cobrando cada vez más importancia. Índice general 1. Introducción 1.1. Contexto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2. Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3. Estructura del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 2 2 2. Juego del Go 2.1. Elementos del juego . . . . . . . . . 2.1.1. Tablero . . . . . . . . . . . . 2.1.2. Piedras . . . . . . . . . . . . 2.1.3. Jugadores . . . . . . . . . . . 2.2. Reglas . . . . . . . . . . . . . . . . . 2.2.1. Captura . . . . . . . . . . . . 2.2.2. Suicidio . . . . . . . . . . . . 2.2.3. Ko . . . . . . . . . . . . . . . 2.3. Recuento de puntos . . . . . . . . . . 2.3.1. Clasificación de los jugadores 2.4. Complejidad e Inteligencia Artificial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 4 4 4 5 6 6 7 7 8 9 10 3. Implementación del juego del Go 3.1. Las clases . . . . . . . . . . . . . 3.2. El Go y el usuario . . . . . . . . 3.3. El Tablero y las Reglas del juego 3.3.1. Libertad del bloque . . . 3.3.2. Validez de una jugada . . 3.3.3. Colocación de una pieza . 3.3.4. Recuento de territorios . . 3.4. Los Bloques . . . . . . . . . . . . 3.4.1. La estructura . . . . . . . 3.4.2. Las operaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 11 12 13 13 13 14 15 15 15 16 4. Algoritmo MCTS 4.1. Estructura . . . . . . . . . . . 4.2. El algoritmo . . . . . . . . . . 4.3. Las fases . . . . . . . . . . . . 4.3.1. Selección . . . . . . . 4.3.2. Expansión . . . . . . . 4.3.3. Simulación . . . . . . 4.3.4. Retropropagación . . . 4.4. Selección del movimiento final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 20 21 21 22 23 23 24 . . . . . . . . . . . . . . . . iii ÍNDICE GENERAL iv 5. Implementación del método MCTS 5.1. Las clases . . . . . . . . . . . . . . . . . 5.1.1. NodoUCT . . . . . . . . . . . . . 5.1.2. Contenido . . . . . . . . . . . . . 5.1.3. SimulaciónUCT . . . . . . . . . . 5.1.4. SimulacionUCTGo . . . . . . . . 5.2. Reutilización de simulaciones anteriores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 25 25 25 26 29 30 6. Aplicación 6.1. Esquema . . . . . . . . . . . 6.2. Interfaz . . . . . . . . . . . 6.2.1. Ventana Inicio . . . 6.2.2. Ventana de reglas . . 6.2.3. Ventana de opciones 6.2.4. Ventana de juego . . 6.2.5. Tablero . . . . . . . 6.3. Valor del coeficiente UCT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 33 33 33 34 34 35 36 37 7. Conclusiones 7.1. Marco de trabajo . . . . 7.2. Resultados obtenidos . . 7.3. Diagrama de tiempos . . 7.4. Lı́neas de trabajo futuro 7.5. Problemas encontrados . 7.6. Valoración personal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 39 39 40 40 41 42 A. Gestión del proyecto A.1. Metodologı́a de desarrollo . . A.2. Fases del proyecto . . . . . . A.3. Gestión de tiempo y esfuerzo A.4. Supervisión del proyecto . . . A.5. Herramientas utilizadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 43 44 45 46 46 . . . . . . . . . . . . B. Requisitos 49 C. Aplicaciones MCTS C.1. Deterministas . . . . . . . . . . . . . . . C.1.1. Deterministas de un jugador . . C.1.2. Deterministas de dos jugadores . C.1.3. Deterministas multijugadores . . C.2. Estocásticos . . . . . . . . . . . . . . . . C.2.1. Estocásticos de un jugador . . . C.2.2. Estocásticos de dos jugadores . . C.2.3. Estocásticos de varios jugadores C.3. Juegos de propósito general . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 51 51 52 52 52 52 53 53 54 D. Ejemplo de simulación D.1. La estructura del nodo . . D.2. Forma del árbol . . . . . . D.3. Iteraciones . . . . . . . . . D.3.1. Primera iteración . D.3.2. Segunda iteración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 55 56 56 56 58 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ÍNDICE GENERAL v D.3.3. Tercera iteración . . . . . . . . . . . . . . . . . . . D.3.4. Iteraciones de la cuarta a décima . . . . . . . . . . D.3.5. Decimoprimero iteración . . . . . . . . . . . . . . . D.3.6. Iteraciones de la decimosegunda a la decimocuarta D.3.7. Decimoquinta iteración . . . . . . . . . . . . . . . D.3.8. Decimosexta iteración . . . . . . . . . . . . . . . . D.3.9. Iteraciones de la de la decimoséptima a la vigésima D.3.10. Futuras iteraciones . . . . . . . . . . . . . . . . . . D.4. Elección del mejor nodo . . . . . . . . . . . . . . . . . . . D.5. Número de simulaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 61 61 62 62 63 64 65 66 67 E. Validación E.1. Go . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.1.1. Reglas y bloques . . . . . . . . . . . . . . . . . . . E.1.2. Recuento de puntuaciones . . . . . . . . . . . . . . E.2. MCTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . E.2.1. Eficiencia del método . . . . . . . . . . . . . . . . E.2.2. Avanzar cuándo el árbol es vacı́o . . . . . . . . . . E.2.3. Avanzar cuándo el árbol es no vacı́o . . . . . . . . E.2.4. Mezcla de las anteriores: Avanzar sobre árbol vacı́o E.3. Aplicación . . . . . . . . . . . . . . . . . . . . . . . . . . . E.3.1. Pruebas de funcionamiento . . . . . . . . . . . . . E.3.2. Pruebas de usabilidad e inteligencia del juego . . . . . . . . . . . . . . . . . . . . . . . . y no . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . vacı́o. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 69 70 83 86 86 86 87 88 89 89 90 F. Manual de usuario F.1. Ventanas y navegación F.2. Ventana de inicio . . . F.3. Ventana de opciones . F.4. Ventana de juego . . . F.5. Ventana de reglas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 91 92 92 93 95 Glosario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 vi ÍNDICE GENERAL Capı́tulo 1 Introducción El problema de búsqueda en árboles es un problema en el cual los estados se representan como nodos de un árbol, y las acciones pueden ser representadas como ejes entre los nodos. Se define un árbol como un grafo acı́clico donde cada nodo tiene un conjunto de cero o más nodos hijos, y al menos un nodo padre. 1 Distinguimos tres tipos de problemas relacionados con el mundo de los juegos2 [1, 2, 3]: 1) Problemas sin oponentes (llamados también problemas de optimización, juegos de un jugador o puzles); 2) Problemas con un oponente (juegos de dos jugadores, en los que se lucha contra el oponente o se colabora con él) y 3) Problemas con múltiples oponentes (juegos multijugador donde se puede crear coaliciones). Sin embargo, también se pueden clasificar según intervengan algún elemento aleatorio (Problemas estocásticos[5]) o no (Problemas deterministas[4]). La Tabla 1.1 muestra un esquema de ejemplos para estos problemas. Determinista Estocástico Un jugador Problema del viajante Problema de navegación Dos jugadores Go, ajedrez Backgammon Multi-jugadores Damas chinas Catan Simplificado Cuadro 1.1: Problemas de búsqueda en árboles Un algoritmo de búsqueda toma un problema (ej. un juego) como entrada y devuelve una solución en forma de una secuencia de acciones (ej. secuencia de movimientos). Muchos algoritmos de búsqueda se han desarrollado durante el último siglo. Durante décadas, el algoritmo αβ [6]ha sido el estándar de la búsqueda en árboles para juegos de dos jugadores. Este algoritmo requiere una función de evaluación3 para dar resultados satisfactorios. Sin embargo, está función de evaluación no está disponible para el Go (juego elegido para el proyecto), donde el efecto de colocar una pieza es solo visible a largo plazo. Como consecuencia, los mejores programas de Go en 2005 utilizaron una combinación de la búsqueda αβ, sistemas expertos, heurı́sticos y patrones, donde la metodologı́a usada era completamente dependiente del dominio. Una alternativa que emergió sobre esta época, fue usar las simulaciones de Monte-Carlo como alternativa a la función de evaluación de posición, que pronto darı́a lugar a una nueva técnica, el método Monte-Carlo Tree Search (MCTS) en español Búsqueda en Árbol de Monte-Carlo. En 2006 comenzaron a surgir las distintas versiones de este método, según las estrategias que se usasen en él. Hoy en dı́a el método MCTS aun sigue siendo tema de investigación interesante. 1 Russell and Norvin 1995 problemas de juegos son aquellos en que uno o varios jugadores compiten por lograr un mismo objetivo. 3 Es una función que estima con un valor numérico cada una de las posiciones analizadas en algoritmos de búsqueda en arboles. [7, 8] 2 Los 1 2 CAPÍTULO 1. INTRODUCCIÓN 1.1. Contexto Este proyecto ha sido desarrollado en el GIGA (Grupo de Informática Gráfica Avanzada) en la Universidad de Zaragoza, utilizando las instalaciones del Laboratorio del Instituto de Investigación de Ingenierı́a de Aragón. El estudio del método Monte-Carlo Tree Search plateado pretende analizar las posibilidades del mismo, con objeto de analizar su uso en otras de las ramas de trabajo del grupo. El juego del Go se ha visto como un buen instrumento para la ilustración y comprensión del método. Hasta el momento, el grupo no habı́a realizado ningún estudio previo en este campo, por lo que el código implementado no se apoya en otro anterior. 1.2. Objetivos El objetivo del proyecto es la realización en lenguaje Java de un jugador virtual que sea capaz de enfrentarse en el juego del Go a un jugador humano, aplicando el método MCTS. El proyecto consta de cinco grandes tareas que pasamos a detallar a continuación: 1. Estudio del juego del Go y el uso de la Inteligencia Artificial en él. 2. Estudio del método MCTS y sus diversas variantes. 3. Implementación del juego del Go. 4. Implementación del método MCTS, intentando que dicha implementación sea lo más general posible, de cara a poder utilizarse en otros problemas interesantes para los directores de este proyecto. 5. Implementación de un programa que enfrente al usuario y al ordenador en el juego del Go. El apéndice B de requisitos se explica en más detalle los objetivos de las tareas de implementación. 1.3. Estructura del documento El resto del documento se organiza de la siguiente manera: el capı́tulo 2 presenta el juego del Go; el capı́tulo 3 se explica la implementación realizada de éste; en el capı́tulo 4 se explica el método MCTS; en el capı́tulo 5 la implementación de éste; en el capı́tulo 6 se explica la implementación de la aplicación y el capı́tulo 7 muestra las conclusiones obtenidas. Se incluyen como apéndices: 1. Gestión de proyecto: incluye metodologı́a del desarrollo, fases realizadas, gestión del tiempo y esfuerzos, supervisión y herramientas utilizadas. 2. Requisitos: explica los objetivos de una manera más detallada. 3. Aplicaciones MCTS: explica algunas de las aplicaciones del método MCTS y algunos de sus logros en estos campos. 4. Ejemplo de simulación: explica paso a paso como se desarrolla una simulación MCTS 5. Validación: explica como se ha llevado a cabo la validación y pruebas realizadas 6. Manual de usuario: contiene el manual de usuario de la aplicación Capı́tulo 2 Juego del Go El Go es el juego de mesa estratégico más antiguo del mundo1 . Millones de personas en Oriente juegan al Go, y en Occidente el número de jugadores sigue creciendo. Podrı́a decirse que el Go es tan popular en Oriente como el ajedrez en Occidente. El objetivo del juego es simple: controlar territorio y rodear al enemigo. Famoso por la simplicidad de sus reglas y la complejidad estratégica que este esconde, el Go, se considera un elemento muy importante en la cultura oriental. Hay mucho escrito sobre la historia del Go, su relación con la ciencia, el arte, la filosofı́a y la educación. Numerosos estudios demuestran que su aprendizaje y su práctica facilitan el desarrollo de la inteligencia, pensamiento lógico, creatividad, habilidad para tomar decisiones acertadas, creación de estrategias y muchas otras destrezas. Tanto es ası́ que el Go se enseña en West Point, la Academia militar estadounidense, y en universidades japonesas se permite el ingreso sin examen a los jugadores de Go que acrediten un cierto nivel.[12] En Japón, China, Corea y Taiwán algunos de sus jugadores profesionales gozan de un gran prestigio nacional y ganan importantes sumas de dinero. Debido a la gran importancia de las competiciones de este juego, existen empresas dedicadas exclusivamente a retransmitir y analizar los partidos de Go. El Go además tiene su espacio en la cultura y la ciencia. Aparece en publicaciones (novelas, mangas, artı́culos cientı́ficos y psicológicos...), televisión (series como Andromeda o Mentes criminales, el anime Hikaru no Go ...), e incluso cine (The Go Master, Una mente maravillosa, Tron, The Valiant Ones ...) .[10] Figura 2.1: Imagen de la pelı́cula “Una mente maravillosa” 1 Originado en China hace más de 2500 años 3 4 CAPÍTULO 2. JUEGO DEL GO 2.1. Elementos del juego Para poder jugar se necesitan un tablero, las piedras o piezas y dos jugadores. Figura 2.2: Partida de Go 2.1.1. Tablero El Go se juega sobre un tablero cuadrado formado por una cuadricula de lı́neas horizontales y verticales. El estándar es 19x19, pero se puede jugar con cualquier otro tamaño. Los tamaños más comunes para partidas rápidas suelen ser 9x9 o 13x13. El tamaño preferido por los principiantes es 9x9 ya que suele ser más estimulante al inicio jugar más número de partidas que jugar una partida muy larga. Por simplicidad en los ejemplos se ilustrarán las reglas con tableros pequeños, como puede ser uno de 5x5. Una intersección es un punto donde se cruza una lı́nea horizontal con una lı́nea vertical. En tableros grandes como 19x19 se marcan unos puntos de referencia sobre las intersecciones tal cual se observa en la Figura 2.3. Figura 2.3: Tablero de 19x19 Dos intersecciones se dicen adyacentes si son distintas y están conectadas por una lı́nea horizontal o vertical sin ninguna otra intersección entre ellas. La Figura 2.4 muestra a la izquierda dos imágenes de intersecciones adyacentes y a la derecha una imagen de dos intersecciones no adyacentes. 2.1.2. Piedras Las piedras son las fichas del juego. Cada jugador utiliza las piedras de un color (negro o blanco). Tradicionalmente se juega con 181 piedras negras y 180 piedras, esto es casi siempre más que suficiente, pero si llegasen a faltar podrı́an usarse piedras extra. La forma de las piedras puede apreciarse en la figura 2.5. Las piedras se colocan sobre las intersecciones y una vez colocada una pieza esta no puede moverse. 2.1. ELEMENTOS DEL JUEGO 5 Figura 2.4: Adyacencia de intersecciones. Figura 2.5: Piedras Las piedras verticalmente y horizontalmente adyacentes del mismo color forman un grupo. Para ser adyacentes deben estar conectadas por las lı́neas de la cuadrı́cula directamente, sin otras intersecciones intermedias. La figura 2.6 muestra una situación posible del tablero, donde cada número corresponde a un grupo diferente. Aparecen por tanto, cuatro grupos de piedras negras y cuatro grupos de piedras blancas. Figura 2.6: Grupos de piedras. Se llama libertad de una piedra a una intersección libre adyacente a ella. Un grupo tiene las libertades que tengan todas las piedras que lo conforman. La Tabla 2.1 muestra las libertades que tiene cada grupo de piezas para la situación del tablero reflejada en la Figura 2.7. 2.1.3. Jugadores En Go compiten dos jugadores, llamados Negro y Blanco. El Negro usará piedras de color negro y comenzará la partida. El Blanco usará piedras de color blanco y tendrá una puntuación extra adicional por haber empezado más tarde. Esta puntuación extra es pactada antes del comienzo de la partida y tiene un valor decimal que impide el empate. Si los jugadores tienen distinto grado, el jugador más débil será el Negro. Este podrı́a colocar incluso pre-colocar varias piedras a modo de hándicap antes de que comience el juego para compensar 6 CAPÍTULO 2. JUEGO DEL GO Grupo Libertades 1 c,d,h 2 d,e,f,g,h 3 g,h 4 a,b 5 c 6 d,h 7 f,e Cuadro 2.1: Tabla de libertades para el ejemplo de Figura 2.7 Figura 2.7: Ejemplo de libertades la diferencia de fuerzas. Este hándicap normalmente suele consistir en comenzar la partida precolocando las piedras sobre los puntos de referencia del tablero mencionados en el apartado anterior. Si los jugadores no se ponen de acuerdo acerca de los colores con que jugar, entonces uno cualquiera coge una o varias piedras del montón y el otro jugador tiene que adivinar si el número es “par” o “impar”. Si lo acierta este jugador jugará con piedras negras y en caso de fallar jugará con piedras blancas. 2.2. Reglas La mecánica general del juego es la siguiente, la partida comienza con el tablero vacı́o, primero juegan Negras (jugador con piedras negras) y después se juega alternativamente Blancas y Negras, como se observa en la Figura 2.8. Durante su turno, cada jugador puede colocar una pieza (piedra) o pasar (perder su turno). En competiciones el tiempo por turno esta delimitado y medido con cronómetro. La partida finaliza cuando los dos jugadores pasan consecutivamente, momento en el que se hace el recuento de puntos para ver quien es el ganador. Figura 2.8: Ejemplo de inicio del juego En cuanto a la colocación de una piedra, las piedras se colocan sobre las intersecciones libres del tablero siempre que no incumplan las reglas de suicidio y Ko, las cuales se explicarán más adelante. Además la colocación de una pieza puede tener como efecto la captura de piedras del jugador contrario tal y como se explica a continuación. 2.2.1. Captura Una piedra o grupo de piedras se captura cuando al colocar una piedra del oponente se pierde la última libertad que la piedra o grupo poseı́a, es decir, se queda sin intersecciones adyacentes 2.2. REGLAS 7 libres. La piedra o grupo de piedras capturado se elimina del tablero y se guarda hasta que la partida finalice. Las figuras 2.9 y 2.10 muestran algunos ejemplos de captura. Figura 2.9: Ejemplos de captura La figura 2.9 contiene dos ejemplos en los que se captura una sola piedra blanca al colocar una piedra negra sobre la intersección a. En el ejemplo de la figura 2.10 la piedra colocada, sobre la intersección a, es de color blanco y produce la captura de un grupo formado por cuatro piedras negras. Figura 2.10: Ejemplo de captura 2.2.2. Suicidio No está permitido la colocación de una piedra que suponga la eliminación de libertades de una piedra o grupo de piedras del jugador que tenga el turno, ya que estas piedras morirı́an y supondrı́a un suicidio. La Figura 2.11 muestra un par de ejemplos de situaciones de suicidio, en los que colocar la piedra sobre la intersección a supondrı́a una auto-captura (suicidio) y por lo tanto no es una jugada válida. La excepción, es que en la jugada se capture piedras enemigas, porque quedarı́an intersecciones adyacentes libres y la piedra colocada seguirı́a viva. Esto se puede observar en la Figura 2.12; aparentemente al colocar la piedra negra sobre la intersección a supondrı́a la desaparición del grupo de negras, pero como las libertades del grupo de blancas desaparecerı́an, el jugador Negro es el que captura al grupo de Blancas. 2.2.3. Ko Los jugadores no tienen permitido hacer un movimiento que devuelva al juego a su posición inmediatamente anterior, debido a que crearı́a un ciclo y podrı́a darse una situación de Ko o infinitud. Una vez realizado un movimiento distinto, el jugador podrá realizar el movimiento prohibido anteriormente si se diese la situación. 8 CAPÍTULO 2. JUEGO DEL GO Figura 2.11: Ejemplos de suicidio. Figura 2.12: Ejemplo de captura con falso suicidio La Figura 2.13 ilustra este concepto; inicialmente tenemos una situación del tablero donde la última piedra colocada es blanca distinta a b, seguidamente se coloca una piedra sobre la intersección a. Si el jugador blanco colocase la piedra sobre la intersección b, se volverı́a a la situación inicial, por lo tanto debe colocar su piedra en otro lugar. Después de que juegue el jugador negro si la intersección b está libre, el jugador blanco puede colocar su piedra sobre b. Figura 2.13: Idea de Ko 2.3. Recuento de puntos Una vez finalizada la partida (al pasar los dos jugadores consecutivamente), se toma la situación del tablero en ese momento y se procede al recuento de la puntuación. En la situación final, una intersección vacı́a se dice que pertenece al territorio de un jugador si está conectada solo con piedras de ese jugador (negras/blancas) o con intersecciones vacı́as. Con la excepción de que cuando el tablero está vacı́o las intersecciones no pertenecen a ningún jugador. Cada jugador recibe un punto por intersección vacı́a dentro de su territorio. Veamos un ejemplo, en la Figura 2.14 se muestra la situación final de una partida sobre tablero 9x9. En ella las intersecciones con letra a pertenecen al territorio del jugador negro y las intersecciones con letra b pertenecen al territorio del jugador blanco. La intersección con letra c al estar en contacto con piedras de ambos jugadores no pertenece al territorio de ninguno. La puntuación 2.3. RECUENTO DE PUNTOS 9 de territorios es de 18 para negras y de 14 para blancas. Esta puntuación se utiliza en el cálculo de la puntuación final. Figura 2.14: Territorios Existen dos modos de recuento: el japonés y el chino; ambos emplean los territorios y la compensación que posee el blanco2 . En el japonés se incluye las piedras capturadas y en el chino el número de piedras sobre el tablero. El cuadro 2.2 muestra las fórmulas de recuento de puntos para los jugadores negro y blanco para el sistema japonés y chino. Negro Japonés PtosTerritorioNegro + NºPiedrasBlancasCapturadas Chino PtosTerritorioNegro + NºPiedrasNegrasEnTablero Blanco PtosTerritorioBlanco + NºPiedrasNegrasCapturadas + Compensación PtosTerritorioBlanco + NºPiedrasBlancasEnTablero + Compensación Cuadro 2.2: Fórmulas de recuento de puntos Continuando con el ejemplo de la Figura 2.14, se calcula la puntuación final para cada color según los dos modos de recuento. Se sabe que al inicio de partida se pactó dar 2,5 puntos de compensación al jugador blanco y que durante el transcurso de ella el jugador blanco capturó 3 piedras negras y el negro 2 piedras blancas. Calculando la puntuación final usando las fórmulas anteriores, tal y como muestra la Tabla 2.3, el jugador Negro ganarı́a fuera cual fuera el sistema de puntuación usado para el recuento. Sistema/Jugador Japonés Chino Negro 18+2=20 18+26=44 Blanco 14+3+2,5=19,5 14+22+2,5=38,5 Cuadro 2.3: Puntuaciones finales 2.3.1. Clasificación de los jugadores En Go, el rango de un jugador indica su habilidad en el juego. Los rangos se miden mediante un sistema de grados de kyu y dan, un sistema que también ha sido adoptado por diversas artes marciales. 2 Compensación por haber empezado más tarde, es decimal y se pacta al comienzo de la partida. 10 CAPÍTULO 2. JUEGO DEL GO Los grados de kyu (abreviados k ) son considerados grados de estudiante. Su número disminuye a medida que el nivel de juego aumenta, de modo que el 1er kyu (equivalente a cinturón negro en artes marciales) es el grado de kyu más fuerte. Los grados de dan (abreviados d ) se consideran grados de maestro, y se incrementan de 1er a 7o dan. Los jugadores profesionales obtienen un grado especial de dan, el dan profesional (abreviado p), cuyo máximo grado es el 9o dan. El cuadro 2.4 muestra los rangos del juego, donde 8d y 10p son tı́tulos especiales. Tipo de rango kyu de doble dı́gito kyu de doble dı́gito kyu de un solo dı́gito dan Amateur dan Profesional Rangos 30-21k 20-11k 10-1k 1-7d 1-9p Etapa Principiante Jugador ocasional Intermedio/Jugador de club Jugador experto Profesionales Cuadro 2.4: Rangos del Go 2.4. Complejidad e Inteligencia Artificial El Go plantea un enorme desafı́o para los programadores. Mientras que los programas de ordenador de ajedrez más fuertes derrotan a los mejores jugadores humanos (por ejemplo, el programa Deep Frit en 2006, ejecutándose en un ordenador portátil, batió al campeón mundial sin perder una sola partida), los mejores programas de Go alcanzan solo el nivel de Dan amateur. ¿A qué se debe esto? 1) El número de casillas del tablero es mucho mayor3 ; 2)El colocar una pieza en la fase inicial puede afectar al juego cientos de movimientos más tarde (cosa que no sucede en el ajedrez); 3) No existe forma sencilla de evaluar una posición4 ; 4) Tiene caracterı́sticas que pueden ser leı́das más fácilmente por humanos que por ordenadores.5 Incluso los mejores programas de Go, siempre se ayudan de la paralelización y de ordenadores potentes para poder realizar los cálculos lo más rápidamente posible. Los tableros pequeños de 9x9 dejaron de ser un reto en 2008 cuando el programa MoGo fue capaz de ganar algunas partidas contra jugadores profesionales. Para tableros 19x19 este mismo programa fue capaz de vencer a ciertos jugadores partiendo de la ventaja de 9 de hándicap (máximo permitido), que le permite colocar 9 de sus piezas antes de comenzar la partida. Poco a poco, han ido surgiendo distintos programas que enfrentándose a jugadores profesionales los van venciendo en partidas cada vez con hándicaps menores. En partidas sin hándicap la cosa se complica, el mejor resultado se alcanzó en Marzo de 2012 el nivel obtenido fue de 6 dan (amateur). 3 El número de casillas del Go es de 361 en contraste con 64 del ajedrez; siendo el número de movimientos permitidos por turno muy alto, y también las combinaciones posibles. Adelantarse ocho movimientos supondrı́a 512 quintillones de combinaciones posibles (5 dı́as en los ordenadores más potentes). 4 En los juegos basados en captura (como ajedrez), normalmente una posición puede ser evaluada relativamente temprano calculando quien tiene una ventaja material o más piezas activas. El Go es una excepción. 5 Aunque no hay rigurosas evidencias que garanticen esta hipótesis, parece que los rasgos que tiene el Go, hacen más fácil para los humanos la “lectura” (predecir posibles variaciones) de largas secuencias de movimientos, resultando irrelevantes para un programa de ordenador. Capı́tulo 3 Implementación del juego del Go La solución implementada además de las funcionalidades básicas del juego (poner pieza, pasar, obtener resultados), presenta unas funciones que permiten definir ciertos valores (tamaño, tipo de recuento, penalización) antes de que se inicialice el juego. Si no se llamada a estas funciones, el juego Go creado posee los valores por defecto. En este bloque se presentan las clases implementadas, los estados del juego, las ideas generales de implementación de las reglas y el sistema de bloques que implementa los grupos. 3.1. Las clases La figura 3.1 presenta el diagrama de clase del juego Go implementado. La importancia en el juego del concepto de grupo da lugar a dos clases llamadas Bloques y ConjBloques. Las reglas del juego se controlan en la clase Tablero y las cuestiones más generales en la clase Go. La clase puntuaciónGo se emplea simplemente como registro para almacenar el recuento de puntos. Figura 3.1: Diagrama de clases del Go 11 12 CAPÍTULO 3. IMPLEMENTACIÓN DEL JUEGO DEL GO 3.2. El Go y el usuario La clase Go se encarga de interactuar con el usuario, permitiéndole: cambiar las condiciones del juego, jugar (colocando pieza o pasando) y obtener el resultado. Como es lógico, no se podrá obtener el resultado si aun no ha finalizado la partida, o cambiar las condiciones del juego una vez comenzada esta. Podemos decir entonces que una partida de Go se encuentra en distintos estados, según las acciones realizadas en él. Las acciones principales que suponen el paso de un estado a otro son: 1) ColocarPieza(x,y) que coloca una piedra en la intersección pasada por argumento, 2) Pasar() que pasa el turno y 3) NuevaPartida() que vacı́a el tablero y da turno al jugador negro para comenzar una nueva partida. El turno es otro tema importante. Las acciones de Pasar() o ColocarPieza(x,y) se aplican a un jugador según sea su turno. En la implementación se ha controlado que no se produzca un paso de turno cuando la acción no sea válida y que se asignen las piedras capturadas a un jugador u otro según corresponda el turno. La Figura 3.2 muestra un diagrama con los distintos estados del juego según las acciones realizadas en cada momento. En el diagrama se pueden apreciar claramente las tres zonas de estados que se dan en el juego: Figura 3.2: Diagrama de estados del Go 1. Inicio: En este estado es posible cambiar las condiciones iniciales. Desde él, se pasa al estado “Pieza colocada” si se realizan las acciones ColocarP ieza(x, y) o N uevaP artida(); o al estado “Pasar” si se realiza la acción P asar(); al realizar cualquier otra acción se permanece en el estado de “Inicio”. 2. Juego: Es la zona central del diagrama, compuesta por dos estados: “Pieza colocada” y “Pasado”. El estado “Pieza colocada” indica que la última acción válida1 ha sido la colocación de una pieza, y el estado “Pasado” indica que la última acción válida ha sido pasar. El paso de unos estados a otros corresponde con estas ideas, aunque se pasará al estado “Acabada” cuando se llame a P asar() desde el estado “Pasado”, que corresponderá con el fin de la partida.2 1 Corresponde a una jugada válida. Por ejemplo, si se intenta colocar la piedra en una posición no correcta, se indica que ésta no es válida pero se mantiene en el estado actual, ya sea “Pieza colocada” o “Pasado”. 2 Una partida finaliza cuando se pasa dos veces consecutivas. 3.3. EL TABLERO Y LAS REGLAS DEL JUEGO 13 3. Acabada: En este estado la partida ya ha acabado y es posible obtener los resultados de ésta. Si se llama a N uevaP artida() se volverá al estado de “Pieza colocada” descrito anteriormente. 3.3. El Tablero y las Reglas del juego La clase Tablero es la clase central del juego, contiene la información de la posición del tablero además de los grupos que existen dentro de él. Se encarga de controlar todo el proceso de colocación de pieza, captura, suicidio y Ko. Podemos decir que es, en sı́, el cuerpo del juego. Sus únicos componentes son: Una matriz de juego: Es una matriz cuadrada de enteros que representa el tablero real del juego. Según el valor del entero se indica que la intersección o posición está libre u ocupada por una piedra de un color. La figura 3.3 muestra la matriz de juego para una situación concreta del tablero, en la implementación realizada el valor 0 corresponde a la intersección vacı́a, 1 a la piedra negra y 2 a la piedra blanca . Figura 3.3: Matriz del juego. Una matriz estado anterior : que no es más que una matriz de las mismas caracterı́sticas que la anterior, que guarda el estado anterior del tablero y se utiliza para poder satisfacer la regla del Ko. Un conjunto de bloques: que guarda todos los bloques del tablero. Este conjunto de bloques debe actualizarse cada vez que se realice una modificación sobre la matriz anterior para ser coherente con el juego y es muy útil a la hora de comprobar la posibilidad de colocación de una pieza, captura, suicidio y en sı́ todas las acciones que necesiten comprobar las libertades. Esta clase se explica en el apartado 3.4. 3.3.1. Libertad del bloque En muchas ocasiones necesitamos saber si un bloque es libre o no. Por ello la función BloqueLibre, a partir de una posición del tablero, mira si el bloque de esa piedra es libre. Para ello va comprobando para cada una de las posiciones que lo componen si alguna tiene una intersección adyacente libre hasta encontrar alguna. Si encuentra alguna el bloque completo será libre y sino, no lo será. 3.3.2. Validez de una jugada La función de JugadaVálida comprueba si de acuerdo a las reglas del Go es posible colocar la pieza o no. Devuelve un entero en vez de un booleano para ası́ poder precisar si el motivo de que 14 CAPÍTULO 3. IMPLEMENTACIÓN DEL JUEGO DEL GO la jugada no sea válida es que es un suicidio o es Ko. El algoritmo 3.1 muestra el pseudocódigo de esta función. Algoritmo 3.1 Pseudo-código de Jugada válida Datos: fila, columna, color Resultado: entero /* ¿Está dentro del tablero?*/ si (!DentroTablero(fila,columna)) devuelve FALSE; FinSi /* ¿Está libre?*/ si (!EstaLibre(fila,columna)) devuelve FALSE; FinSi /* ¿Es suicidio?*/ si (EsSuicidio(fila,columna,color)) devuelve SUICIDIO; FinSi /* ¿Es Ko?*/ si (EsKo(fila,columna,color)) devuelve KO; FinSi /* Todo correcto */ devuelve TRUE; Suicidio: Para comprobar si es suicidio o no, primero se coloca temporalmente la piedra en la matriz de juego, pero no en el conjunto de grupos y antes de devolver la solución se vuelve a dejar la casilla vacı́a. Esto permite comprobar de forma sencilla las consecuencias que tendrı́a esta jugada. Primero se comprueba si mata a otros, en caso afirmativo no serı́a suicidio. Segundo, en el caso de no matar a otros, se comprueba si tiene libertad. En caso de no tener libertad estarı́amos en un suicidio. Para comprobar si tiene libertad lo que se hace es mirar si alguna de sus intersecciones adyacentes es libre o si alguno de sus bloques adyacentes es libre. Ko: Para comprobar si se da la situación de Ko, se coloca la pieza en el tablero (trabajando sobre una copia) y si el tablero de ésta coincide con la matriz de estado anterior tendremos una situación de Ko y la jugada no será valida. 3.3.3. Colocación de una pieza La función ColocarPieza(x,y) tiene como precondición que la jugada sea válida y realiza las acciones correspondientes a la colocación de una pieza: 1. Actualización de los tableros: Copia la matriz de juego sobre la matriz de estado anterior, y actualiza sobre la matriz de juego la posición correspondiente con el tipo de piedra dado. 2. Unión de la pieza al conjunto de bloques: Comprueba si los bloques adyacentes son del mismo tipo y en función de ello crea un bloque nuevo, se une a uno ya existente o fusiona varios si se encuentra en la posición de unión. En la figura 3.4 se pueden observar las situaciones posibles cuando es turno de blancas. Colocando la piedra blanca en la posición a, se crearı́a un bloque nuevo, colocándola en la posición b se unirı́a a la piedra blanca de abajo, colocándola en la posición c unirı́a los bloques izquierdo y derecho y colocándola en la posición d unirı́a el bloque de abajo y el de su derecha. 3. Captura: Finalmente se comprueba si se captura alguno de los grupos del oponente, viendo si en las posiciones adyacentes hay bloques no libres. En caso afirmativo, se eliminan del conjunto de bloques los bloques capturados, poniendo las casillas correspondientes como libres y devuelve el recuento de las piezas capturadas. 3.4. LOS BLOQUES 15 Figura 3.4: Unión de la pieza al conjunto de bloques 3.3.4. Recuento de territorios Para el recuento de territorios lo primero que se hace es crear bloques con los grupos de intersecciones libres conectados entre si y luego para cada uno de ellos se comprueba si están rodeados por piedras de un solo color o ambas. En función del resultado se sumarán o no a la puntuación de cada color. La clase PuntuacionGo es un registro que permite que se devuelvan los valores de los dos colores usando una única función. 3.4. Los Bloques En el juego del Go, los grupos formados por la conexión entre piedras juegan un papel fundamental, por ello, se han implementado unas clases particulares que los gestionen. En este apartado primero se explica la estructura usada para la gestión de los bloques, profundizando en cada una de las clases y posteriormente el funcionamiento de algunas de las operaciones llevadas a cabo con los bloques. 3.4.1. La estructura La gestión de los bloques es una tarea complicada. Para cada una de las acciones propuestas por el usuario no se debe recalcular todos los grupos, sino que se necesita un registro que pueda almacenarlos y conservarlos. La clase implementada además permite acceder rápidamente al grupo de cada pieza y se usa para realizar comprobaciones de libertad de grupos. Se han implementado dos clases, una clase Bloques, que representa en si un grupo de tablero y una clase ConjBloques que almacena todos los grupos o bloques existentes y se encarga de gestionarlos eficientemente. Veamos en detalle en que consiste cada una de ellas: Bloques: Esta clase representa un grupo del tablero. De forma que un bloque contiene todas las posiciones (x,y) que ocupan las piedras que forman el grupo, podemos ver un ejemplo en la figura 3.5. ConjBloques: Esta clase se apoya en la clase anterior para gestionar todos los bloques que hay sobre el tablero. Está formada por los siguientes elementos: Un vector de bloques: Es un vector que contiene todos los bloques o grupos que hay sobre el tablero. Una matriz de bloques: Es una matriz del mismo tamaño que la matriz de juego donde cada uno de sus elementos indica la posición que ocupa el bloque de esa pieza en el vector de bloques. Si una posición concreta no pertenece a ningún grupo, es que la casilla está vacı́a y se marca con -1. Para comprenderlo mejor fijémonos en la Figura 3.6, donde las piedras conectadas entre si poseen el mismo valor en la matriz de bloques 16 CAPÍTULO 3. IMPLEMENTACIÓN DEL JUEGO DEL GO Figura 3.5: Un bloque representa un grupo de piedras del tablero Figura 3.6: Estructura de almacenamiento de los grupos de piezas ya que pertenecen al mismo grupo. La interconexión entre la matriz de bloques y el vector de bloques es lo que da rapidez al sistema a cambio de necesitar un trabajo de mantenimiento. 3.4.2. Las operaciones Debido a la simplicidad de los métodos de la clase bloques (añadir una piedra al bloque, comprobar si una piedra está dentro de él u obtener la piedra que ocupa la posición i del bloque), nos vamos a centrar en las operaciones de la clase ConjBloques. Dentro de la clase ConjBloques vamos a ver las acciones que modifican la información de los bloques, y por tanto necesitan una gestión que mantenga la consistencia de la estructura: Figura 3.7: Crear Bloque Crear bloque: Crea un nuevo bloque con la posición dada, lo añade al final del vector de bloques y actualiza la matriz de bloques con el valor correspondiente. La figura 3.7 ilustra 3.4. LOS BLOQUES 17 con un ejemplo de colocación de una piedra blanca sobre la posición 0,2 partiendo de la figura anterior. Añadir a bloque: A partir de una posición y un ı́ndice del bloque, busca el bloque con este ı́ndice y añade la posición dada a éste, luego actualiza la matriz de bloques con el ı́ndice del bloque. La figura 3.8 muestra el efecto de colocar una piedra negra sobre la posición 1,3 partiendo de la figura anterior. Figura 3.8: Añadir a Bloque Eliminación de bloque: A partir del ı́ndice del bloque, se elimina éste del conjunto de bloques y se actualizan los valores de la matriz de bloques. La actualización consiste en poner como vacı́as todas las posiciones que tengan como valor el ı́ndice del bloque y decrementar en una unidad todas cuyos ı́ndices sean superiores al ı́ndice del bloque eliminado. La figura 3.9 muestra el ejemplo de eliminación del bloque 7 partiendo de la figura anterior. Observamos que el bloque 8 al tener un ı́ndice superior a 7 se decrementa su ı́ndice en la matriz de bloques. Figura 3.9: Eliminación de un bloque 18 CAPÍTULO 3. IMPLEMENTACIÓN DEL JUEGO DEL GO Fusión de bloques: Fusiona el bloque i con el bloque j, siendo estos distintos. Es decir, copia los elementos del bloque j sobre el bloque i, elimina el bloque j y actualiza los valores de la matriz de bloques. En esta matriz se decrementan en una unidad los valores que sean mayores que j, se actualizan los valores de j a i (si i<j) o a i-1 (si i>j). La figura 3.10 muestra el paso de colocar una piedra negra sobre la posición 0,2 partiendo de la figura anterior. Esta piedra será el punto de unión entre los bloques 0 y 2. Como primer paso, se añade al primer bloque (bloque 0) y como segundo se realiza la fusión entre los bloques 0 y 2. Depende como llamemos a la función tenemos los dos casos explicados. En el primero con i = 0 < j = 2, la fusión se realiza primero añadiendo los elementos del bloque 2 al bloque 0, segundo eliminando el bloque 2 del vector de bloques y finalmente actualizando los valores de la matriz de bloques de los bloques con ı́ndice mayor o igual a dos. Para i = 2 > j = 0, la fusión se realiza primero añadiendo los elementos del bloque 0 al bloque 2, segundo eliminando el bloque 0 del vector de bloques y finalmente actualizando los valores de la matriz de bloques de los bloques con ı́ndice mayor o igual a cero, es decir, todos los bloques no vacı́os. Al ser i>j el bloque resultante pasa a tener ı́ndice 1 en vez de ı́ndice 2. Figura 3.10: Fusión de bloques Capı́tulo 4 Algoritmo MCTS Monte-Carlo Tree Search (MCTS) es el primer método de búsqueda que no requiere una función de evaluación de posición[7, 8], en contraste con la búsqueda αβ[6] . Esta basado en una exploración aleatoria del espacio de búsqueda, pero usa los resultados de previas exploraciones. Para ello MCTS construye gradualmente un árbol en memoria, que mejora sucesivamente estimando los valores de los movimientos más prometedores. MCTS es aplicable si al menos se satisfacen estas tres condiciones: 1) La puntuación del juego está acotada; 2) Las reglas son conocidas (información completa[18]) y 3) Las simulaciones terminan relativamente rápido (la longitud del juego es limitada). Gracias a la estructura de árbol y un alto número de simulaciones aleatorias, el método MCTS puede estimar a largo plazo el potencial de cada movimiento. La técnica MCTS se ha incorporado recientemente en algoritmos para juegos, obteniendo bastantes buenos resultados. Se utiliza en: Problemas de gestión, optimización de rendimiento en bibliotecas, SameGame, Morpion Solitario, Dominio de Navegación, El juego de las amazonas, Lines of Action (LoA), Damas chinas, Colonos del Catán, Juegos de propósito general, y en particular, el Go. Desde un punto de vista más global, el MCTS es también atractivo para muchos más dominios en los que se necesita mejorar el “atasco en la adquisición de conocimiento”. Los detalles de las aplicaciones del algoritmo y los logros mejorados se explican con más detalle en el apéndice C. En esta sección se presentan la estructura del árbol y las cuatro etapas principales del MCTS: selección, expansión, simulación y retropropagación. Cada etapa tiene asociada una estrategia, implementada con una polı́tica especı́fica. El apéndice D muestra con detalle un ejemplo de simulación para el juego del Go, en el que se puede seguir visualmente cada una de las fases con objeto de facilitar la comprensión del mismo. 4.1. Estructura Una partida se representa como un árbol, en la que cada nodo corresponde a un estado particular. El nodo raı́z representa la posición de inicio de partida. Los hijos de cada nodo son estados alcanzables en un movimiento. En un árbol MCTS cada nodo i representa una posición alcanzada (también llamado estado) de una partida. Un nodo contiene al menos las siguientes informaciones: vi es el valor actual de la posición, dependiendo el problema representará una cosa u otra. ni es el contador de visitas que ha sufrido esa posición. Ci es el contenido asociado al problema concreto en el que estemos trabajando, que representa un movimiento realizado desde el estado del nodo padre. Por ejemplo para el juego del Go, cada contenido Ci representa una jugada (colocación de piedra en una intersección concreta o pasar), vi el número de partidas ganadas desde ese nodo. 19 20 CAPÍTULO 4. ALGORITMO MCTS Figura 4.1: Estructura MCTS 4.2. El algoritmo MCTS consiste en cuatro pasos principales, repetidos tantas veces como tiempo disponible haya. En una de las iteraciones se parte de la situación inicial de la partida (situación de la partida en el momento de la simulación), pero se conserva el árbol MCTS, completándose durante las distintas fases y simulaciones. Figura 4.2: Esquema general MCTS Las fases del algoritmo son las siguientes: Selección: El árbol se recorre desde el nodo raı́z hasta alcanzar un nodo hoja. Expansión: Se añaden nodos al árbol MCTS según una estrategia de expansión. Simulación: Se realiza una partida simulada partiendo del nodo o estado alcanzado en las fases anteriores. Durante esta partida simulada, el programa juega solo, realizando los movimientos de todos los jugadores que intervienen hasta que la partida finalice y se obtenga un resultado, con el que actualizará los valores del nodo. Retropropagación: El resultado de la simulación se propaga hacia los nodos atravesados previamente. Cuando el tiempo o número de simulaciones haya finalizado, el movimiento elegido en el programa será el más prometedor teniendo en cuenta la información almacenada. El pseudocódigo del MCTS se muestra en el Algoritmo 4.1. En éste, A es el árbol que contiene todos los nodos del árbol de búsqueda. Seleccionar(N odoN ) es el procedimiento que devuelve un hijo del nodo N . Expandir(N odoN ) es el procedimiento que añade según las estrategia de expansión los nodos al árbol, devolviendo el nodo desde el que realizar la simulación. JugarP artidaSimulada(N odoN ) es el procedimiento que realiza una simulación de la partida desde el nodo devuelto en la expansión y devuelve un resultado R. Retropropagación(IntegerR) 4.3. LAS FASES 21 Algoritmo 4.1 Pseudocódigo del MCTS Datos: nodoRaiz Resultado: mejorMovimiento MientrasQue (haya_tiempo) hacer nodoActual ←nodoRaiz /* Selección */ MientrasQue (nodoActual ∈ A)hacer nodoActual ←Seleccionar(nodoActual) Fin /* Expansión del nodo */ nodoActual ←Expandir(nodoActual) /* Simulación de una partida*/ R ←JugarP artidaSimulada(nodoActual) /* Retropropagación del resultado */ MientraQue(nodoActual ∈ A)hacer Retropropagación(nodoActual, R) nodoActual =nodoActual.padre Fin Fin Devuelve mejorMovimiento =M ejorHijo(nodoRaiz) es el procedimiento que actualiza el valor del nodo dependiendo del resultado R de la última partida simulada. M ejorHijo(N odoN ) devuelve el hijo más prometedor según los valores de estos. En los siguientes apartados se explica detalladamente cada una de las fases y la selección del movimiento final. 4.3. Las fases Como hemos visto, el método MCTS repite una serie de pasos o fases hasta llegar a un número de simulaciones o tiempo dado. En este apartado, analizaremos cada una de las fases ası́ como distintas estrategias a seguir en cada una de ellas. La explotación y exploración del espacio de búsqueda son elementos clave de cualquier método de búsqueda y optimización. Mientras la explotación guı́a la búsqueda hacia las mejores soluciones encontradas hasta el momento, la exploración favorece el descubrimiento de regiones sin explorar y evita una convergencia antes de tiempo. Lograr un balance entre estos dos objetivos es un problema de vital importancia que enfrentan la mayorı́a de las técnicas de búsqueda y optimización actuales. 4.3.1. Selección Figura 4.3: Selección 22 CAPÍTULO 4. ALGORITMO MCTS En la fase de selección, se avanza desde la raı́z del árbol hasta alcanzar un nodo hoja tal y como muestra la Figura 4.3. Se toma una rama u otra dependiendo de la estrategia de selección que se emplee y la información almacenada en el nodo en ese momento, como el valor y el número de visitas. A continuación se detallan algunas de estas estrategias: OMC (Objective Monte-Carlo): Donde se calcula la urgencia 1 de cada uno de los movimientos (nodos) posibles y se juega un movimiento u otro según los valores de urgencia calculados y el número de visitas realizadas. PBBM (Probability to be Better than Best Move): Similar a la anterior, pero tiene en cuenta la desviación tı́pica[22] del mejor movimiento a la hora de calcular la urgencia. UCT (Upper Confidence bounds apllied to Trees): Es la estrategia más usada y ha dado lugar a diversas variantes. La estrategia UCT calcula para cada uno de los movimientos posibles una combinación de dos valores, la tasa de éxito de ese nodo y un número asociado a la relación del número de veces que se ha visitado el nodo en relación a un nodo padre. El valor de la tasa de éxito está relacionado con la explotación y el valor del número asociado esta relacionado con la exploración. Dependiendo del coeficiente empleado en la combinación de ambos valores, se puede dar mayor prioridad a la explotación o a la exploración. Todas estas estrategias de selección, son independientes del juego y no usan ningún dominio del conocimiento. La estrategia UCT es una de las más usadas debido a su simplicidad y eficiencia. Por ello, es la que se ha usado en la implementación realizada. 4.3.2. Expansión El paso de expansión añade nodos al árbol MCTS. En la mayorı́a de los problemas en los que no es posible almacenar en memoria el juego completo es necesario poseer una estrategia de expansión. Según cuando se expande podemos encontrar estas dos estrategias: Siempre: Se expande sea cual sea las veces visitadas Al alcanzar un nº de visitas: Se expande solo cuando se alcanza un número mı́nimo M IN de visitas ni . Figura 4.4: Modelo de expansión La no expansión hasta que no se alcance un número mı́nimo de simulaciones, permite ahorrar espacio en memoria, pudiendo evitar en muchos casos crear ramas innecesarias. El nodo raı́z se trata como un caso especial, al reflejar la situación de partida no es útil realizar simulaciones directamente sobre él, por lo que siempre se expande. La Figura 4.4 muestra el esquema en donde 1 Es un valor proporcional a la probabilidad de que un movimiento sea mejor al actual mejor movimiento[1] 4.3. LAS FASES 23 el nodo hoja Ni solo se expande si el número de visitas ni alcanza un mı́nimo M IN . En el caso de expandirse, puede crear un solo hijo o todos ellos tal y como explicamos a continuación. Según el número de hijos a expandir se tienen estas dos estrategias: Crear un solo hijo: Ocupa menos memoria, pero durante cada iteración del proceso de selección se deberá calcular si hay más movimientos posibles que partan de ese nodo y no han sido añadidos, lo que supone una carga de procesado considerable. Crear todos los hijos de golpe: Ocupa más espacio en memoria, pero solo se calculan todos los movimientos posibles alcanzables desde el nodo actual una vez. En este caso se debe seleccionar un nodo cualquiera de los creados, desde el cual se realizará la simulación. En la implementación realizada se ha decidido expandir todos los nodos de golpe cuando se haya visitado el nodo un número mı́nimo de veces. 4.3.3. Simulación A partir del nodo hoja Ni dado por la fase anterior, se realiza una partida simulada. Durante esta partida simulada, el programa juega solo, realizando movimientos de todos los jugadores que intervienen de forma aleatoria hasta que la partida finalice y obtenga un resultado R. Podemos ver este proceso en la Figura 4.5. Figura 4.5: Actualización de valores Las estrategias que se utilizan consisten o bien utilizar los movimientos aleatorios o combinar la aleatoriedad con una heurı́stica asociada al problema concreto. En estos casos es necesario buscar un equilibrio entre la exploración, que da la aleatoriedad, y la explotación, que dirige hacia un movimiento más prometedor. Debido a que se desea generar un algoritmo MCTS genérico independiente del problema, se ha decidido utilizar la estrategia aleatoria. 4.3.4. Retropropagación En el paso de Retropropagación se realiza la actualización de los valores de los nodos, actualizando primero el nodo hoja, luego el nodo padre de éste y ası́ consecutivamente hasta alcanzar la raı́z del árbol, tal y como muestra la Figura 4.6. La actualización de cada nodo, consiste en incrementar en una unidad el número de visitas ni y actualizar su valor vi usando el resultado R de la simulación. Veamos distintas estrategias existentes de actualización del valor vi de un nodo: Simples: Se actualiza en función únicamente del resultado obtenido. Max: Adquiere el valor máximo de sus hijos. Media: Adquiere la media de sus valores hijos. 24 CAPÍTULO 4. ALGORITMO MCTS Figura 4.6: Retropropagación Mezcla: Combina las estrategias de valor máximo y media. MCTS-Solver: Considera a un nodo ganador si alguno de sus hijos lo es y perdedor si todos sus hijos lo son. En este proyecto se ha seleccionado el método “Simple”, dadas las caracterı́sticas del problema seleccionado, el juego del Go. 4.4. Selección del movimiento final Después de las simulaciones, es el momento de elegir el mejor movimiento a realizar, la elección vendrá dada por el “mejor hijo” de la raı́z. Hay distintas formas de elegir qué hijo es el mejor: 1. Valor máximo: Es el hijo que tenga el mayor valor vi . 2. Más robusto: Es el hijo que tiene un mayor contador de visitas ni . 3. Robusto-Valor máximo: Es el hijo que tiene tanto el mayor valor vi , como el número de visitas ni . 4. Más seguro: Es el hijo que maximiza un lı́mite inferior del intervalo de confianza[23, 1]. Según el problema puede ser más conveniente usar un método u otro. Experimentos aplicados al Go relacionados por expertos con los distintos métodos muestran que no hay una diferencia significativa entre ellos si hay un suficiente número de simulaciones por movimiento jugado. Sin embargo, si el tiempo de simulación por movimiento es corto (ej. 1 seg), la elección por Valor máximo da unos resultados significativamente peores que el resto de los métodos. La selección elegida en este proyecto ha sido la de “Más robustez ”, porque su simplicidad de implementación, menor consumo de tiempo y por presentar mismas prestaciones que otros métodos al aplicarse al juego del Go. Capı́tulo 5 Implementación del método MCTS En esta sección se explica la solución final desarrollada. Recordemos que uno de los objetivos era que el modulo del método MCTS a implementar fuese genérico, de forma que pudiese aplicarse a distintos problemas, no solo al juego del Go. Si se quiere conocer en más detalle como ha sido la evolución seguida en la implementación del método, en el apéndice A se describe la metodologı́a seguida y los grandes pasos dados antes de llegar a la solución final. 5.1. Las clases La Figura 5.1 muestra el diagrama de clases MCTS del método MCTS implementado. Veamos más a fondo cada una de las clases, sin entrar en detalle en la clase Go ya explicada en la sección anterior. 5.1.1. NodoUCT Esta clase representa un nodo del árbol MCTS. Con la referencia al nodo padre y a los nodos hijos que el nodo posee se consigue la estructura del árbol MCTS necesaria para realizar las simulaciones. Este nodo, es un nodo genérico y debe instanciarse en el momento de su creación, tanto el tipo de contenido (asociado a las acciones o movimientos del problema a resolver) como el tipo de valor (que debe ser de tipo numérico y se usará en las distintas fases del método). La figura 5.2 muestra la representación gráfica del nodo que implementa la clase. 5.1.2. Contenido La clase Contenido, ilustrada por la figura 5.3, no es más que una estructura con la que se instanciará al nodo del árbol MCTS y que representa una acción asociada al juego del Go: Pasar o colocar una pieza en una posición concreta. Esta estructura está formada por un booleano que indica si la acción es pasar (en caso de ser el booleano cierto) o colocar una pieza (en caso de ser booleano falso) y por dos valores enteros (x,y) que indican donde la pieza seria colocada. El tipo valor en el caso del juego del Go representa el número de partidas ganadas (representadas por un entero). Por lo que el nodo se instancia con el tipo entero para el tipoValor y con el tipo Contenido para el tipoContenido. 25 26 CAPÍTULO 5. IMPLEMENTACIÓN DEL MÉTODO MCTS Figura 5.1: Diagrama clases MCTS Figura 5.2: Representación gráfica del nodo 5.1.3. SimulaciónUCT En el capı́tulo 4 se explicó el algoritmo MCTS, sus principales estrategias en las distintas fases y las opciones elegidas. El cuadro 5.1 muestra una recapitulación de estas estrategias y las soluciones elegidas. Las estrategias elegidas son: UCT para la fase de selección, expandir creando todos los nodos al alcanzar un número mı́nimo de visitas en la fase de expansión, actualizar los valores de los nodos usando solo el resultado proporcionado por la simulación o nodos anteriores en la fase de retro-propagación y usar la estrategia de robustez para la selección del movimiento final a realizar. La solución implementada presenta unas funciones que permiten definir el valor del coeficiente UCT y nº de simulaciones antes de expandir. Si no se llama a estas funciones se usan los valores por defecto. Debido a que se pretende dar al método un carácter general para que pueda utilizarse en distintos problemas, se han creado un número importante de funciones abstractas. Estas funciones se deben implementar en las clases hijas (en nuestro caso en la clase SimulacionUCTGo) y deben implementar la funcionalidad que se requiera asociada al problema que quiera resolver (en nuestro caso es el juego del Go). Estas funciones suelen ser bastante simples, pero son de gran importancia. 5.1. LAS CLASES 27 Figura 5.3: Contenido del nodo para el juego del Go Selección Expansión Simulación Retropropagación Movimiento final Estrategias - OMC - PBBM - UCT - UCB-TUNED ¿Cúando? - Siempre - Al alcanzar un nº min de visitas ¿Cuánto? - Hijo por juego simulado - Todos los hijos de golpe - Movimientos aleatorios - Movimientos pseudo-aleatorios - Simples - Max - Media - Mix - MCTS-Solver - Valor máximo - Más robusto - Robusto-Valor máximo - Más seguro Elegido UCT Al alcanzar un nº min de visitas. Crear todos los hijos de golpe. Aleatorios Simple Más robusto Cuadro 5.1: Recapitulación de soluciones elegidas Veamos ahora con más detalle la implementación de cada una de las cuatro fases del método: Selección: El algoritmo UCT que sirve para seleccionar un nodo u otro tiene en cuenta una tasa de éxito del nodo y un número relacionado con el número de visitas. Ambos valores tendrán como valor mı́nimo cero. En cuanto al cálculo de la tasa de éxito, dependiendo del problema, se pueden considerar más favorables unos valores u otros, por lo que no hay una forma general de calcularla. La figura 5.4 muestra algunos ejemplos de casos posibles y sus correspondientes implementaciones de la función que calcula la tasa de éxito. Expansión: Como ya se ha dicho, el nodo se expande solo al alcanzar un número mı́nimo de visitas (número definido antes de que comience la primera iteración). Veamos como se lleva a cabo esta expansión. Tal y como muestra la figura 5.5, se añaden solo los movimientos (contenidos) que sean válidos a partir del estado actual. Para ello se crea una función abstracta que devuelve las posibles acciones en una lista de contenidos. Se crearán tantos nodos hijos como contenidos haya devuelto esta función, poniéndose el contador de visitadas a 0 y el valor del nodo con un valor numérico inicial (indicado también por otra función abstracta). Se tomará uno de ellos de manera aleatoria para continuar con la fase de simulación si el nodo no se ha expandido. 28 CAPÍTULO 5. IMPLEMENTACIÓN DEL MÉTODO MCTS Figura 5.4: Ejemplos de implementación de la función TasaExito Figura 5.5: Expansión implementada Simulación: La fase de simulación consiste en realizar una simulación aleatoria para obtener un resultado. El algoritmo 5.1 muestra el pseudocódigo de la simulación aleatoria, las cuatro funciones que aparecen en él son abstractas ya que dependen del problema concreto. Se ha incluido la función de inicio de la simulación, ya que, en ocasiones es necesario realizar algunas inicializaciones o almacenar cierta información para la obtención correcta del resultado (por ejemplo el turno en el caso del Go). Algoritmo 5.1 Pseudo-código Simulación Aleatoria Resultado: tipoValor InicioSimulacionAleatoria(); MientrasQue (NoAcabadaSimulacion()) hacer RealizarAccionAleatoriaEnSimulación(); Fin Devuelve Resultado(); Retropropagación: Consiste en propagar el resultado obtenido en la fase de simulación, desde el nodo hoja hasta la raı́z del árbol. Para ello deberemos actualizar el contenido de los nodos: Incrementando en uno el contador de visitas y actualizando el valor de éste. El nuevo valor será calculado en una función abstracta y dependerá del problema que se esté resolviendo, del resultado obtenido en la simulación y del valor anterior del nodo, tal y como muestra la figura 5.6. Además el valor propagado al nodo padre puede variar también dependiendo del problema, por lo se usará una función abstracta para que indique cuál es el valor. La propagación se realiza de la manera ilustrada en la figura 5.7. 5.1. LAS CLASES 29 Figura 5.6: Actualización del nodo Figura 5.7: Propagación del resultado Al finalizar una iteración del método se vuelve a la posición inicial del problema, al depender de éste se implementa en la clase hija. Es necesario que las iteraciones no se repitan infinitamente, por lo tanto se han implementado dos formas distintas de controlar esto. La primera, fijando el número de simulaciones a uno concreto, y la segunda limitando el tiempo. Esta segunda, ha sido implementada mediante un thread que se destruye al pasar el tiempo fijado. Como mejor hijo, tal y como se ha explicado en la parte teórica, se toma el hijo con mayor número de visitas. 5.1.4. SimulacionUCTGo Esta clase contiene todo lo necesario para poder aplicar el método MCTS al juego del Go. Para ello, almacena la situación de partida del juego (Go inicial), una partida donde realizará las simulaciones y un entero que guarda el turno antes de comenzar las simulaciones (cuya utilidad describiremos más adelante). La clase además implementa todas las funciones abstractas de la clase SimulacionUCT, veamos a continuación el contenido de éstas según la fase en la que intervienen: Selección: La función que calcula la tasa de éxito es simplemente una división entre el número de partidas ganadas (valor del nodo) y en número de partidas simuladas (visitadas). Expansión: Para devolver el vector con las acciones posibles, mira si es posible colocar la pieza en cada una de las posiciones del tablero; cuando lo es añade la acción al vector de acciones, la acción Pasar siempre es posible, por lo que se añade también al vector. En cuanto el valor inicial para los nuevos nodos creados, se pone que es 0, ya que representa el número de partidas ganadas hasta el momento. Simulación: La simulación consiste en realizar jugadas válidas aleatorias sobre el tablero hasta que la partida finalice. La figura 5.8 muestra un ejemplo de simulación aleatoria para 30 CAPÍTULO 5. IMPLEMENTACIÓN DEL MÉTODO MCTS una partida de Go sobre tablero 3x3, donde la situación inicial de la simulación es el tablero con una piedra negra colocada. Figura 5.8: Ejemplo de simulación aleatoria La función resultado devuelve 1 (cierto) si el jugador que tenı́a el turno antes de comenzar la simulación ha ganado (en el ej. si es negro) o 0 (false) si ha perdido. Pero esto solo lo podemos saber si hemos guardado antes este valor en la función de inicialización de la simulación. El atributo de la clase turno antes simulación aleatoria almacena este valor para poderse usar en la función resultado. Retropropagación: Como el valor del nodo representa el número de partidas ganadas, se incrementa en una unidad este valor si la partida ha sido ganada o no se incrementa si la partida se ha perdido. En la estructura del árbol cada nivel representa un movimiento de piedras de un color, alternando negras y blancas, por lo que si un hijo pierde la simulación, el padre la gana. Lo mismo sucede en el caso de ganar la partida, si el hijo la gana, el padre la pierde, por lo que la implementación de la función (ValorPadreRetropropagación) no es más que negar la entrada. Al finalizar la iteración se debe volver a la situación inicial, realizando una copia de la partida Go inicial sobre la partida de simulación. 5.2. Reutilización de simulaciones anteriores Uno de los objetivos perseguidos, era que las simulaciones pudiesen partir de distintas situaciones iniciales y el poder aprovechar la información obtenida en simulaciones anteriores (dentro del mismo problema y ejecución). Veamos mejor la idea con un ejemplo. Para el juego de Go, la situación de partida seria el tablero vacı́o, tras hacer la simulación, nos propondrı́a un movimiento, lo realizarı́amos, el oponente realizarı́a también su movimiento pertinente y nos volverı́a a tocar. Llegado a este punto necesitamos saber que jugada realizar. La solución buscada para cumplir estos objetivos ha sido, informar de la realización de una acción sobre el problema (o partida) real mediante la función Avanzar(Contenido). Esta función será llamada tantas veces como avances se hayan realizando, pasándoles el contenido correspondiente a cada uno de ellos. Esta función consta de dos pasos principales que detallamos a continuación: 1. Realizar un movimiento: Si la acción o movimiento asociada al contenido proporcionado es válida, se aplica y se almacena el estado actual como estado inicial, de forma que al comenzar cada iteración del método comience del estado almacenado y no del vacı́o. Si la acción no es válida, no se realiza el paso 2 y no se produce ningún cambio. 2. Avanzar por el árbol : Una vez aplicada la acción, se avanza por el árbol según el contenido proporcionado. El avance se realizará comparando el contenido de los nodos del árbol con el 5.2. REUTILIZACIÓN DE SIMULACIONES ANTERIORES 31 contenido pasado por entrada a la función. Una vez encontrado el nodo que corresponde al movimiento, este pasará a ser la nueva raı́z, desechando ası́ otras ramas del árbol y ahorrando espacio en memoria. Hay que observar que al crear todos lo hijos de golpe, si la jugada es Figura 5.9: Avance caso raı́z con hijos válida y la raı́z tiene hijos, uno de sus hijos siempre va a tener el contenido proporcionado en la jugada. Si la raı́z no posee hijos, se crea un nuevo nodo raı́z con ese contenido. Estos últimos casos son ilustrados en la figura 5.9, donde se ve el efecto que tiene en el árbol al avanzar con contenido 1,1, y la figura 5.10, donde se ve el efecto que tiene en el árbol avanzar con contendio 1,2 . Figura 5.10: Avance caso raı́z sin hijos En las dos fases explicadas anteriormente se usan funciones abstractas implementadas en la clase hija por la dependencia que tienen con el problema, por ejemplo la comprobación de que la jugada es válida o la comparación de contenidos. 32 CAPÍTULO 5. IMPLEMENTACIÓN DEL MÉTODO MCTS Capı́tulo 6 Aplicación La aplicación del Go implementada permite de una forma visual jugar al juego del Go contra el ordenador, seleccionar las opciones de juego y dispone de información complementaria de ayuda por si fuera necesaria para el seguimiento del juego o simplemente para recordar las reglas. Este apartado muestra el esquema de clases implementado, la interfaz creada, sus funcionalidades y el valor UCT seleccionado. 6.1. Esquema En cuanto a la implementación, se ha creado una clase para cada una de las ventanas y una especialización de las clases Go y Tablero. La figura 6.1 muestra la relación que existe entre estas clases. Figura 6.1: Diagrama de clases para la Aplicación 6.2. Interfaz La interfaz esta formada por las ventanas de: Inicio, reglas, opciones y juego; además de la clase tablero, que genera el tablero de la ventana de juego. A continuación se explica un poco más en detalle cada uno de estos elementos. 6.2.1. Ventana Inicio Corresponde a la clase Go Interfaz Menu, que crea la ventana de inicio o menú mostrada por la figura F.2. Además asocia los botones a las ventanas correspondientes: El botón “Jugar” crea 33 34 CAPÍTULO 6. APLICACIÓN la ventana opciones (objeto de la clase Go Interfaz Opciones), el de “Reglas” la ventana de reglas (objeto de la clase Go Interfaz Reglas) y el botón “Salir” cierra las ventanas y finaliza el programa. Figura 6.2: Ventana de Inicio 6.2.2. Ventana de reglas Corresponde a la clase Go Interfaz Reglas, que crea la ventana de ayuda mostrada en la figura 6.3. Esta ventana esta formada por un directorio árbol y por un texto. El texto va variando según la parte del árbol seleccionada, mostrando información relacionada con él. Figura 6.3: Ventana de Reglas 6.2.3. Ventana de opciones Figura 6.4: Ventana de opciones 6.2. INTERFAZ 35 Corresponde a la clase Go Interfaz Menu, que crea la ventana de selección de opciones mostrada en la figura F.3. Al cliquear el botón “Confirmar” se crea una nueva partida de Go (Interfaz) con las opciones seleccionadas. Pulsar el botón “Cancelar” cierra la ventana de opciones y el botón “Ayuda” abre la ventana de Reglas por la sección de ayuda en opciones. El Go (interfaz) creado, además de realizar las tareas del Go correspondientes, crea la clase Tablero en su especialización de interfaz que será usada por la ventana de juego. Además añade una serie de funciones como por ejemplo almacenar el color de piedras de la máquina. 6.2.4. Ventana de juego Corresponde a la clase Go Interfaz Juego, que crea la ventana de juego mostrada en la figura F.4. Esta ventana esta formada por tres elementos principales: Botones: Permiten salir de la partida pulsando “Abandonar”, abrir la ventana de reglas pulsando el botón “Reglas” o pasar turno pulsando sobre el botón “Pasar”. Tablero: El tablero es incorporado por la ventana de juego en la interfaz de la ventana, pero la gestión de este y su dibujado se realizan en su propia clase. Otros elementos: Además de esos elementos principales, la ventana dispone de otros elementos que complementan al juego, como son el fondo y la información de piedras capturadas, el temporizador de cada turno y los mensajes de ayuda. Figura 6.5: Ventana de juego Al finalizar la partida tal y como muestra la figura 6.6 muestra un mensaje con la puntuación final. 36 CAPÍTULO 6. APLICACIÓN Figura 6.6: Ventana emergente mostrando la puntuación final 6.2.5. Tablero La parte relacionada con la interfaz del tablero se lleva a cabo en la clase Tablero interfaz, que es una clase hija de la clase Tablero. Al inicializar el tablero, se crea la parte gráfica: Se carga el fondo del tablero, las letras y números de guı́a y las lı́neas (cuadrı́cula). Las piedras se gestionan usando una matriz de imágenes. Si la intersección correspondiente a los ı́ndices de la matriz está libre, la matriz de imágenes no almacenará en ella nada (valor null), en cambio si hay una piedra colocada en esta intersección, se almacena la imagen de esa piedra. Posteriormente se pueden eliminar estas piedras (debido a una captura) marcando las imágenes como no visible y marcándolas como libres en la matriz de imágenes. Además esta clase implementa la acción de colocar pieza. Captura los clic producidos sobre el tablero y actúa en consecuencia: Coloca la pieza si la jugada es válida, avisa al usuario si no es posible realizar la jugada o no realiza ninguna acción si no es el turno del jugador o se ha cliqueado fuera del rango de las intersecciones1 . La figura 6.7 muestra un mensaje emergente en caso de poder realizarse la jugada por ser suicidio o por ser Ko. Figura 6.7: Ventana emergente Movimiento no válido 1 Se llama rango de intersección al área cercana a la intersección, de forma que cliquear dentro de este área significa haber cliqueado en la propia intersección. 6.3. VALOR DEL COEFICIENTE UCT 6.3. 37 Valor del coeficiente UCT La estrategia UCT selecciona los mejores movimientos encontrados hasta el momento pero también explora otros movimientos menos prometedores.2 Algoritmo 6.1 Fórmula UCT para el nodo Ni V alorU CT (Ni ) = tasaExitoi + C × q ln(np ) ni Comenzando por la raı́z, UCT busca un camino de movimientos a través del árbol calculando el valor de cada posición candidata de acuerdo a la tasa de éxito (tasaExitoi ) , el valor del coeficiente C , el número de visitas del nodo ni y el número de visitas del nodo padre np , tal y como muestra la fórmula 6.1. Si hay hijos de un nodo que no se han visitado ninguna vez (ni = 0), se elige uno de ellos aleatoriamente. Como este método no asume ningún conocimiento, lo natural es que se visite cada uno de ellos al menos una vez. Es necesario definir el valor del coeficiente UCT (C) que será usado en la fase de selección del MCTS. Tenemos que determinar un compromiso entre explotación y expansión. Si el valor es pequeño se dará más importancia a la explotación, en cambio si el valor es grande se da importancia a la exploración. Explotación (Valores comprendidos entre 0 y 1): dan más importancia al movimiento más prometedor. La importancia dada será mayor cuanto menor sea el valor. Igualdad (Valor 1): da igual importancia a la explotación como a la exploración. Exploración (Valores mayores de 1): da más importancia a la exploración. La importancia será mayor cuanto mayor sea el valor. En esta implementación se ha optado por la igualdad (valor 1), ya que explora un número suficiente de veces cada rama, pero una vez dirigido hacia la solución desarrolla solo la rama más prometedora, mientras esta de buenos resultados. La figura 6.8 muestra los datos obtenidos en una simulación de Go sobre tablero 3x33 . Como se puede observar en la gráfica el aumentar el valor del factor disminuye el nº de visitas de la rama más prometedora, pero aumenta el del resto de ramas, notándose cada vez más cuales son los siguientes movimientos más prometedores. Debido a la simetrı́a del tablero, el movimiento más prometedor para tableros 3x3 es tanto el (0,1) ,(1,0) (1,2) como el (2,1). 2 Esto lo hace mediante la fórmula del algoritmo 6.1, es decir sumando un número a la tasa de éxito de cada movimiento, menor conforme el nodo haya sido más veces visitado. Este número también crece cuando el nodo padre ha sido visitado pero se ha seleccionado otro de los nodos hijos. Esto significa que la tasa de éxito + el número crecerá hacia movimientos no explorados de forma que en ciertos momentos la suma del nodo será mayor que la del resto de movimientos que tienen tasas de éxito superiores. Si el movimiento funciona (es exitoso), se incrementa la tasa de éxito y podrá próximamente ser seleccionado de nuevo. Si falla (no es exitoso), la tasa de éxito decrece junto con el número y el movimiento deberá esperar un tiempo mayor antes de que sea seleccionado de nuevo. Un movimiento puede también seleccionarse si el resto de movimientos resultan fallidos y por lo tanto las tasas de éxito del resto de competidores descienden. 3 Con 50000 iteraciones, tablero 3x3, 0.5 de penalización, número de simulaciones antes de expandir 30 y modo de recuento Japonés 38 CAPÍTULO 6. APLICACIÓN Figura 6.8: Nº de visitas en simulaciones 3x3 para distintos factores Capı́tulo 7 Conclusiones 7.1. Marco de trabajo En primer lugar, este proyecto ha implicado tomar contacto con un juego y un método desconocidos hasta el momento por mı́. Se ha realizado un trabajo de comprensión de la naturaleza e importancia tanto para el juego Go, como para el método MCTS. Se ha visto que el método MCTS necesita que la información sea perfecta y abarca todos los campos donde esta condición se cumple: Juegos deterministas o estocásticos de uno, dos o tres jugadores. En todos ellos se han obtenido resultados que incluso superan en algunos aspectos a los mejores programas hasta el momento. Su carácter general, permite además obtener buenos resultados en programas de propósito general. En cuanto a la aplicación del método MCTS al juego del Go (juego determinista de dos jugadores), se sabe que se ha obtenido una gran mejora con respecto a programas que usaban otros métodos, pero aun ası́ necesita el apoyo de potentes ordenadores y sigue sin ser capaz de vencer a los humanos más expertos. El gran número de casillas y jugadas posibles en cada turno hace que las combinaciones posibles de movimientos sean increı́blemente grandes, ofreciendo aun un gran reto para la informática. El motivo de este trabajo ha sido conocer el comportamiento del método MCTS de cara a utilizarlo en otros problemas interesantes para los directores de este proyecto. 7.2. Resultados obtenidos El objetivo del proyecto era la realización en lenguaje Java de un jugador virtual que fuera capaz de enfrentarse en el juego del Go a un jugador humano, aplicando el método MCTS. El proyecto constaba de estas cinco grandes tareas: 1. Estudio del juego del Go y el uso de la Inteligencia Artificial en él. 2. Estudio del método MCTS y sus diversas variantes. 3. Implementación del juego del Go. 4. Implementación del método MCTS, intentando que dicha implementación sea lo más general posible, de cara a poder utilizarse en otros problemas interesantes para los directores de este proyecto. 39 40 CAPÍTULO 7. CONCLUSIONES 5. Implementación de un programa visual que enfrente al usuario y al ordenador en el juego del Go. Todas estas tareas se han realizado satisfactoriamente, cumpliéndose además los objetivos detallados de las tareas de implementación recogidos en el apéndice B. 7.3. Diagrama de tiempos El diagrama de la figura 7.1 muestra los tiempos dedicados en las principales fases del proyecto. Este diagrama junto con todo lo relacionado en la gestión del proyecto (metodologı́a, fases, gestión de tiempo y esfuerzos, supervisión del proyecto y herramientas utilizadas) aparece explicado en el apéndice A. Figura 7.1: Diagrama de tiempos 7.4. Lı́neas de trabajo futuro En la creación del módulo MCTS se eligieron unas estrategias concretas para cada una de las fases. Por lo que una lı́nea futura podrı́a ser la modificación de este módulo eligiendo unas estrategias distintas. A partir del módulo MCTS implementado podrı́a también implementarse una versión no genérica de él, donde se usasen simulaciones pseudoaleatorias (en vez de aleatorias) de acuerdo con el problema a tratar, que condujesen de una forma más rápida a la solución. Además resultarı́a muy interesante la paralelización del método. En cuanto al juego Go implementado, una de las lı́neas futuras serı́a poder permitir un hándicap, para compensar la diferencia de niveles antes de comenzar una partida. En cuanto a la aplicación que enfrenta en el juego del Go al usuario con un jugador virtual (ordenador) una lı́nea futura serı́a crear un servidor que enfrentase tanto a jugadores humanos como jugadores virtuales. Como trabajo futuro, se contempla el poder aplicar el método a cualquiera de sus diversos campos. Concretamente dentro del GIGA (Grupo de Informática Gráfica Avanzada) en los campos de trabajo con los que se trabaja, como pueden ser el de los videojuegos o el cálculo de la iluminación de una escena. 7.5. PROBLEMAS ENCONTRADOS 7.5. 41 Problemas encontrados Aquı́ se enumeran los principales problemas encontrados: Comprensión del método MCTS: La compresión del método resultó bastante costosa, prácticamente un mes. La documentación encontrada sobre el tema explicaba el método de forma general, pero carecı́a de ejemplos concretos que facilitasen su comprensión. El encontrar un pseudo-código en internet[19] supuso un avance importante, ya que se aplicaba a un ejemplo concreto. Las ideas presentadas por este pseudo-código se emplearon en la implementación de la primera versión. La ejecución de esta versión sirvió para ver paso a paso como se pasaba por las distintas fases del método, alcanzando con ello su total comprensión. Después de ello ya se pudo comenzar a estudiar a fondo cada una de las fases viendo cual era más conveniente para la solución buscada en este PFC. Estrategias a usar en el método MCTS implementado: El decantarse por una estrategia u otra en cada una de las fases fue también una labor no siempre fácil. Generalización del módulo MCTS: Uno de los objetivos del proyecto era que el módulo MCTS implementado fuese lo más genérico posible. Este hecho supuso entrar en profundidad en cada una de las fases y ver como se podı́a hacer lo más genéricas posible. Se vio que la estructura hasta entonces utilizada dependı́a mucho del problema aplicado (juego del Go) por lo que fue necesario enfocar de forma diferente tanto la estructura como las fases del método. Recuento de puntuación en el juego del Go: En la mayorı́a de documentación encontrada, se define el sistema de recuento del Go como el explicado en el capı́tulo 2. Sin embargo, en internet se encontraban imágenes sobre el recuento de puntuaciones que no siempre coincidı́a con esta definición. Este hecho resulto bastante desconcertante, y hubo que intentar averiguar cual era el sistema correcto de recuento. Finalmente se descubrió[16] que una variación de la versión japonesa del juego bastante extendida, es que para contar los territorios se tiene en cuenta el concepto de “Vida y muerte”[17]1 . Esto hace que al finalizar la partida algunas piedras sean “retiradas” debido a que serı́an matadas en un futuro y se tienen en cuenta a la hora del recuento de la misma forma que las piedras capturadas. El problema es que con este método hay situaciones en las que no se sabe si los territorios pertenecen a un jugador u otro. En el sistema Chino, se da por hecho que los jugadores pasan porque no tienen más movimientos posibles, o estos provocarı́an una misma puntuación tras el recuento. De forma que si los jugadores pasan teniendo más movimientos posibles significa que asumen la puntuación del tablero según las reglas explicadas en el capı́tulo 2. Se decidió dejar el sistema de recuento explicado en el capı́tulo 2, debido a la complejidad que supone en la implementación de la variante japonesa aquı́ explicada y un aparentemente incumplimiento de dos de las condiciones para que se aplicase el método MCTS2 . El lenguaje Java: Al iniciar este proyecto solo se conocı́an los aspectos más básicos del lenguaje, por lo que en ocasiones resulto algo más costoso de lo normal descubrir como implementar ciertas cuestiones. Concretamente no se conocı́a nada de la parte gráfica ni de los threads. Pero gracias a la librerı́a gráfica Java Swing[27] fue mucho más sencillo desarrollar sobre todo la labor estética. 1 Se define un grupo de piedras como ”vivo”, si tiene posibilidad de permanecer en el tablero, o ”muerto”, si el grupo será ”capturado”. La idea básica puede expresarse sencillamente ası́: Un grupo debe tener dos ojos (libertades internas seguras) para vivir. 2 No hay conocimiento completo (las reglas de recuento no son claras) y las simulaciones no terminarı́an rápido. 42 7.6. CAPÍTULO 7. CONCLUSIONES Valoración personal La realización del proyecto me ha resultado muy positiva. Las reuniones con el director y codirector han sido muy útiles a la hora de saber qué dirección tomar, he trabajado muy a gusto con ellos y me he sentido apoyada en todo momento. El tema, pese a ser algo nuevo para mı́, me ha parecido muy interesante; tanto el método MCTS aún por explotar y muy útil en numerosos campos; como el Go, juego curioso que resulta a la vez inquietante por el hecho de qué aún sea un reto para la informática. En definitiva, la experiencia ha sido muy enriquecedora y gratificante. La realización de este proyecto me ha permitido conocer ciertos campos muy interesantes que desconocı́a, completando también mi formación en cuanto a aptitudes y conocimientos. Apéndice A Gestión del proyecto A.1. Metodologı́a de desarrollo La creación de la solución final ha seguido un proceso evolutivo, concretamente el modelo en cascada con realimentación mostrado en la figura A.1. Éste ha sido aplicado en las tres grandes tareas de implementación (Go, MCTS y aplicación), las fases del modelo son las siguientes: Análisis: Fase en la que se establecen los requisitos funcionales y no funcionales. Diseño: Fase en la que se desarrollan los diagramas de clase y de estados con el fin de satisfacer los requisitos de la fase anterior. Implementación: Fase en la que se escribe el código siguiendo el diseño creado. Pruebas: Fase en la que se prueban los elementos creados, tanto simples, como otros más complejos, para verificar el correcto funcionamiento del código implementado. Cada una de las fases depende directamente de la anterior. En ocasiones al llegar a una fase, se ha visto que era necesario modificar cosas de las fases anteriores, produciéndose por lo tanto una retroalimentación. Figura A.1: Modelo en cascada con retroalimentación 43 44 APÉNDICE A. GESTIÓN DEL PROYECTO A.2. Fases del proyecto Veamos cuales han sido las principales fases del proyecto y una breve descripción de éstas: 1. Estudio del Go: Fase en la que se estudió el juego del Go, conociendo sus reglas básicas, jugando al juego y estudiando los logros de la inteligencia artificial en este campo. 2. Estudio del Método Monte-Carlo Tree Search: Fase en la que se estudió el método Monte-Carlo Tree Search, tanto su proceso general, como el conocimiento de distintas posibilidades para cada una de las fases que éste posee. 3. Implementación del Go: Fase en la que se implementó el juego del Go en su modelo de información perfecta. Primero las funciones más simples y recuento de puntuaciones, segundo la estructura de los bloques, seguido de la implementación de la captura, suicidio y finalizando con la regla del Ko. Figura A.2: Evolución del módulo UCT 4. Implementación del método Monte-Carlo Tree Search: Fase en la que se creó el módulo del método Monte-Carlo Tree Search. Inicialmente se realizó una versión base, se continuó elaborando una versión que interactuase con el módulo que implementaba el juego Go, seguida de la versión genérica (donde se generalizó el módulo para aplicarlo en distintos dominios), finalizando por la incorporación de la funcionalidad de reutilización de simulaciones y el poder partir de distintos problemas. Las figuras A.2 y A.3 muestran el proceso de evolución, tanto de los módulos del método como de la estructura del nodo. Figura A.3: Generalización del nodo 5. Aplicación: Fase en la que se implementó la aplicación que usa el módulo genérico MCTS final que enfrenta un jugador humano a uno virtual en el juego del Go. A esta fase pertenece también la creación de la interfaz y la implementación de las funcionalidades correspondientes. 6. Memoria: Fase en la que se escribió la memoria del proyecto. A.3. GESTIÓN DE TIEMPO Y ESFUERZO A.3. 45 Gestión de tiempo y esfuerzo La distribución en el tiempo de cada una de las fases puede verse en el diagrama de Gantt1 que recoge la figura A.4. Como observamos el proyecto se ha desarrollado entre Octubre y Junio. Algunas fases han sido más largas que otras debido a la dificultad encontrada en ellas. Además durante el primer cuatrimestre el avance fue más lento debido a la compaginación del proyecto con otros estudios. Figura A.4: Diagrama de Gantt Como puede verse en la imagen, hay una franja temporal en la que coinciden el estudio del método e implementación del mismo. Esto se debe a que esta implementación sirvió para la comprensión total del método. También se puede observar que, en la implementación del Go, la regla del Ko fue incorporada al código más tarde; ya que la idea de como enfocarlo surgió con posterioridad. Se puede observar claramente la dependencia entre la segunda versión del MCTS (MCTS-Go) con la implementación del juego del Go. En cuanto al tiempo dedicado al proyecto es aproximadamente unas 600 horas. Las horas para cada una de las fases aparecen en la tabla A.1. Las partes de implementación del Go y del método MCTS son las que más tiempo han empleado. El cálculo de horas incluye para cada tarea las distintas fases de la metodologı́a usada (Análisis, Diseño, Implementación y Pruebas). Además, la retroalimentación realizada, ha provocado que el paso por las distintas fases se repita en numerosas ocasiones, principalmente en la implementación del módulo MCTS. En cambio, el desarrollo de la aplicación se ha realizado en un tiempo mucho menor. Estudio del Go Estudio MCTS Implementación del Go Implementación MCTS Aplicación Memoria Total Horas estimadas 40 85 126 240 52 64 607 Cuadro A.1: Horas dedicadas 1 Herramienta gráfica cuyo objetivo es mostrar el tiempo de dedicación previsto para diferentes tareas o actividades a lo largo de un tiempo total determinado. 46 APÉNDICE A. GESTIÓN DEL PROYECTO En la figura A.5 podemos ver el porcentaje de tiempo empleado por cada una de las fases. Se observa, que la implementación del Go y del método MCTS suponen un 60 % del total de horas, en contraste con el desarrollo de la aplicación que supone solo un 9 %. Figura A.5: Porcentaje del trabajo A.4. Supervisión del proyecto Durante la realización del proyecto se ha contado con la supervisión del director y co-director, con los que se ha realizado reuniones periódicamente. En ellas, se presentaban los avances, y se consultaban las distintas dudas surgidas. La periocidad de las reuniones ha sido variable. Inicialmente las reuniones fueron semanales hasta la completa comprensión del método Monte-Carlo Tree Search y posteriormente ya fueron cada dos semanas o mensuales. En estas reuniones se presentaba un PowerPoint con el siguiente contenido: Recapitulación de lo alcanzado anteriormente Presentación en detalle de los avances conseguidos desde la última reunión, explicando las ideas aplicadas. Resumen de los avances. Presentación de dudas y posibles soluciones. Presentación del trabajo a realizar en las próximas semanas. A.5. Herramientas utilizadas En cuanto a la realización del proyecto se han utilizado distintas herramientas para facilitar la elaboración del mismo. Las cuales se enumeran a continuación: Eclipse: Como entorno de programación y ejecución. GanttProject: Para realizar los diagramas de Gantt. VisualParadigm for UML: Para la realización de los diagramas de clases y estados. Microsoft Excel: Para la creación de gráficas. Microsoft PowerPoint: Para la creación de las presentaciones de las reuniones y figuras como esquemas o tableros presentes en la memoria. A.5. HERRAMIENTAS UTILIZADAS 47 Photoshop CS3: Para la creación de la textura del tablero de la interfaz y el fondo de la pantalla de juego. LYX: Como entorno para la escritura de la memoria en lenguaje LATEX. 48 APÉNDICE A. GESTIÓN DEL PROYECTO Apéndice B Requisitos Tres de los objetivos del proyecto consistı́an en la implementación de distintos elementos: El juego del Go, el método MCTS y una aplicación que enfrentase el usuario al ordenador en el juego del Go. Para cada uno de estos objetivos se marcaron una serie de requisitos a cumplir. Los requisitos son de dos tipos: 1) Funcionales: Que definen el comportamiento interno del software: cálculos, detalles técnicos, manipulación de datos y otras funcionalidades especı́ficas y 2) No funcionales: Que especifican criterios que pueden usarse para juzgar la operación de un sistema. Los requisitos marcados en el proyecto se recogen en los cuadros: B.1 para el juego del Go, B.2 para el método MCTS y B.3 para la aplicación. Código RF-0 RF-1 RF-2 RF-3 RF-4 RF-5 RF-6 RF-7 RNF-0 RNF-1 Descripción Se debe permitir elegir entre modo de recuento chino o japonés. Se debe poder elegir entre tableros de distinta dimensión. Se podrá seleccionar el valor de compensación. Una vez comenzada la partida no podrán ser modificadas las opciones anteriores Permitirá al usuario, “colocar pieza” o “pasar” Se deberán respetar las reglas del juego (captura, suicidio,Ko...) Se podrá volver a comenzar una partida en cualquier momento del juego. Al comenzar una nueva partida se guardan las opciones definidas anteriormente. Deberá funcionar en tiempo real Debe ser implementado en lenguaje Java Cuadro B.1: Requisitos del Go En los cuadros aparecen numerados cada uno de los requisitos, se nombran con RF a los requisitos funcionales y con RNF a los requisitos no funcionales. Por ejemplo en el cuadro B.1 aparecen 8 requisitos funcionales y 2 requisitos no funcionales. 49 50 APÉNDICE B. REQUISITOS Código RF-0 RF-1 RF-2 RF-3 RF-4 RF-5 Descripción Deberá poder adaptarse al problema, en lo que se refiere a contenido y valor. Debe permitir realizar sucesivas simulaciones hasta un número tope o un tiempo lı́mite dado. Debe permitir avanzar por las ramas del árbol según contenidos (movimientos) dados. Debe permitir reutilizar el árbol en simulaciones y búsquedas posteriores. Antes de comenzar la simulación se tienen que poder modificar los valores de todas las constantes usadas en el método. Debe ser genérico y poderse usar en distintos problemas (incluido el Go) como particularización del módulo genérico. Cuadro B.2: Requisitos del módulo MCTS En el cuadro B.2 los seis requisitos son funcionales y en B.3 aparecen seis requisitos funcionales y uno no funcional. Código RF-0 RF-1 RF-2 RF-3 RF-4 RF-5 RNF-0 Descripción El sistema debe poseer una interfaz que permita al usuario jugar interactivamente al juego del Go contra un jugador virtual. Antes de comenzar el juego se deberá poder seleccionar las opciones del Go además de tiempo lı́mite por turno, color de piezas en el juego y nombre del usuario. El jugador virtual usará el método Monte-Carlo Tree Search (MCTS) para seleccionar la jugada a realizar. Al finalizar la partida se mostrará el resultado según el modo de recuento anteriormente seleccionado. La ventana de juego deberá mostrar al menos: un tablero, las piezas colocadas, número de piezas capturadas y el tiempo que le queda a cada jugador. Las ventanas dispondrán de elementos de ayuda como ventanas o textos indicativos. La interfaz deber permitir al usuario jugar de una forma agradable y sencilla. Cuadro B.3: Requisitos de la aplicación Apéndice C Aplicaciones MCTS El método implementado en este PFC se ha aplicado solo al juego del Go. Este apéndice muestra de forma resumida distintas aplicaciones realizadas por expertos en distintos dominios, si desea profundizar en cualquiera de ellos use las referencias bibliográficas, están enlazadas a los artı́culos correspondientes. Los dominios que trataremos serán exclusivamente los que tengan información perfecta. Veremos a continuación que el método MCTS ha conducido a los mejores programas en varios de los dominios y además es muy atractivo para muchos otros. MCTS parece permitir superar el problema de adquisición de conocimiento permitiendo hacer de una forma más sencilla esta adquisición en muchos campos. C.1. Deterministas C.1.1. Deterministas de un jugador El método MCTS se ha aplicado a problemas de gestión y producción (Production Management Problems) obteniendo resultados bastante aceptables[29]. Otra aplicación fue el juego SameGame, con el que se ganó el record mundial de este juego usando variantes del MCTS[30]. Además estos métodos superaban también las mejores puntuaciones humanas para el Morpion Solitario[31]. Figura C.1: SameGame y Morpion Solitario Considerando los problemas de optimización como juegos de un jugador, se han usado variantes MCTS en la optimización de librerı́as para diferentes plataformas (Library Performance Turing). 51 52 C.1.2. APÉNDICE C. APLICACIONES MCTS Deterministas de dos jugadores Para juegos deterministas de dos jugadores como el ajedrez y las damas, el uso de αβ con una función de evaluación fuerte fue la base para la construcción de un fuerte jugador de Inteligencia Artificial. Sin embargo, donde el MCTS ha tenido más éxito es en el campo del Go, cuyos programas ganan los torneos de las olimpiadas de computación desde 2006. Además del Go, MCTS se usa también para otros juegos deterministas de dos jugadores, como Amazons (Juego de las amazonas)[33] o LinesOfAction(LOA)[34], en el primero ganaron las olimpiadas de 2008 y 2009 y en el segundo se ha conseguido el mismo nivel que el mejor juego del mundo. Figura C.2: Amazons y LinesOfAction C.1.3. Deterministas multijugadores En 2008 Sturtevant aplicó MCTS en juegos multijugador como Las Damas Chinas, Spades and Hearts (Picas y corazones). En las damas chinas demostró que MCTS era capaz de superar los métodos de búsqueda estandard maxn y paranoid equipados con una fuerte función de evaluación. Para las versiones de Spades and Hearts, MCTS se posicionó al mismo nivel que el estado del arte. Figura C.3: Damas chinas y Spades and Hearts C.2. Estocásticos C.2.1. Estocásticos de un jugador Las primeras aplicaciones de MCTS para juegos estocásticos de un jugador fueron en el dominio de navegación[35]. El dominio de navegación es un problema estocástico que busca el menor camino entre dos puntos bajo condiciones de viento variable. Este problema fue tratado usando el método UCT con C.2. ESTOCÁSTICOS 53 el que se consiguió que se necesitasen significativamente menos simulaciones para alcanzar el mismo rendimiento que los programas existentes hasta entonces. C.2.2. Estocásticos de dos jugadores Uno de estos juegos es el Backgammon[36], en el que un programa con selección UCT y simulaciones completamente aleatorias fue capaz de encontrar la mejor forma de comenzar el juego en un tercio del tiempo que otros programas, pero sin embargo, era significativamente más débil que los programas del estado del arte. Figura C.4: Backgammon C.2.3. Estocásticos de varios jugadores La popularidad de los juegos modernos de estrategia de tablero está incrementándose desde que nacieron el la década de los 90. Los juegos de estrategia de tablero, son de especial interés para los investigadores de la inteligencia artificial, ya que suponen un puente entre los juegos clásicos de tablero (deterministas de dos jugadores) y los videojuegos. Se aplicó el MCTS al juego multijugador Colonos del Catán[37], aumentando el algoritmo con un conocimiento limitado del juego. En los experimentos, en los que las reglas fueron cambiadas para conseguir una estocástica perfecta información del juego, se obtuvo que el programa era capaz de derrotar convincentemente al mejor programa de código abierto de Inteligencia Artificial disponible, y que es un razonable fuerte jugador para los humanos. Figura C.5: Colonos del Catán 54 C.3. APÉNDICE C. APLICACIONES MCTS Juegos de propósito general El propósito de los juegos de propósito general es crear agentes inteligentes que automáticamente aprendan como jugar a diferentes juegos a un nivel experto sin intervenciones de los humanos. El más exitoso agente en el pasado habı́a usado la tradicional búsqueda en árboles de juego combinada con funciones heurı́sticas de aprendizaje automático para evaluar los estados de juego. Sin embargo desde 2007, los programas MCTS han ganado los torneos de juegos de propósito general usando UCT, con un algoritmo de aprendizaje online para las simulaciones[38]. Apéndice D Ejemplo de simulación Para comprender mejor el método MCTS, en este apéndice se explica un ejemplo de simulación para el juego del Go de tamaño 3x3, que expande sus nodos cuando se han visitado dos veces. Primero se explica la estructura del nodo, luego se explica en detalle las veinte iteraciones realizadas y finalmente se explica algunas ideas, por si estas no quedasen claras o no se visualizasen durante el ejemplo. Decir que durante las simulaciones, se trabaja sobre una copia del Go, realizando acciones sobre esta copia sin tocar la partida de Go en la que se juega con el adversario. En cada iteración, primero se vuelve a copiar sobre la copia el estado del Go proporcionado al inicio de la simulación MCTS, y se trabajará sobre esta copia realizando sobre ella los movimientos según la selección que realcemos y los movimientos aleatorios de la simulación aleatoria. Durante este ejemplo al hablar de partida del Go, se referirá a la copia del Go sobre la que se trabaja. Como se observará más adelante el árbol se mantiene, actualizándose tras las distintas iteraciones. D.1. La estructura del nodo Figura D.1: Nodo MCTS del Go El nodo MCTS consta de dos partes: Datos para el algoritmo MCTS y Contenido. Tal y como muestra la figura D.1, para el caso del Go, como datos para el algoritmo MCTS tenemos el número de partidas ganadas (de las simuladas a partir de ese nodo u hijos) y número de simulaciones realizadas (desde él o sus hijos). En cuanto a la información correspondiente al juego, es decir al contenido, en el Go corresponde con las acciones de colocar pieza y pasar; que se representa mediante un booleano que indica si la acción consiste en pasar o no y las coordenadas x,y que indican la posición donde se ha colocado la pieza, usando como punto de referencia es la esquina superior izquierda del tablero. Durante el resto de la explicación usaremos la versión abreviada del 55 56 APÉNDICE D. EJEMPLO DE SIMULACIÓN nodo, mostrada en la figura D.2. Donde el nodo será de un color u otro dependiendo del turno del jugador que realiza la acción (negro/blanco). Figura D.2: Simplificación del nodo MCTS Go Un caso especial es la representación del nodo raı́z aunque no se haya realizado ninguna acción (colocación de pieza o pasar), es decir, al inicio de la partida. En el Go se ha representado con el siguiente contenido: Pasar=false, x=-1, y-1. En las figuras del ejemplo, se indica que un nodo es raı́z del árbol cuando esté señalado por una flecha naranja. La figura D.3 muestra la raı́z del árbol para tablero vacı́o. Figura D.3: Raı́z para comienzo de la partida Además durante el ejemplo se acompaña la representación del árbol en las figuras con un dibujo que se indica la situación del tablero y el turno, en el Go usado para la simulación. En la figura D.4 muestra la situación del tablero y turno al comienzo de una partida. Figura D.4: Situación tablero y turno D.2. Forma del árbol En el juego del Go, se alterna turno de negras y de blancas. Como el árbol representa las jugadas realizadas por estos (salvo el nodo raı́z), el árbol por lo tanto también alterna color: primer nivel jugador negro, segundo jugador blanco, tercero negro... En la figura D.5 se puede ver ésta idea. D.3. Iteraciones D.3.1. Primera iteración Comenzamos con la primera iteración. Partimos de la situación de inicio de partida del Go (tablero vacı́o y turno para el jugador negro, tal y como indica la figura D.4), en la que el árbol D.3. ITERACIONES 57 Figura D.5: Forma del árbol Figura D.6: Raı́z para comienzo de la partida solo posee un nodo raı́z, tal y como muestra la figura D.3. 1. Selección: Como el nodo raı́z no tiene hijos, no se selecciona ninguno de ellos y no se avanza. La situación de la partida y del árbol permanecen iguales. 2. Expansión: La raı́z siempre se expande, por lo tanto se crean todos sus hijos. Y sobre los hijos creados, se selecciona uno cualquiera. En la simulación realizada, el nodo seleccionado ha sido el de colocar una pieza en la posición 1,0 , cuya acción será aplicada a la partida del Go de la simulación. La Figura D.7 ilustra la creación de los hijos (cada hijo corresponde a una jugada posible que puede realizar el jugador negro, el cual poseı́a el turno, representados con un negro grisáceo) y la selección del nodo 1,0 (representado por un negro puro) realizando la colocación de la piedra negra sobre la intersección 1,0 del tablero y pasando el turno al jugador blanco. Figura D.7: Efectos de la fase de expansión 3. Simulación: La simulación parte del nodo anteriormente seleccionado, es decir, de la situación del tablero obtenida después de la fase de expansión. A partir de esta se van realizando acciones válidas aleatoriamente (colocar pieza/pasar) sobre la partida de Go hasta que finalice 58 APÉNDICE D. EJEMPLO DE SIMULACIÓN la partida (pasar dos veces consecutivas) y se obtenga el resultado. La Figura D.8 muestra un ejemplo posible del que se obtiene como resultado que gana el jugador Negro. Figura D.8: Ejemplo de simulación aleatoria 4. Retropropagación: En esta fase se retropropaga el resultado desde la hoja a la raı́z. Como ha ganado el jugador negro y este corresponde con el color del nodo del que parte la simulación, se incrementa tanto el contador de número de visitadas ni como el de ganadas vi . En la retropropagación , en el caso del juego del Go, el que un jugador gane supone que el otro pierda; y al alternar jugada de negras y blancas, el ganar uno supone la pérdida del otro, por lo que si el hijo gana, el padre pierde. Al perder se incrementa solo el número de visitadas ni pero no el de ganadas vi . La Figura D.9 muestra la situación del árbol tras la fase de retropropagación. Figura D.9: Iteración 1:Retropropagación D.3.2. Segunda iteración Al comienzo de la iteración, el Go vuelve a la situación de partida (tablero vacı́o y turno de negras), pero se conserva el árbol generado en la simulación anterior. La figura D.10 muestra tanto el árbol como la situación del juego al comienzo de la segunda iteración. Veamos como se desarrolla la segunda iteración en cada una de las fases: Figura D.10: Iteración 2: Situacion de partida 1. Selección: Se calcula el valor UCT para cada uno de los nodos según la fórmula UCT. Ésta, tiene como divisor el número de visitas ni que en la mayorı́a de casos es 0. Se controla esta D.3. ITERACIONES 59 división por 0 dando a estos nodos un valor aleatorio muy grande. Esto fuerza a que cada nodo sea seleccionado una vez antes de volverse a seleccionar cualquier otro con contador de visitas mayor. En esta iteración en concreto, quiere decir, que se seleccionará cualquier nodo salvo el 1,0. En el ejemplo el nodo seleccionado ha sido el 2,1, como puede observarse en la figura D.11. Figura D.11: Iteración 2: Selección 2. Expansión: El nodo seleccionado no se ha visitado ninguna vez (ni = 0) por lo que no alcanza el número de visitas mı́nimo para expandirse (ni = 2) y no se expande, quedando el árbol y la partida en el mismo estado. 3. Simulación: En este paso se realiza una simulación aleatoria partiendo de situación actual de la partida (tablero vacı́o con piedra negra sobre intersección 2,1). La imagen D.12 muestra esta simulación , en la que negras pierde. Figura D.12: Iteración 2: Simulación aleatoria 4. Retropropagación: El resultado obtenido (negras pierde) se propaga desde la hoja a la raı́z actualizando los nodos. Incrementa los contadores de visitas ni de ambos en 1. Al perder negras, el valor vi (que representa partidas ganadas) no se incrementa, pero si el del nodo padre. La figura D.13 ilustra estas actualizaciones. Figura D.13: Iteración 2: Retropropagación 60 APÉNDICE D. EJEMPLO DE SIMULACIÓN D.3.3. Tercera iteración La figura D.14 muestra tanto el árbol como la situación del juego al comienzo de la tercera iteración. Veamos como se desarrolla la iteración en cada una de las fases: Figura D.14: Iteración 3: Situacion de partida 1. Selección: Como sigue habiendo nodos que aun no han sido visitados ninguna vez, se selecciona uno de estos, en este ejemplo el 0,0. Tal y como muestra la figura D.15. Figura D.15: Iteración 3: Selección 2. Expansión: El nodo seleccionado no se ha visitado ninguna vez (ni = 0) por lo que no alcanza el número de visitas mı́nimo para expandirse (ni = 2) y no se expande, quedando el árbol y la partida en el mismo estado. 3. Simulación: En este paso se realiza una simulación aleatoria partiendo de situación actual de la partida (tablero vacı́o con piedra negra sobre intersección 0,0) de la misma forma que en las iteraciones anteriores. En este caso negras pierde. 4. Retropropagación: El resultado obtenido (negras pierde) se propaga desde la hoja a la raı́z actualizando los nodos, tal y como ilustra la figura D.16. Figura D.16: Iteración 3: Retropropagación D.3. ITERACIONES D.3.4. 61 Iteraciones de la cuarta a décima Estas iteraciones se realizan de forma idéntica a las anteriores. En la cuarta iteración se ha seleccionado el nodo 0,2 y la simulación aleatoria ha dicho que gana negras. En la quinta el nodo 2,0, perdiendo. En la sexta, el nodo Pasar, perdiendo. En la séptima el nodo 1,1 ganado. En la octava el nodo 2,2 perdiendo. En la novena el nodo 2,1 perdiendo y en la décima el nodo 0,1 ganando. D.3.5. Decimoprimero iteración La figura D.17 muestra tanto el árbol como la situación del juego al comienzo de la decimoprimera iteración. Veamos como se desarrolla la iteración en cada una de las fases: Figura D.17: Iteración 11: Situacion de partida 1. Selección: Se han visitado ya todos los nodos al menos una vez, por lo que a partir de ahora se va a aplicar siempre el algoritmo UCT sobre estos nodos. Como el contador de visitas ni es para todos el mismo, tendrán un valor mayor UCT los nodos que hayan ganado las simulaciones realizadas. Y se selecciona uno de estos, en este caso, el nodo 0,1 por ser el primero que tiene el mayor valor. La figura D.18 muestra la selección del mismo. Figura D.18: Iteración 11: Selección 2. Expansión: El nodo seleccionado ha sido visitado una sola vez (ni = 1) por lo que no alcanza el número de visitas mı́nimo para expandirse (ni = 2) y no se expande, quedando el árbol y la partida en el mismo estado. 3. Simulación: En este paso se realiza una simulación aleatoria partiendo de situación actual de la partida (tablero vacı́o con piedra negra sobre intersección 0,1) de la misma forma que en las iteraciones anteriores. En este caso negras pierde. 4. Retropropagación: El resultado obtenido (negras pierde) se propaga desde la hoja a la raı́z actualizando los nodos, tal y como ilustra la figura D.19. 62 APÉNDICE D. EJEMPLO DE SIMULACIÓN Figura D.19: Iteración 11: Retropropagación D.3.6. Iteraciones de la decimosegunda a la decimocuarta Estas iteraciones se realizan de forma idéntica a la anterior. En la iteración decimosegunda se selecciona el nodo 0,2, perdiendo la partida. En la decimotercera, se selecciona el nodo 1,0 ganando. En la decimocuarta se selecciona el nodo 1,1 perdiendo. En estas iteraciones se aplica la fórmula UCT, por ejemplo el nodo 1,0 al ganar la partida tendrá una tasa de éxito mayor al resto de nodos, afectando a su valor UCT calculado. D.3.7. Decimoquinta iteración La figura D.20 muestra tanto el árbol como la situación del juego al comienzo de la decimoquinta iteración. Veamos como se desarrolla la iteración en cada una de las fases: Figura D.20: Iteración 15: Situacion de partida 1. Selección: Como muestra la figura D.21 se selecciona el nodo 1,0. Figura D.21: Iteración 15: Selección 2. Expansión: El nodo seleccionado ha sido visitado dos veces (ni = 2) alcanzando ası́ el número de visitas mı́nimo para expandirse (ni = 2) , expandiéndose. Al expandirse crea tantos hijos como situaciones alcanzables desde el nodo inicializando los valores ni y vi de sus nodos a cero. En la partida del Go el turno es del jugador blanco, por lo que estos nodos representan D.3. ITERACIONES 63 jugadas del jugador blanco. De todos los nodos creados se selecciona uno al azar, en este caso se ha seleccionado el 2,0 tal y como muestra la figura D.22. Se realizan las acciones acordes con esta selección, es decir colocar una piedra blanca sobre la posición 2,0 y el turno pasa al jugador negro. Figura D.22: Iteración 15: Expansión 3. Simulación: En este paso se realiza una simulación aleatoria partiendo de situación actual de la partida (tablero vacı́o con piedra negra sobre intersección 0,0) de la misma forma que en las iteraciones anteriores. En este caso negras pierde. 4. Simulación: La simulación parte del nodo anteriormente seleccionado, es decir, de la situación del tablero obtenida después de la fase de expansión (tablero vacı́o con negra en posición 0,1 y blanca en posición 2,0 siendo turno de negras). La figura D.23 muestra la simulación aleatoria que se ha producido, en la que el jugador blanco es el ganador. Figura D.23: Iteración 15: Simulación aleatoria 5. Retropropagación: El resultado obtenido (blancas gana) se propaga desde la hoja a la raı́z actualizando los nodos, tal y como ilustra la figura D.24. En nodo hoja es blanco, por lo tanto se incrementa en una unidad tanto número de ganadas vi como el contador de visitas ni . Propagamos el resultado al nodo padre, al ser negro y ganar el blanco, se actualiza el contador de visitas ni , pero no el contador de ganadas vi . Es decir, si el nodo hijo gana, el padre pierde. Se actualiza el nodo raı́z incrementando ambos valores en una unidad. D.3.8. Decimosexta iteración La figura D.25 muestra tanto el árbol como la situación del juego al comienzo de la decimosexta iteración. Veamos como se desarrolla la iteración en cada una de las fases: 1. Selección: Como muestra la figura D.26 se selecciona el nodo 0,1. 64 APÉNDICE D. EJEMPLO DE SIMULACIÓN Figura D.24: Iteración 15: Retropropagación Figura D.25: Iteración 16: Situacion de partida 2. Expansión: El nodo seleccionado se ha visitado dos veces (ni = 2) alcanzando ası́ el número de visitas mı́nimo para expandirse (ni = 2) y expandiéndose. Al expandirse crea tantos hijos como situaciones alcanzables desde el nodo inicializando los valores ni y vi de sus nodos a cero. En la partida del Go el turno es del jugador blanco, por lo que estos nodos representan jugadas del jugador blanco. De todos los nodos creados se selecciona uno al azar, en este caso se ha seleccionado el 0,0 tal y como muestra la figura D.27. Se realizan las acciones acordes con esta selección, es decir colocar una piedra blanca sobre la posición 0,0 y el turno pasa al jugador negro. 3. Simulación: En este paso se realiza una simulación aleatoria partiendo de situación actual de la partida (tablero vacı́o con piedra negra sobre intersección 0,1 , blanca sobre 0,0 y turno de blancas) de la misma forma que en las iteraciones anteriores. En este caso blancas gana. 4. Retropropagación: El resultado obtenido (blancas gana) se propaga desde la hoja a la raı́z actualizando los nodos, tal y como ilustra la figura D.28. D.3.9. Iteraciones de la de la decimoséptima a la vigésima En la iteración decimoséptima se ha seleccionado el nodo 0,2 , que se expande, eligiendo el nodo pasar y perdiendo la simulación. En la decimoctava, se selecciona en nodo 1,1 que se expande, eligiendo el nodo 1,0 y perdiendo la simulación. En la decimonovena se selecciona el nodo 0,1, el D.3. ITERACIONES 65 Figura D.26: Iteración 16: Selección Figura D.27: Iteración 16: Expansión cual no se expande y pierde la simulación. En la vigésima iteración se selecciona el nodo 1,2, el cual no se expande y pierde la simulación. D.3.10. Futuras iteraciones El ejemplo se ha realizado solo para veinte simulaciones, debido a que solo pretende ilustrar el método. Sin embargo hay algunos conceptos que este no se reflejan en el ejemplo y que explicamos a continuación. Selección: En el paso de selección se avanza desde la raı́z hasta las hojas, decidiendo en cada uno de ellos que hijo seleccionar. El camino tomado puede conducir a que se atraviesen varios niveles, tal y como muestra la figura D.29. Expansión: Conforme nos vamos acercando al final de la partida, el número de jugadas posibles suele ser menor. Puede llegar el caso en que no se pueda realizar ninguna jugada, por lo tanto el nodo al expandirse no cree ningún hijo. En el juego del Go indica que la partida ha finalizado (se ha pasado dos veces consecutivas). Simulación aleatoria: Las simulaciones aleatorias mostradas en el ejemplo eran relativamente 66 APÉNDICE D. EJEMPLO DE SIMULACIÓN Figura D.28: Iteración 16: Retropropagación Figura D.29: Selección en el Go cortas. El número de movimientos realizado antes de acabar la partida puede ser muy pequeño o muy grande, dependiendo de la situación de partida y hacia donde se dirija ésta con los movimientos realizados. Retropropagación: En la retropropagación se recorren tantos nodos como nivel tenga la hoja. Esto quiere decir que se actualizan más nodos o menos dependiendo el nivel al que se encuentre la hoja. D.4. Elección del mejor nodo En el ejemplo realizado, tras realizar las veinte iteraciones del método se ha obtenido el árbol representado en la figura D.30. Como solo se necesita observar los nodos del primer nivel, el resto se representan en la figura con un tamaño menor. Para la elección del mejor nodo, se observan los valores de los nodos alcanzables desde la raı́z, D.5. NÚMERO DE SIMULACIONES 67 tanto el contador de visitas ni como el número de partidas ganadas vi . El método implementado para seleccionar el mejor nodo ha sido el de “Más robustez” que elige el nodo que tiene un mayor número de visitas ni 1 . En este caso corresponden a los nodos: 0,1 , 0,2 , 1,0 y 1,1. El nodo 0,1 al tener un valor vi menor se descarta. Elegir uno de los otros tres, dados los resultados conocidos, resulta indiferente, se elegirı́a por ejemplo el primero, en este caso el 0,2. Figura D.30: Árbol generado tras la simulación de veinte iteraciones D.5. Número de simulaciones En el ejemplo ilustrado se han realizado 20 iteraciones del método, un número realmente pequeño. Es necesario usar un número significativo de iteraciones (dependiendo del problema podrá convenir uno u otro), es difı́cil saber el número apropiado por ello es muy útil limitar este con el tiempo2 . 1 En caso de que varios tengan el mismo nodo cogerá el que mayor valor tenga. Si además hay varios con el mismo valor elegirá uno cualquiera de ellos. 2 Hacer todas las iteraciones que se pueda en un tiempo dado. 68 APÉNDICE D. EJEMPLO DE SIMULACIÓN Apéndice E Validación E.1. Go Para validar el juego del Go, lo que se ha hecho ha sido forzar distintas situaciones y comprobado que los resultados sean correctos. Al ser progresiva la implementación se ha ido probando poco a poco las funcionalidades añadidas en cada caso. Para la comprobación se ha visualizado por pantalla el contenido de la matriz tablero, matriz de bloques y conjunto de bloques según conviniese. Figura E.1: Código que prueba los bloques 69 70 E.1.1. APÉNDICE E. VALIDACIÓN Reglas y bloques Debido a que para crear ciertas situaciones se necesita colocar un gran numero de piezas y ver el proceso de cada una resultarı́a costoso. Se fueron realizando pruebas de forma incremental añadiendo cada vez algunas lı́neas de código para forzar situaciones a partir de ejemplos anteriores. El ejemplo que se muestra a continuación ilustra el funcionamiento de bloques, las reglas de captura, suicidio y la del Ko. El código de la prueba correspondiente aparece en la figura E.1. Para seguir el desarrollo del ejemplo se muestra paso a paso, la traza obtenida por pantalla junto con una ilustración que muestra el tablero y los grupos de piedras. Además se acompaña de explicaciones para la total comprensión de la prueba. Durante las explicaciones se emplea tanto la palabra bloque como la palabra grupo, para hablar de los grupos de piedras conectados debido a su adyacencia, explicado en la parte teórica del juego. En las figuras siguientes se agrupan los tableros de cuatro en cuatro y de dos en dos, igual que las salidas para hacer que ocupen menos espacio y sea más sencilla su lectura. Figura E.2: Jugadas (1-3) La figura E.2 muestra la situación del tablero y los grupos para las primeras jugadas. En la figura E.3 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos se parte de tablero vacı́o, en el que no hay ningún grupo. A continuación se coloca una piedra negra creando el primer grupo formado por una única pieza. Luego el blanco coloca su piedra, creando un nuevo grupo (con ı́ndice 1) y le sigue el negro colocando una piedra adyacente a la blanca, pero al ser de distinto color forma un grupo nuevo. E.1. GO 71 Figura E.3: Trazas jugadas (1-3) Figura E.4: Jugadas (4-7) La figura E.4 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.5 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos en la jugada 6, la pieza blanca colocada se une al bloque ya existente. 72 APÉNDICE E. VALIDACIÓN Figura E.5: Trazas jugadas (4-7) Figura E.6: Jugadas (8-11) La figura E.6 muestra la situación del tablero y los grupos para las jugadas siguientes. En la E.1. GO 73 figura E.7 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos la jugada 8, no es válida ya que supone la eliminación de libertades y por lo tanto suicidio. La traza indica también que la acción no es válida y no realiza cambio en el tablero ni los grupos. En la jugada 10, con la colocación de la piedra negra se realiza una fusión entre dos grupos de color negro, actualizando los valores de los ı́ndices de los grupos según corresponda. Algo similar ocurre en la jugada 11, la colocación de la piedra blanca genera también una fusión y actualización de los ı́ndices de los grupos. Figura E.7: Trazas jugadas (8-11) La figura E.8 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.9 se ven las trazas obtenidas para cada una de las situaciones anteriores. 74 APÉNDICE E. VALIDACIÓN Figura E.8: Jugadas (11-12) Figura E.9: Trazas jugadas (11-12) Figura E.10: Jugadas (13-14) La figura E.10 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.11 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos en la jugada 14, se produce una fusión entre los dos grupos de blancas existentes. E.1. GO 75 Figura E.11: Trazas jugadas (13-14) Figura E.12: Jugadas (15-16) La figura E.12 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.13 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos en la jugada 15, la pieza negra se une al grupo ya existente. 76 APÉNDICE E. VALIDACIÓN Figura E.13: Trazas jugadas (15-16) Figura E.14: Jugadas (17-18) La figura E.14 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.15 se ven las trazas obtenidas para cada una de las situaciones anteriores. E.1. GO 77 Figura E.15: Trazas jugadas (17-18) Figura E.16: Jugadas (19-20) La figura E.16 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.17 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos la jugada 20 no es posible, ya que supondrı́a un suicidio tanto para el grupo 2, como el 5. 78 APÉNDICE E. VALIDACIÓN Figura E.17: Trazas jugadas (19-20) Figura E.18: Jugadas (21-22) La figura E.18 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.19 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos en la jugada 22, la pieza negra produce la muerte tanto del grupo 2 como del 5, retirándose todas las piedras de estos grupos del tablero. E.1. GO 79 Figura E.19: Trazas jugadas (21-22) Figura E.20: Jugadas (23-24) La figura E.20 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.21 se ven las trazas obtenidas para cada una de las situaciones anteriores. 80 APÉNDICE E. VALIDACIÓN Figura E.21: Trazas jugadas (23-24) Figura E.22: Jugadas (25-26) La figura E.22 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.23 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos en la imagen al colocar la piedra blanca en la jugada 25 se captura una piedra negra. En la jugada 26, el jugador negro quiere colocar una pieza para matar a la piedra blanca, pero esta jugada no es posible, debido a que el tablero volverı́a a la situación anterior (jugada 24) infringiendo la regla de Ko. E.1. GO 81 Figura E.23: Trazas jugadas (25-26) Figura E.24: Jugadas (27-28) La figura E.24 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.25 se ven las trazas obtenidas para cada una de las situaciones anteriores. Como vemos en la jugada 27 coloca pieza el jugador negro ya que la jugada anterior no era válida. 82 APÉNDICE E. VALIDACIÓN Figura E.25: Trazas jugadas (27-28) Figura E.26: Jugada (29) La figura E.26 muestra la situación del tablero y los grupos para las jugadas siguientes. En la figura E.27 se ven las trazas obtenidas para cada una de las situaciones anteriores. Ahora si que puede colocar el jugador negro la pieza en esta posición, sin incumplir la regla del Ko, ya que la situación del tablero no corresponde a la de la jugada anterior (jugada 27). E.1. GO 83 Figura E.27: Trazas jugada (29) E.1.2. Recuento de puntuaciones Comprobemos ahora que el recuento de puntos es correcto. Para el recuento se usa un sistema de bloques pero en vez de bloques de piedras se crean bloques de casillas libres. Si ese conjunto de casillas libres está rodeado por piezas de un solo jugador ese bloque pertenecerá a ese jugador. Comenzaremos viendo la salida de bloques y puntuación para el ejemplo anterior. Figura E.28: Territorios del recuento de puntuaciones Tal y como mesta la figura E.28 y la figura E.29, hay 8 bloques de vacı́as. Algunos de ellos no pertenecen a ningún jugador y otros al jugador negro. En este ejemplo el jugador blanco no consigue ningún territorio. En el dibujo del tablero las intersecciones marcadas con a, indican que pertenecen a territorios del jugador negro y las marcadas con c a ninguno de los dos jugadores. Observemos que como durante la partida se habı́an capturado diversas piezas estas se tienen en cuenta para el cálculo de la puntuación final. Veamos ahora otro ejemplo. La situación final del tablero viene representada por la figura E.30, en ella las intersecciones marcadas por a pertenecen al territorio del jugador negro, las intersecciones marcadas por b al territorio del jugador blanco y las intersecciones marcadas por c a ninguno de 84 APÉNDICE E. VALIDACIÓN Figura E.29: Recuento de puntuaciones para el ejemplo anterior los dos jugadores. El código se ha elaborado de forma que no se produce ninguna captura, además lo omitimos debido a su gran extensión y carencia de interés. Figura E.30: Situación de prueba puntuación En la figura E.31 podemos ver la traza que se muestra por pantalla en lo que respecta al cálculo de territorios. Podemos ver los bloques de conjuntos vacı́os creados y su asignación a los jugadores. E.1. GO 85 Figura E.31: Bloques prueba territorios En la figura E.32 vemos las puntuaciones obtenidas tanto para modo de recuento japonés (arriba) como chino (abajo). Figura E.32: Puntuación prueba territorios 86 E.2. APÉNDICE E. VALIDACIÓN MCTS Como sistema de validación, por un lado se ha realizado un número determinado de simulaciones y comprobado que en cada uno de los pasos se realizan las acciones pertinentes. La clase dispone de un booleano que si es activado muestra poco a poco cada uno de los pasos de la simulación realizada. Activado este flag, los resultados se muestran poco a poco, avanzando conforme se pulse la tecla enter, haciendo ası́ más fácil seguir la simulación. El Apéndice D contiene un ejemplo de salida de simulación que se apoya en distintas imágenes para hacer más sencillo el seguimiento de este y su comprensión. Por otro lado, se ha forzado a que se diesen distintas situaciones “especiales” y visto si los resultados obtenidos son los adecuados. Estas situaciones corresponden a probar la parte de reutilización del árbol para diversas simulaciones y permitir realizar la simulación desde distintos puntos, es decir, todo lo relacionado con el apartado 5.2 de la memoria. Como el tamaño del tablero no interviene en estas pruebas, hemos tomado un tablero 2x2 debido a que a tamaño menor es mucho más sencillo seguir el ejemplo, e incluso podemos representar el árbol de forma gráfica. El nodo se extenderá cuando se hayan visitado al menos dos veces. E.2.1. Eficiencia del método La eficiencia del método MCTS no ha podido ser testada, ya que no se dispone de jugadores profesionales a quien enfrentarse, ni de ordenadores tan potentes como los usados en las competiciones reales, pero si que se ha visto que posee cierta inteligencia según las jugadas realizadas, sobre todo en tamaños de tablero pequeños o con tiempos grandes de procesado. En las pruebas realizadas a los usuarios, recogidas en la sección E.3.2 de este mismo capı́tulo, se realizan varias preguntas asociadas a la inteligencia proporcionada por el método al juego. Se observa que todos los usuarios consideran al jugador virtual como “inteligente”. E.2.2. Avanzar cuándo el árbol es vacı́o Partiendo de tablero vacı́o, veamos el efecto que produce las operaciones primero de avance y luego búsqueda en el árbol. La figura E.33 muestra el ejemplo gráfico de lo que sucede y la figura E.34 muestra la traza obtenida. Como vemos en la traza se mantiene lo que la figura representa. Figura E.33: Avance y búsqueda a partir de árbol vacı́o E.2. MCTS 87 Figura E.34: Traza del ejemplo (Avance y búsqueda a partir de árbol vacı́o) E.2.3. Avanzar cuándo el árbol es no vacı́o En este ejemplo, primero se ha realizado una búsqueda para que el árbol se cree y luego se ha avanzado sobre él. Finalmente se ha realizado otra búsqueda (después de avanzar) para verificar que todo ha funcionado correctamente. La figura E.35 muestra el ejemplo gráfico de lo que sucede y la figuraE.36 muestra la traza obtenida. Como vemos en la traza se mantiene lo que la figura representa. Como el número de simulaciones realizadas no es muy alto, no todos los nodos llegan a expandirse, si el nodo con el que se avanzas fuera uno que no llegó ha expandirse, funciona completamente igual, este nodo pasa a ser raı́z y al no tener hijos pues el árbol tendrá solo un nodo hasta que se llame a la función de simulación. Figura E.35: Avance y búsqueda a partir de árbol vacı́o 88 APÉNDICE E. VALIDACIÓN Figura E.36: Traza del ejemplo (Avance y búsqueda a partir de árbol vacı́o) E.2.4. Mezcla de las anteriores: Avanzar sobre árbol vacı́o y no vacı́o. Partiendo de tablero vacı́o, veamos el efecto que produce las operaciones primero de avance, luego búsqueda en el árbol, luego de nuevo búsqueda, avance y búsqueda otra vez. La figura E.37 muestra el ejemplo gráfico de lo que sucede (obviando la última búsqueda) y la figuraE.38 muestra la traza obtenida. Figura E.37: Avance y búsqueda a partir de árbol vacı́o E.3. APLICACIÓN 89 Figura E.38: Traza del ejemplo (Avance y búsqueda a partir de árbol vacı́o) E.3. Aplicación Las pruebas de la aplicación pueden dividirse en dos grandes bloques: pruebas de funcionamiento y pruebas de usabilidad. Veamos cada una de ellas. E.3.1. Pruebas de funcionamiento En estas pruebas se ha probado que la aplicación realiza las acciones que le fueron encomendadas. A continuación detallamos las principales pruebas realizadas. Navegación entre ventanas: Se comprobó que cada ventana se abre una ventana cuando se tiene que abrir o se cierra cuando se tiene que cerrar. Opciones seleccionadas: Las opciones de la partida de Go que se juega en la ventana de juego deben corresponder a las opciones seleccionadas en la ventana anterior (ventana de opciones). Para ello se han seleccionado las opciones y comprobado que efectivamente corresponden. En la ventana de juego viendo la interfaz se comprobó que el nombre del jugador, tamaño del tablero, color de piedras del jugador y tiempo lı́mite coincidı́a con el seleccionado. Y al finalizar la partida en la ventana emergente, que el tipo de recuento y la penalización correspondı́an con los seleccionados en la ventana de opciones. Esta prueba fue llevada a cabo en varias ocasiones probando a seleccionar opciones distintas a las anteriores y cambiando solo algunas de ellas. 90 APÉNDICE E. VALIDACIÓN Tiempo limite: Se comprobó que el contador del reloj se decrementaba en cada segundo y que al sobrepasar el tiempo lı́mite se pasase el turno al otro jugador. Acciones teclado: Se cliqueó en diversos puntos del tablero y se vio si actuaba correctamente: Cliqueando en intersecciones, en puntos muy cercanos a ellas, en zonas fuera del rango de estas o en los bordes del tablero. Todas ellas realizadas cuando es el turno del jugador humano y siendo el turno del ordenador. Además se probó que se visualizasen las piedras cuando fuera conveniente, mostrarse al colocar una pieza o desaparecer en caso de captura y que no dejase realizar movimientos prohibidos. Para ello se trabajo con un tablero pequeño, haciendo que estas situaciones se pudiesen dar más rápido, y se forzó a que ocurriesen para ası́ testear que efectivamente funcionaban como debı́an. Botón pasar: Se comprobó que si se cliqueaba el botón “Pasar” pasaba el turno al siguiente jugador, realizando también la acción correspondiente al juego del Go y finalizando la partida si se hubiera pasado anteriormente. E.3.2. Pruebas de usabilidad e inteligencia del juego El problema de probar esta aplicación, sobre todo la inteligencia del juego, es que se necesita gente conocedora del Go. Solo se han encontrado cuatro usuarios que sepan jugar, los cuales poseen un nivel bastante bajo (algunos acaban de aprender a jugar y otros ya lo tienen bastante olvidado). Los usuarios a los que se les ha realizado la evaluación coinciden en que la el programa es muy sencillo de usar, además de tener una interfaz muy agradable. El funcionamiento les parece bueno, considerando el jugador virtual bastante inteligente, dos de los usuarios no fueron capaces de vencer al ordenador en ninguna de las partidas jugadas. También se ha detectado que en tableros pequeños parece que realice jugadas más inteligentes, si es cierto que ninguno los usuarios ha jugado ninguna partida completa en tableros grandes y que en estas los efectos se ven reflejados muchas jugadas más tarde, por lo que tampoco es realmente fiable esta información. Para finalizar, todos han concluido con que les gusta la aplicación, eso sı́, algunos se sentı́an frustrados por no conseguir vencer ninguna partida. Apéndice F Manual de usuario En este apéndice se explica como usar la aplicación que permite jugar al Go enfrentándose al ordenador. Para ello veremos de que ventanas está formado, la navegación entre ellas y como realizar la interacción con el programa. F.1. Ventanas y navegación La interfaz de la aplicación está formada por cuatro ventanas: Ventana de inicio: Es el menú del juego. Ventana de opciones: Permite seleccionar las opciones de la partida a jugar. Ventana de juego: Es donde se juega la partida contra el ordenador. Ventana de reglas: Da información acerca de las reglas y opciones a elegir. La figura F.1 muestra el esquema de navegación entre ellas. Figura F.1: Navegación entre ventanas 91 92 APÉNDICE F. MANUAL DE USUARIO F.2. Ventana de inicio Esta ventana corresponde al menú del juego, se abre al ejecutar la aplicación y permanece abierta mientras se esté usando la aplicación. Figura F.2: Ventana de Inicio Desde ella se pueden realizar las siguientes acciones: Jugar una partida: Pulsando al botón “Jugar”. Esto hace que se abra la ventana de opciones explicada en la sección F.3 Acceder a las reglas del Go: Pulsando el botón “Reglas”. Esto hace que se abra la ventana de reglas explicada en la sección F.5 Abandonar el juego: Pulsando el botón “Salir”. Se abandona el juego cerrando todas las ventanas de la aplicación. F.3. Ventana de opciones En esta ventana se eligen las opciones antes de jugar la partida, acorde con la figura F.3. Las opciones a elegir son las siguientes: 1. Color de piedras del usuario: Pudiendo elegir entre Negro o Blanco marcando la opción correspondiente. 2. Sistema de recuento: Permite elegir entre el modo de recuento de puntuación Japonés o Chino marcando la casilla correspondiente. 3. Nombre del jugador: Permite insertar el nombre del jugador humano (usuario) 4. Tamaño del tablero: Se elige seleccionando el tamaño deseando sobre el desplegable. 5. Penalización: Permite decir que beneficio (puntuación extra) tiene el jugador blanco por empezar más tarde la partida, se elige seleccionando del desplegable la cantidad deseada. 6. Tiempo lı́mite por turno: Corresponde al tiempo del que dispone cada jugador para realizar una acción durante su turno del juego (Colocar pieza/Pasar). Además tiene estos tres botones: Continuar: Permite comenzar la partida de Go; para ello, cierra la ventana de opciones y abre la ventana de juego con las opciones seleccionadas. F.4. VENTANA DE JUEGO 93 Cancelar: Cierra la ventana de opciones. Ayuda: Abre la ventana de reglas en la sección de ayuda de opciones. Figura F.3: Ventana de opciones F.4. Ventana de juego Figura F.4: Ventana de juego Esta formada por ocho zonas (correspondiente a las zonas marcadas en la figura F.4): 1. Tablero: Corresponde al tablero del juego. Durante su turno, puede colocar una piedra pulsando sobre una intersección libre. Cuando sea el turno del ordenador este podrá colocar una piedra de su color. 94 APÉNDICE F. MANUAL DE USUARIO 2. Tiempo del usuario: Durante su turno, aparece sobre la zona marcada en 2 un temporizador, que indica el tiempo que le queda para realizar una acción. Pasado este tiempo (el temporizador marque cero) se interpretará como que su acción ha sido “Pasar”. 3. Tiempo del ordenador: Cuando sea el turno del ordenador, aparecerá sobre la zona marcada con 3 un temporizador, que indica el tiempo que le queda al ordenador para poder realizar su acción, de la misma forma que el tiempo de usuario. 4. Nº de piedras del ordenador capturadas: Indica cuantas piedras ha capturado el jugador al ordenador1 . 5. Nº de piedras del jugador capturadas: Indica cuantas piedras ha capturado el ordenador al jugador2 . 6. Mensaje de turno: Mensaje en el que indica de quien es el turno. 7. Mensaje de última jugada: Mensaje que indica cuál es la última jugada realizada. 8. Botones: Cliqueando en ellos realiza las acciones que indicamos a continuación: a) Pasar: Cuando es el turno del usuario pasa el turno y si es el turno del ordenador avisa de que no es posible pasar mediante la ventana emergente que muestra la figura F.5. b) Abandonar: Abandona la partida. c) Reglas: Abre la ventana de reglas. Figura F.5: Mensaje “No puedes pasar” La partida comienza nada más abrirse la ventana y por tanto también se pone en marcha el temporizador del jugador negro, que es el encargado de comenzar. Durante su turno cada jugador puede: Colocar una piedra: Cliqueando sobre las intersecciones libres del tablero, siempre que se cumplan las reglas de suicidio y Ko. Si la colocación de esta pieza incumple alguna de estas reglas, se avisa mediante una ventana emergente (como la de la figura F.6 para el caso de suicidio) y el tiempo sigue decrementándose. Figura F.6: Mensaje de suicidio Pasar: Cliqueando sobre el botón “Pasar” o esperando a que se acabe el tiempo del turno. 1 Junto al contador hay un cuenco sobre el que se irán añadiendo piedras (imágenes) dependiendo del nº de piedras capturadas. 2 Se añaden también imágenes de piedras dependiendo de la captura de éstas F.5. VENTANA DE REGLAS 95 Una vez hayan pasado consecutivamente los dos jugadores (usuario y ordenador) el programa muestra una ventana emergente (figura F.7) con el resultado de la partida y cierra la ventana de juego. Figura F.7: Mensaje resultado de la partida F.5. Ventana de reglas Esta formado por dos zonas tal y como muestra la figura F.8: 1. Directorio árbol: Tiene clasificada la información en forma de árbol, mediante carpetas desplegables y archivos. Si queremos abrir un archivo o carpeta, cliquearemos sobre el nombre de esta. Si queremos desplegar una carpeta para ver sus componentes, basta con hacer doble clic sobre ella o pulsar sobre el circulito que hay a la izquierda (éste último sirve tanto para desplegar como para recoger). 2. Texto: Muestra un texto u otro dependiendo de lo que se haya seleccionado en el directorio. Figura F.8: Ventana de reglas 96 APÉNDICE F. MANUAL DE USUARIO Glosario PFC: Proyecto fin de carreara GIGA: Grupo de Informática Gráfica Avanzada Negras / Negro: Jugador con piedras negras Blancas / Blanco: Jugador con piedras blancas kyu: grado de Go correspondiente a estudiante, abreviado k dan: grado de Go correspondiente a experto, abreviado d MCTS: Método de Monte-Carlo Tree Search (Búsqueda en árboles de Monte-Carlo) UCT: Upper Confidence bounds applied to Trees RF: Requisito funcional RNF: Requisito no funcional 97 98 APÉNDICE F. MANUAL DE USUARIO Bibliografı́a [1] G.M.J-B.Chaslot. Monte-Carlo Tree Search, http://www.unimaas.nl/games/files/phd/Chaslot thesis.pdf [2] Teorı́a de juegos http://es.wikipedia.org/wiki/Teor%C3%ADa de juegos [3] Algoritmos de juegos http://www.gran-angular.net/wpcontent/uploads/2008/07/algoritmos-de-juegos.pdf [4] Sistema determinista http://es.wikipedia.org/wiki/Sistema determinista [5] Sistema estocástico http://es.wikipedia.org/wiki/Estoc%C3%A1stico [6] Poda αβ http://es.wikipedia.org/wiki/Poda alfa-beta [7] Función de evaluación http://www.fenach.cl/docs/memoria/node47.html [8] Función de evaluación. Wikipedia. http://es.wikipedia.org/wiki/Funci%C3%B3n de evaluaci%C3%B3n [9] Go. Wikipedia española. http://es.wikipedia.org/wiki/Go [10] Go - Game. Wikipedia inglesa. http://en.wikipedia.org/wiki/Go %28game%29 [11] Computer Go. Wikipedia inglesa. http://en.wikipedia.org/wiki/Computer Go [12] Por qué aprender a jugar al go http://www.go.org.ar/page.php?name=porque [13] Camino interactivo hacia el Go http://www.thinkchile.com/playgo/ [14] KGS Go http://www.gokgs.com/tutorial/index.jsp [15] Asociación del Go go.org/index.php?page=main [16] Go rules. Wikipedia inglesa. http://en.wikipedia.org/wiki/Rules of Go#End 2 [17] Go vida y muerte http://es.wikipedia.org/wiki/Vida y muerte %28go%29 [18] Información completa http://es.wikipedia.org/wiki/Informaci%C3%B3n completa [19] Sensei’s Library, Web colaborativa sobre el juego del Go. http://senseis.xmp.net/ [20] Yenny Noa Vargas, Estrategias para mejorar el Balance entre Exploración y Explotación en Optimización de Enjambre de Partı́culas http://www.yorku.ca/sychen/research/theses/2011 Yenny MSc.pdf [21] Random Search Algorithms http://www.wpi.edu/Pubs/E-project/Available/Eproject-041808-104235/unrestricted/Random Search Algorithms Final Presentation.pdf de 99 por Andalucı́a Franklin 2010. Bassarsky http://www.andalucia- 100 BIBLIOGRAFÍA [22] Desviación estándar. Desviación tı́pica. http://es.wikipedia.org/wiki/Desviaci%C3%B3n est%C3%A1nda [23] Intervalo de confianza http://en.wikipedia.org/wiki/Confidence interval [24] G.M.J-B. Chaslot, S. Bakkes, I. Szita, and P. Spronck. Monte-Carlo Tree Search: A New Framework for Game AI. In Proceedings of the Fourth Artificial Intelligence and Interactive Digital Entertainment Conference. AAAI Press, Menlo Park, CA, 2008. http://sander.landofsand.com/publications/Monte-Carlo Tree Search A New Framework for Game AI.pdf [25] The Monte-Carlo Revolution in Go, JFFoS’2008: Japanese-French Frontiers of Science Symposium. http://remi.coulom.free.fr/JFFoS/JFFoS.pdf [26] The Java Tutorials http://docs.oracle.com/javase/tutorial/java/ [27] Lesson: Using Swing Components http://docs.oracle.com/javase/tutorial/uiswing/components/index.htm [28] G.M.J.B. Chaslot, M.H.M. Winands, and H.J. van den Herik. Parallel montecarlo tree search. Proceedings of the Conference on Computers and Games 2008 (CG 2008), volume 5131 of Lecture Notes in Computer Science, pages 60-71. Springer, Berlin Heidelberg, 2008. http://www.personeel.unimaas.nl/mwinands/documents/multithreadedMCTS2.pdf [29] G.M.J-B. Chaslot, S. de Jong, J-T. Saito, and J.W.H.M. Uiterwijk. Monte-Carlo Tree Search in Production Management Problems. In Proceedings of the 18th BeNeLux Conference on Artificial Intelligence, Namur, Belgium, pages 91-98, 2006. http://www.personeel.unimaas.nl/G-chaslot/papers/pmp.pdf [30] Maarten P.D. Schadd, Mark H.M. Winands, H. Jaap van den Herik, Guillaume M.JB. Chaslot, and Jos W.H.M. Uiterwijk. Single-Player Monte-Carlo Tree Search, 2008. http://www.informatik.uni-freiburg.de/∼ki/teaching/ws0910/gamesem/schadd-etal-2008.pdf [31] Christopher D.Rosin. Nested Rollout Policy Adaptation for Monte Carlo Tree Search, 2011. http://www.chrisrosin.com/rosin-ijcai11.pdf [32] Arpad Rimmel. Thesis : Improvements and Evaluation of the Monte-Carlo Tree Search Algorithm, 2009. http://www.lri.fr/∼rimmel/Files/ArpadRimmelThese.pdf [33] Julien Kloetzer, Hiroyuki Iida, and Bruno Bouzy. The Monte-Carlo Approach in Amazons, 2007. http://web.mi.parisdescartes.fr/∼bouzy/publications/KIBMCAmazons-CGW07.pdf [34] Mark H.M. Winands, Yngvi Björnsson, and Jahn-Takeshi to. Monte-Carlo Tree Search in Lines of Action, http://www.ru.is/faculty/yngvi/pdf/WinandsB10a.pdf [35] Levente Kocsis and Csaba Szepesvári. Bandit based Monte-Carlo Planning https://web.engr.oregonstate.edu/∼afern/classes/cs533/notes/uct.pdfhttps://web.engr.oregonstate.edu/ [36] Francois Van Lishout, Guillaume Chaslot, and Jos W.H.M. Uiterwijk. Monte-Carlo Tree Search in Backgammon http://orbi.ulg.ac.be/bitstream/2268/28469/1/vanlishout backgammon.pdf [37] I. Szita; G.M.J-B. Chaslot, P. Spronck. Monte-Carlo Tree Search in Settlers of Catan. In Proceedings of the Twelfth International Advances in Computer Games Conference (ACG’09), Pamplona, Spain, May 11-13, 2009. In Press. http://www.personeel.unimaas.nl/g-chaslot/papers/ACGSzitaChaslotSpronck.pdf Sai2010. BIBLIOGRAFÍA [38] 101 Hilmar Finnsson, Yngvi Björnsson. CadiaPlayer: Search-Control Techniques http://posgrado.escom.ipn.mx/biblioteca/CadiaPlayer%20SearchControl%20Techniques.pdf