P. 1
El Problema Del Tres en Raya

El Problema Del Tres en Raya

|Views: 1.581|Likes:

More info:

Published by: Charming Pilares Leon on Nov 08, 2010
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

06/14/2013

pdf

text

original

El problema del Tres en raya

Aliaga Cornejo María Eugenia xmary17@gmail.com Pilares León Charming Catherine charm.cathpl@gmail.com

Universidad Nacional de San Agustin, Arequipa Escuela Profesional de Ingeniería de Sistemas

Resumen Los orígenes del Tres en Raya se remontan a hace mucho tiempo en un país del lejano Oriente. Muchos autores piensan que el Tres en Raya (el llamado Tic Tac Toe en inglés) se originó en China, como muchos otros juegos de mesa. El tres en raya es un «juego de lápiz y papel» entre dos jugadores: O y X, que marcan los espacios de un tablero de 3×3 alternadamente. Un jugador gana si consigue tener una línea de tres de sus símbolos: la línea puede ser horizontal, vertical o diagonal.

1.

INTRODUCCIÓN El juego Tres en raya ha sido propuesto desde sus inicios como un juego entre adversarios (dos jugadores) y con manejo de fichas o simplemente a lápiz y papel. Con el tiempo esta idea ha ido evolucionando y ha tenido un gran impacto con la computación, debido a que se trata de un problema de razonamiento y estrategia, y que puede ser utilizado como base introductoria a lo que es Inteligencia Artificial. El proceso de razonamiento va enfocado principalmente a que el jugador escoja la mejor jugada, debido a que el objeto de búsqueda es encontrar el camino desde un estado de punto de partida a un estado objetivo, lo que lo hace un problema algo complicado. Ante este problema es que se han planteado diferentes algoritmos para su resolución, siendo la mejor opción la utilización del algoritmo Minimax, el que será detallado y desarrollado en el transcurso de este documento.

2.

DEFINICIÓN DEL PROBLEMA El objetivo del tres en raya, es que dado dos jugadores: O y X, marquen los espacios de un tablero de 3×3 alternadamente hasta conseguir que un ganador gane, esto sucede cuando se consigue tener una línea de tres símbolos (el símbolo varía dependiendo del jugador) que puede ser horizontal, vertical o diagonal. Este problema tiene diferentes propuestas de solución, las que detallaremos a continuación:

Solución #1 Una primera solución directa a este juego podría ser la de almacenar en un vector las 19.693 (39) posibilidades de un tablero de 3 x 3 con tres valores posibles en cada casilla (vacío-X-O), así como las correspondientes jugadas sucesoras. Para realizar una jugada, bastaría con acceder a la posición del tablero actual y la jugada sucesora correspondiente.

1

Su estrategia es más fácil de comprender y realizar cambios. Aunque es menos eficiente que la solución anterior en términos de tiempo. y una estimación de la probabilidad de que esa jugada lleve a la victoria. Para ello se define variables constantes que determinen el estado del juego. PARAR. Esta última solución cuenta con un algoritmo.alguien debe realizar el pesado trabajo de introducir todas las jugadas y sus sucesoras . Sin embargo. y un 2 . es decir. donde se puede relacionar con el siguiente movimiento. se analiza el posible triunfo a partir de un estado del tablero dado. el cual inspecciona secuencias de movimientos intentando maximizar la probabilidad de victoria. por ejemplo a tres dimensiones. considerando si la jugada produce la victoria. Solución #3 Implementar una estructura que contenga el tablero actual.Las desventajas de este eficiente programa son bastante obvias: . y en caso contrario considerando todos los movimientos que el oponente puede realizar asumiendo que éste elegirá el peor para nosotros. Para decidir la siguiente jugada se tienen en cuenta las posiciones de tablero que resultan de cada movimiento posible. El tablero es representado como una lista de posiciones del tablero. aunque el programador debe comprender la totalidad de la estrategia de antemano. Necesita mucho más tiempo que los demás. MODELADO DEL PROBLEMA El problema del Tres en raya se enuncia inicialmente así: Empieza inicialmente con un tablero de 3x3 que es representado por un vector de nueve componentes.necesita gran cantidad de memoria .el juego no se puede ampliar. Solución #2 Considerando una estrategia para cada turno de jugador. en este caso fue construida una estructura vector. además también se han considerado otros estados propios del desarrollo del juego propiamente dicho: COMENZAR. o no lo está. EMPATE. tiene la ventaja que es más eficiente en términos de espacio. así como una lista de posiciones del tablero que podrían ser el próximo movimiento. Se decide la posición que corresponde a la mejor jugada. es superior a las demás soluciones pues podría ser ampliado para manipular juegos más complicados. ya que debe realizar una búsqueda en una estructura de posibilidades antes de realizar cada movimiento. GANADOR_JUEGO_X. JUGANDO. para así calcular si la partida ha finalizado o está aún en proceso. 3. estado: GANADOR_JUEGO_O. donde las componentes del vector se corresponden con las posiciones del tablero de la siguiente forma: Figura 1: Representación del tablero También consideramos una variable que determine la posición dentro del vector para calcular si ese campo está vacío.

número que representa una estimación de la probabilidad de que la jugada lleve a la victoria al jugador que mueve. considerar todos los posibles movimientos que el oponente puede realizar en la siguiente jugada. realizar la jugada que corresponda a esa posición. Para determinar cómo es evaluado cada nodo o estado de la jugada. Cualquier puesto que tenga la jugada. - Para determinar cómo son dadas las jugadas simulamos el compartimiento de cada una: Figura 3: Distribución de las jugadas 3 . se debe tener en cuenta las posiciones del tablero que resultarán de cada posible movimiento. asignarla al nodo que se está considerando. Asumir que el oponente realizará este movimiento. se realiza una evaluación por cada jugada. Si ocurre catalogarla como la mejor dándole el mejor puesto en la clasificación. Aplicación del Algoritmo Para poder decidir la siguiente jugada. y asignar la clasificación de mejor movimiento a la posición actual. de la siguiente manera: Figura 2: Evaluación jugada Y así determinamos que posibilidades existe para realizar la siguiente jugada. se realiza para cada una de ellas la siguiente: Ver si se produce la victoria. El mejor nodo es el que resulte con un puesto más alto. En caso contrario. dependiendo de la posición de esta jugada inicial. Decidir qué posición es la mejor. Para decidir cuál de todas las posibles posiciones es mejor.

Para la resolución de este problema se ha aplicado el algoritmo Minimax. Simbolo_actual = _jugador. } else if(val == mejor_valor) { mejores_movimientos[++indice]=lista_movimientos. como ya se había mencionado previamente es Minimax. RESOLUCIÓN En base al modelo presentado. donde se almacenan las movidas realizadas por el jugador. para luego determinar los resultados en base a las posiciones del tablero ocupadas. std::list<int> lista_movimientos. jugador _jugador) { int mejor_valor = -ORDENADOR. pesimista y heurística Indeciso desarrollado a partir del juego de tener que resolver el valor de una junta sin terminar / indecidible que resulta de un control de mayor profundidad para reducir el tiempo de búsqueda. la estructura principal usada es un array de listas. generar_movimientos(_tablero. Como el juego es del tipo «Humano vs computadora». int indice = 0.simbolo. } _tablero[lista_movimientos. se ha determinado considerar las variables: +ORDENADOR y –ORDENADOR. este algoritmo inspecciona varias secuencias de movimientos para encontrar aquella que lleva a la victoria. int val = movimiento_Min(_tablero.El algoritmo utilizado.pop_front(). El lenguaje de programación utilizado es C++ bajo Visual Studio. } return mejores_movimientos[indice]. Intenta maximizar la probabilidad de victoria. lista_movimientos). _jugador). Con el fin de aplicar este algoritmo es necesario que se genere una lista de movimientos.front()]= _jugador. 4. Una vez implementado el algoritmo queda de la siguiente manera: int MiniMax(char _tablero[9]. que calculara si el computador está ganando o está perdiendo. debido a su facilidad en manipulación de objetos y estructuras. este recibe como parámetros un tablero definido con las 9 posiciones de posible juego descritas anteriormente y un jugador que realizara el movimiento respectivo. /* Utilización de la estructura */ std::list<int> lista_movimientos. if(val > mejor_valor) { mejor_valor = val. mediante la suposición de que el oponente intentará minimizar dicha probabilidad. char mejores_movimientos[9] = {0}.simbolo. indice = 0. } En esta implementación del algoritmo Minimax.front()+ 1. o simplemente el valor 0 si se trata de un empate La variación entre el optimista. 4 . las heurísticas utilizadas en este estudio fueron diseñados para ser simples. Se parte de la idea inicial de tener el tablero con sus respectivas posiciones. mejores_movimientos[indice]=lista_movimientos. se ha utilizado dos estructuras de datos para la representación del árbol formado por este algoritmo.front()+1. Heurística Para este problema. while(!lista_movimientos.empty()) { _tablero[lista_movimientos.front()]= 0. se ha implementado en un lenguaje determinado para que pueda ser resuelto. char mejores_movimientos[9] = {0}. lista_movimientos.

front()] = Simbolo_actual. lista_movimientos). std::list<int> &lista_movimientos) { for(int i = 0.simbolo == 'X') Simbolo_actual = 'O' else Simbolo_actual = 'X'. lista_movimientos.pop_front(). } } } Donde se muestra claramente que cada movimiento realizado es almacenado en la lista creada. int val = movimiento_Min(_tablero. lista_movimientos). if(val > mejor_valor) { mejor_valor = val.empty()) { if(_jugador. } return mejor_valor. std::list<int> lista_movimientos. _jugador). _jugador). i < 9. int val = movimiento_Max(_tablero. } _tablero[lista_movimientos.empty()) { if (_jugador. lo que corresponde a calcular el mínimo y máximo valor. generar_movimientos(_tablero. Dicha función esta implementada como: void generar_movimientos(char _tablero[9]. generar_movimientos(_tablero. _tablero[lista_movimientos.push_back(i). std::list<int> lista_movimientos. lista_movimientos). } _tablero[lista_movimientos.pop_front().front()] = 0. jugador _jugador) { int estado_tablero = evaluar_estado_tablero(_tablero. while(!lista_movimientos. if(estado_tablero != -1) { return estado_tablero. esta implementada basándose en dos conceptos de este algoritmo. mediante la función propia del tipo lista: lista_movimientos. _jugador). if(val < mejor_valor) { mejor_valor = val.En esta función se llama a la función: generar_movimientos(_tablero.simbolo == 'X') Simbolo_actual = 'X' else Simbolo_actual = 'O'. if(estado_tablero != -1) { return estado_tablero.front()] = 0. } return mejor_valor. Por ello que se han implementado como otras funciones: // Encontrar el mejor movimiento para minimizar int movimiento_Min(char _tablero[9]. ++i) { if(_tablero[i] == 0) { lista_movimientos. _jugador). } 5 . } int mejor_valor = +ORDENADOR. jugador _jugador) { int estado_tablero = evaluar_estado_tablero(_tablero. } // Encontrar el mejor movimiento para maximizar int movimiento_Max(char _tablero[9]. } int mejor_valor = -ORDENADOR.push_back(i).front()] = Simbolo_actual. lista_movimientos. Esta función que representa el comportamiento del algoritmo Minimax. while(!lista_movimientos. _tablero[lista_movimientos.

REFERENCIAS [1] [2] [3] Martha Mercaldi. Este código nos ejecutará el resultado para el juego de modo consola: Figura 4: Resultado de ejecución 5. 2006 [4] 6 . Jozsef Toth. este término especifica que tanto de entrenamiento se le ha asignado al computador para tal juego. Using Heuristics to Evaluate the Playability of Games. Katarzyna Wilamowska General Heuristic for Tic-Tac-Toe. Buro. MTU Department of Computer Science.Para el cálculo de la profundidad del árbol generado por el algoritmo. Schaeffer. Minimax Search in Computers and Games. Heuristic Search. Chapter 4 Heather Desurvire. Martin Caplan. Hauk. 2004 Desconocido. es que se ha definido la función: int obtener_nivel_juego() Esta función determina el nivel de dificultad del juego.

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->