tictac toe minimax

14
  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

Upload: omar-pm

Post on 07-Oct-2015

37 views

Category:

Documents


0 download

DESCRIPTION

Distribuidos Zarate

TRANSCRIPT

  • Instituto Politcnico Nacional

    Escuela Superior de Cmputo

    Alumno:

    POSADAS MATIAS OMAR

    Asignatura:

    DESARROLLO

    DE SISTEMAS DISTRIBUIDOS

    Profesor:

    Jos Enrique Zarate Asuncin

    EXAMEN 01

    Grupo:

    4CM3

  • Tres en lnea El tres en lnea, tambin 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 lpiz y papel entre dos jugadores: O y X, que marcan los espacios de un tablero de 33 alternadamente. Un jugador gana si consigue tener una lnea de tres de sus smbolos: la lnea 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 nios pequeos los que juegan al tres en raya: cuando ya han descubierto una estrategia imbatible se pasan a juegos ms 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 paso 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 pedaggica para ensear los conceptos de teora de juegosy la rama de inteligencia artificial que se encarga de la bsqueda derboles de juego.

    Variantes

    http://es.wikipedia.org/wiki/Juego_de_l%C3%A1piz_y_papelhttp://es.wikipedia.org/wiki/Tablero_de_juegohttp://es.wikipedia.org/w/index.php?title=Empate&action=edit&redlink=1http://es.wikipedia.org/wiki/Timbiriche_(juego)http://es.wikipedia.org/wiki/Tres_en_l%C3%ADnea#cite_note-xkcd-1http://es.wikipedia.org/wiki/Teor%C3%ADa_de_juegoshttp://es.wikipedia.org/wiki/Inteligencia_artificialhttp://es.wikipedia.org/wiki/%C3%81rbol_de_juegohttp://commons.wikimedia.org/wiki/File:Tic-tac-toe-game-1.pnghttp://commons.wikimedia.org/wiki/File:Tic-tac-toe-game-2.pnghttp://commons.wikimedia.org/wiki/File:Tictactoe-X.svghttp://commons.wikimedia.org/wiki/File:Tic-tac-toe-game-1.pnghttp://commons.wikimedia.org/wiki/File:Tic-tac-toe-game-2.pnghttp://commons.wikimedia.org/wiki/File:Tictactoe-X.svghttp://commons.wikimedia.org/wiki/File:Tic-tac-toe-game-1.pnghttp://commons.wikimedia.org/wiki/File:Tic-tac-toe-game-2.pnghttp://commons.wikimedia.org/wiki/File:Tictactoe-X.svg

  • Animacin de una partida donde las X ganan en su cuarta movida al evitar que las O hagan una lnea de

    tres en su tercer movimiento en la esquina inferior derecha.

    Entre las variantes del tres en raya se encuentran:

    Tres en lnea: Es una variante que se juega en un tablero con nueve puntos conectados

    vertical y horizontalmente, adems de dos grandes diagonales. Cada jugador consta de

    tres piezas. Por turnos, cada uno coloca sus piezas, cuando todas estn en el tablero,

    empiezan a moverse una interseccin 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 mn y el objetivo es

    conseguir k en raya.

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

    333 no tiene mucho sentido: es fcil que el primer jugador gane, pues slo tiene que

    empezar a poner su primera ficha en el centro del tablero. El cuatro en raya en un tablero

    de 444 es ms 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 juego 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 lnea, 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 lneas de cinco en un tablero que

    usualmente es de 10x10.

    Gato Polar, el tablero cambia por una distribucin polar formada por cinco crculos

    concntricos, subdividos por 4 dimetros, formando un total de 40 casillas. Con la misma

    mecnica del juego tradicional, los jugadores deben colocar, alternadamente, cculos y

    cruces en las casillas. Gana el primero que consiga una "lnea" de 5. Las lneas pueden

    ser radiales, axiales o diagonales (unidas por un vrtice).

    http://es.wikipedia.org/w/index.php?title=Juego_m,n,k&action=edit&redlink=1http://es.wikipedia.org/w/index.php?title=Patashnik&action=edit&redlink=1http://es.wikipedia.org/w/index.php?title=Juegos_de_tablero_resueltos&action=edit&redlink=1http://es.wikipedia.org/wiki/1980http://es.wikipedia.org/w/index.php?title=Victor_Allis&action=edit&redlink=1http://es.wikipedia.org/w/index.php?title=Victor_Allis&action=edit&redlink=1http://es.wikipedia.org/wiki/1994http://es.wikipedia.org/wiki/Atarihttp://commons.wikimedia.org/wiki/File:Tictactoe1.gif

  • Multijugador: se puede jugar entre varios jugadores (de preferencia un nmero par), en

    que alternadamente van colocando crculos y cruces.

    Gato con Gravedad: se juega en un tablero "vertical" y los crculos y cruces slo se

    pueden colocar sobre otros, de tal forma que van apareciendo columnas de crculos y

    cruces. Se gana cuando un jugador completa cuatro en lnea.

    Juego del Molino: Un juego antiguo del cual parece derivar el Tres en lnea. Por cada fila

    de tres formada, se le quita una ficha al oponente.

    Reglas

    Cada jugador solo debe de colocar su smbolo 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 smbolo.

    Minimax En teora de juegos, Minimax es un mtodo de decisin para minimizar la prdida mxima esperada en juegos con adversario y con informacin 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. Generacin del rbol de juego. Se generarn todos los nodos hasta llegar a un estado

    terminal.

    2. Clculo de los valores de la funcin de utilidad para cada nodo terminal.

    3. Calcular el valor de los nodos superiores a partir del valor de los inferiores. Segn nivel

    si es MAX o MIN se elegirn los valores mnimos y mximos 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.

    http://es.wikipedia.org/wiki/Juego_del_Molinohttp://es.wikipedia.org/wiki/Teor%C3%ADa_de_juegoshttp://es.wikipedia.org/wiki/%C3%81rbol_de_juegohttp://commons.wikimedia.org/wiki/File:Minimax.svg

  • El algoritmo explorar los nodos del rbol asignndoles un valor numrico mediante una funcin de evaluacin, empezando por los nodos terminales y subiendo hacia la raz. La funcin de utilidad definir lo buena que es la posicin 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 tendrn un rango de [+192,-192], correspondindose con el valor de las fichas. Para cada juego pueden ser diferentes.

    Si Minimax se enfrenta con el dilema del prisionero escoger siempre la opcin 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;

    }

    http://es.wikipedia.org/wiki/Funci%C3%B3n_de_evaluaci%C3%B3nhttp://es.wikipedia.org/wiki/Ajedrezhttp://es.wikipedia.org/wiki/Backgammonhttp://es.wikipedia.org/wiki/Dilema_del_prisionero

  • //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: