Tictac Toe Minimax

August 25, 2018 | Author: Omar Haydar PM | Category: Economics Of Uncertainty, Game Theory, Leisure Activities, Gaming, Games Of Mental Skill
Share Embed Donate


Short Description

Descripción: Distribuidos Zarate...

Description

Instituto Politécnico Nacional Escuela Superior de Cómputo

Alumno: POSADAS MATIAS OMAR

Asignatura: DESARROLLO DE SISTEMAS DISTRIBUIDOS

Profesor: José Enrique Zarate Asunción

EXAMEN 01

Grupo: 4CM3

Tres en línea El tres en línea, también conocido como tres en raya, juego del gato, tatetí, triqui, totito, triqui traka, tres en gallo, michi,ceritos, equis cero o la vieja, 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. Una partida ganada por el primer jugador, X:

Una partida que termina en empate:

Los jugadores no tardan en descubrir que el juego perfecto termina en  empate sin importar con qué juega el primer jugador. Normalmente son los niños pequeños los que juegan al tres en raya: cuando ya han descubierto una estrategia imbatible se pasan a juegos más sofisticados, como el de puntos y cajas.

Estrategia óptima para el jugador X. La X en rojo marca el movimiento óptimo a realizar. Se empieza por la casilla superior izquierda. En el siguiente pas o se examina la casilla donde haya marcado el jugador O, que presenta una nueva jugada óptima y así sucesivamente.

1

La misma simplicidad del juego de tres en raya lo hacen ideal como herramienta pedagógica para enseñar los conceptos de teoría de juegosy la rama de inteligencia artificial que se encarga de la búsqueda deárboles de juego.

 Variantes

 Animación de una partida donde las X ganan en su cuarta movida al evitar que las O hagan una línea de tres en su tercer movimiento en la esquina inferior derecha.

Entre las variantes del tres en raya se encuentran: 

Tres en línea: Es una variante que se juega en un tablero con nueve puntos conectados vertical y horizontalmente, además de dos grandes diagonales. Cada jugador consta de tres piezas. Por turnos, cada uno coloca sus piezas, cuando todas están en el tablero, empiezan a moverse una intersección por turno. El primero que logra hacer una fila con sus tres piezas, gana.



Juegos

m ,n ,k : juego

generalizado en que se juega en un tablero de

m×n y

el objetivo es

conseguir k  en raya. 

k  en

raya tridimensional en un tablero de k ×k ×k . El tres en raya en un tablero de

3×3×3 no tiene mucho sentido: es fácil que el primer jugador gane, pues sólo tiene que empezar a poner su primera ficha en el centro del tablero. El cuatro en raya en un tablero de 4×4×4 es más interesante, aunque Patashnik demostró en 1980 yVictor  Allis en 1994 que el primer jugador puede forzar la victoria. Se puede generalizar a dimensiones superiores, pero el juego puede hacerse muy largo y se tiene el riesgo de no visualizar bien el tablero. Existe el video j uego llamado "3-D Tic-Tac-Toe" de Atari 2600 que consiste en el juego 4 el raya. 

Anti-k  en raya: El jugador que hace k en raya pierde. Si k  = 3, el juego termina en empate si los dos jugadores juegan bien.



Cinco en línea, un caso particular de juego

m,n,k  en

el que m=n=10 y k=5. Este juego

adquiere cierta complejidad ya que deben formarse líneas de cinco en un tablero que usualmente es de 10x10. 

Gato Polar , el tablero cambia por una distribución polar formada por cinco círculos concéntricos, subdividos por 4 diámetros, formando un total de 40 casillas. Con la misma mecánica del juego tradicional, los jugadores deben colocar, alternadamente, cículos y cruces en las casillas. Gana el primero que consiga una "línea" de 5. Las líneas pueden ser radiales, axiales o diagonales (unidas por un vértice).



Multijugador : se puede jugar entre varios jugadores (de preferencia un número par), en que alternadamente van colocando círculos y cruces.



Gato con Gravedad: se juega en un tablero "vertical" y los círculos y cruces sólo se pueden colocar sobre otros, de tal forma que van apareciendo columnas de círculos y cruces. Se gana cuando un jugador completa cuatro en línea.



Juego del Molino: Un juego antiguo del cual parece derivar el Tres en línea. Por cada fila de tres formada, se le quita una ficha al oponente.

Reglas Cada jugador solo debe de colocar su símbolo una vez por turno y no debe ser sobre una casilla ya jugada. En caso de que el jugador haga trampa el ganador será el otro. Se debe conseguir realizar una linea recta o diagonal por símbolo.

Minimax En teoría de juegos,  Minimax es un método de decisión para mini mizar la pérdida máx ima esperada en juegos con adversario y con información perfecta. Minimax es un algoritmo recursivo. El funcionamiento de Minimax puede resumirse como elegir el mejor movimiento para ti mismo suponiendo que tu contrincante escogerá el peor para ti.

 Algoritmo Minimax con movimientos alternativos

Pasos del algoritmo Minimax: 1. Generación del árbol de juego. Se generarán todos los nodos hasta llegar a un estado terminal. 2. Cálculo de los valores de la función de utilidad para cada nodo terminal. 3. Calcular el valor de los nodos superiores a partir del valor de los inferiores. Según nivel si es MAX o MIN se elegirán los valores mínimos y máximos representando los movimientos del jugador y del oponente, de ahí el nombre de Minimax. 4. Elegir la jugada valorando los valores que han llegado al nivel superior.

El algoritmo explorará los nodos del árbol asignándoles un valor numérico mediante una función de evaluación, empezando por los nodos terminales y subiendo hacia la raíz. La función de utilidad definirá lo buena que es la posición para un jugador cuando la alcanza. En el caso del ajedrez los posibles valores son (+1,0,-1) que se corresponden con ganar, empatar y perder respectivamente. En el caso del backgammon los posibles valores tendrán un rango de [+192,-192], correspondiéndose con el valor de las fichas. Para cada juego pueden ser diferentes. Si Minimax se enfrenta con el dilema del prisionero escogerá siempre la opción con la cual maximiza su resultado suponiendo que el contrincante intenta minimizarlo y hacernos perder. Desarrollo. Se muestra la parte del algoritmo minimax package gato_minimax;

import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject;

/** * * @author Omar */ public class Minimax extends UnicastRemoteObject implements I_Minimax {

public static int tiradas = 0; NodoGato arbol = new NodoGato(); int[] tablero;

//obtiene las jugadas que faltan, de acuerdo a las casillas vacias @Override public int movDisponibles( int[] tablero ) throws RemoteException{ int mov = 0;

for ( int i = 0; i < 9; i ++ ) if ( tablero[i] == 0 ) mov++;

return mov; }

//recupera los cuadros vacios del tablero @Override public int[] posVacias( int[] tablero ) throws RemoteException{

int[] indices = new int[movDisponibles(tablero)]; int indice = 0;

//recorrer y guardarlos indices for ( int i = 0; i < 9; i ++ ){ if ( tablero[i] == 0 ){ indices[indice] = i; indice++; } } return indices; }

//gestiona cada movimiento hecho, ya se del usuario o la computadora @Override public int movimiento( int[] tablero ) throws RemoteException{

this.tablero = tablero; tiradas ++;

//copiamos el tablero al arbol for ( int i = 0; i < 9; i ++ ) this.arbol.tablero[i] = this.tablero[i];

//movimiento que hara la computadora movComputadora( arbol );

return arbol.mejorMovimiento; }

//se crean los nodos del arbol @Override

public void movComputadora( NodoGato raiz ) throws RemoteException{

int movimientos = movDisponibles(raiz.tablero); int indices[] = posVacias(raiz.tablero); int Max, Min;

//se inicia el nodo raiz.nodos = new NodoGato[movimientos];

//comprueba si ya existe un ganador int ganador = terminado(raiz.tablero); if ( ganador == 1 ) ganador = -1; else if ( ganador == 2 ) ganador = 1;

if ( ganador!= 0 || movimientos == 0){ raiz.ganador = ganador; }else{

//datos de los nodos hijos for( int i = 0; i < movimientos; i ++ ){

/*Inicializamos los nodos hijos del arbol.*/ raiz.nodos[i] = new NodoGato();

/*Les pasamos su tablero.*/ for ( int j = 0; j < 9; j ++ ) raiz.nodos[i].tablero[j] = raiz.tablero[j];

/*Creamos los diferentes movimientos posibles.*/ if ( raiz.miTurno ) raiz.nodos[i].tablero[indices[i]] = 1; else raiz.nodos[i].tablero[indices[i]] = 2;

/*Cambiamos el turno de los hijos*/ raiz.nodos[i].miTurno = !raiz.miTurno;

/*Guardamos el indice de su movimiento.*/ raiz.nodos[i].indice = indices[i];

movComputadora(raiz.nodos[i]);

}

/*Minimax*/ if (!raiz.miTurno) raiz.ganador = max(raiz); else raiz.ganador = min(raiz);

}

}

//se calcula el maximo de los nodos hijos de min*/ @Override public int max( NodoGato raiz ) throws RemoteException{ int Max = -111; //maximo para la computadora, buscamos el valor donde gane. for (int i = 0; i < raiz.nodos.length; i++){ /*Preguntamos por un nodo con un valor alto MAX*/ if (raiz.nodos[i].ganador > Max){ /*Lo asignamos y pasamos el mejor movimiento a la raiz.*/ Max = raiz.nodos[i].ganador; raiz.mejorMovimiento = raiz.nodos[i].indice; /*Terminamos de buscar.*/ if (Max == 1) break; } }

/*Borramos los nodos.*/

raiz.nodos = null;

return Max; }

//se calcula el minimo de los nodos hijos de MAX.*/ @Override public int min( NodoGato raiz ) throws RemoteException{ int Min = 111; //minimo para el jugador for (int i = 0; i < raiz.nodos.length; i++) if (raiz.nodos[i].ganador < Min ){ Min = raiz.nodos[i].ganador; raiz.mejorMovimiento = raiz.nodos[i].indice; if (Min == -1) break; }

/*Borramos los nodos.*/ raiz.nodos = null;

return Min; }

//Regresa 0 si nadie gana, 1 si gana jugador 1 y 2 si gana la computadora @Override public int terminado( int[] tablero ) throws RemoteException{

//linea en las filas if ( tablero[0] == tablero[1] && tablero[0] == tablero[2] && tablero[0] != 0 ) return tablero[0]; else if ( tablero[3] == tablero[4] && tablero[3] == tablero[5] && tablero[3] != 0 ) return tablero[3]; else if ( tablero[6] == tablero[7] && tablero[6]== tablero[8] && tablero[6] != 0 ) return tablero[6]; //linea en las columnas

else if( tablero[0] == tablero[3] && tablero[0] == tablero[6] && tablero[0] != 0 ) return tablero[0]; else if ( tablero[1] == tablero[4] && tablero[1] == tablero[7] && tablero[1] != 0 ) return tablero[1]; else if ( tablero[2] == tablero[5] && tablero[2] == tablero[8] && tablero[2] != 0 ) return tablero[2]; //lineas diagonales else if ( tablero[0] == tablero[4] && tablero[0] == tablero[8] && tablero[0] !=0 ) return tablero[0]; else if ( tablero[2] == tablero[4] && tablero[2] == tablero[6] && tablero[2] != 0 ) return tablero[2];

return 0;

}

public Minimax() throws RemoteException{ super(); }

} Se muestra la parte de los nodos: package gato_minimax;

/** * * @author Omar */

//arbol de movimientos public class NodoGato {

int mejorMovimiento;

//Nodos hijos.

NodoGato nodos[];

//Tablero del juego public int tablero[];

//turno de la computadora boolean miTurno = false;

//indice de la pocision int indice;

int ganador = 0;

NodoGato() {

//incializar variables tablero = new int[9];

}

} Se muestra la parte del servidor RMI: package gato_minimax;

import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.util.logging.Level; import java.util.logging.Logger;

/** * * @author Omar

 */ public class ServidorRMI {

public static void main(String[] args) {

try { I_Minimax minmax; LocateRegistry.createRegistry(1099); minmax = new Minimax(); Naming.bind("ServidorGato", minmax); System.out.println("Servidor funcionando...");

} catch (RemoteException ex) { Logger.getLogger(ServidorRMI.class.getName()).log(Level.SEVERE, null, ex); } catch (MalformedURLException ex) { Logger.getLogger(ServidorRMI.class.getName()).log(Level.SEVERE, null, ex); } catch (AlreadyBoundException ex) { Logger.getLogger(ServidorRMI.class.getName()).log(Level.SEVERE, null, ex); }

}

} Pruebas:

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF