Inicio > programas, sobre mí, videojocs > “Tres en ratlla” en Java

“Tres en ratlla” en Java

Fent servir un llibre d’Intel·ligència Artificial que he agafat avui de la biblioteca de la UdG, he programat un joc del Tres en Ratlla en Java, on es pot jugar contra la CPU.

El seu funcionament és simple: les caselles estan enumerades de l’1 al 9 (sent la primera fila les caselles 1, 2 i 3, la segona 4, 5 i 6, i la última 7, 8 i 9). Comença el jugador (que porta les “X”), i depenent de la casella que hagi triat, la CPU (que porta les “O”) triarà la millor opció per ella. El procediment que fa servir per a triar una casella és el següent:

  1. Busca si hi ha alguna casella que la pot fer guanyar. Si n’hi ha, mou la fitxa a aquesta casella.
  2. Si no, busca una casella que pugui fer guanyar al jugador. Si n’hi ha, mou la fitxa allà per evitar que el jugador guanyi en el pròxim torn.
  3. Si no hi ha cap d’aquestes caselles, tria una casella aleatòria d’entre les que encara estan buides.

A més, a cada jugada mostra el tauler amb l’estat actual de les fitxes. Quan guanya algú, mostra “jugador” o “CPU” com a guanyador i acaba la partida. Si s’emplena el tauler sense cap guanyador, diu que és un empat i acaba.

Altres detalls del codi (com per exemple per què estan codificades les caselles buides amb un 2, les caselles amb “X” amb un 3 i les caselles amb “O” amb un 5) es poden trobar al llibre d’on he tret la idea: Inteligencia Artificial (2ª edición), de Elaine Rich i Kevin Knight.

El codi us el penjo a continuació:

Main.java

package tresenraya;
import java.io.*;
import java.util.*;
/**
 *
 * @author johnny
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    static final int X=3;
    static final int O=5;
    static final int VACIA=2;

    public static void main(String[] args) throws Exception {
        int[] tablero=new int[9];
        int turno;
        int ganador=0;
        int casilla_entrada;
        boolean entrada_valida;
        Random rand=new Random();
        int puede_ganar_cpu, puede_ganar_player;
        BufferedReader buffer=new BufferedReader(new InputStreamReader(System.in));

        for (int i=0; i<9; i++) {
            tablero[i]=VACIA;
        }
        turno=1;
        pintar(tablero, 9);
        while (ganador==0 && turno<=9) {
            if (turno%2==1) {
                //Turno del jugador
                entrada_valida=false;
                do {
                    System.out.println("Casilla donde poner la ficha: ");
                    casilla_entrada=Integer.parseInt(buffer.readLine());
                    if (casilla_entrada>9 || casilla_entrada<=0) {
                        System.err.println("Casilla no valida");
                    } else {
                        casilla_entrada--;
                        if (tablero[casilla_entrada]!=VACIA) {
                            System.err.println("Casilla ocupada");
                        } else {
                            entrada_valida=true;
                        }
                    }
                } while (!entrada_valida);
                tablero[casilla_entrada]=X;
            } else {
                System.out.println("Pensando...");
                Thread.sleep(Math.abs(rand.nextInt()%3000)); //Para darle realismo ;-)
                puede_ganar_cpu=posibleTriunfo(tablero, 2);
                if (puede_ganar_cpu!=-1) {
                    tablero[puede_ganar_cpu]=O;
                } else {
                    puede_ganar_player=posibleTriunfo(tablero, 1);
                    if (puede_ganar_player!=-1) {
                        tablero[puede_ganar_player]=O;
                    } else {
                        do {
                            casilla_entrada=rand.nextInt()%9;
                            if (casilla_entrada<0) {
                                casilla_entrada=-casilla_entrada;
                            }
                        } while (tablero[casilla_entrada]!=VACIA);
                        tablero[casilla_entrada]=O;
                    }
                }
                //Turno de la maquina
            }
            pintar(tablero, 9);
            ganador=hanGanado(tablero);
            turno++;
        }
        if (turno>9 && ganador==0) {
            System.out.println("Empate");
        } else {
            if (ganador==1) {
                System.out.println("Ganador: jugador");
            } else {
                System.out.println("Ganador: CPU");
            }
        }
    }

    public static void pintar(int[] tablero, int tamano) {
        int i=0;
        char[] caracteres=new char[6];
        caracteres[VACIA]=' ';
        caracteres[X]='X';
        caracteres[O]='O';
        System.out.println("---------");
        while (i<tamano) {
            System.out.println("| "+caracteres[tablero[i]]+" "+caracteres[tablero[i+1]]+" "+caracteres[tablero[i+2]]+" |");
            i+=3;
        }
        System.out.println("---------");
    }

    public static int hanGanado(int[] tablero) {
        int ganador=0;
        int lineaX=27;
        int lineaO=125;
        int i=0;
        boolean encontrado=false;

        while (i<3 && !encontrado) {
            encontrado=tablero[i]*tablero[i+3]*tablero[i+6]==lineaX || tablero[i]*tablero[i+3]*tablero[i+6]==lineaO;
            i++;
        }
        if (!encontrado) {
            i=0;
            while (i<9 && !encontrado) {
                encontrado=tablero[i]*tablero[i+1]*tablero[i+2]==lineaX || tablero[i]*tablero[i+1]*tablero[i+2]==lineaO;
                i+=3;
            }
            if (!encontrado) {
                if (tablero[0]*tablero[4]*tablero[8]==lineaX || tablero[2]*tablero[4]*tablero[6]==lineaX) {
                    ganador=1;
                } else if (tablero[0]*tablero[4]*tablero[8]==lineaO || tablero[2]*tablero[4]*tablero[6]==lineaO) {
                    ganador=2;
                }
            } else {
                i-=3;
                if (tablero[i]*tablero[i+1]*tablero[i+2]==lineaX) {
                    ganador=1;
                } else {
                    ganador=2;
                }
            }
        } else {
            i--;
            if (tablero[i]*tablero[i+3]*tablero[i+6]==lineaX) {
                ganador=1;
            } else {
                ganador=2;
            }
        }
        return ganador;
    }

    public static int posibleTriunfo(int[] tablero, int jugador) {
        int resultado=0;
        boolean encontrado=false;
        int i=0;
        int devolver=-1;

        if (jugador==1) {
            resultado=18;
        } else {
            resultado=50;
        }
        while (i<3 && !encontrado) {
            encontrado=tablero[i]*tablero[i+3]*tablero[i+6]==resultado;
            i++;
        }
        if (!encontrado) {
            i=0;
            while (i<9 && !encontrado) {
                encontrado=tablero[i]*tablero[i+1]*tablero[i+2]==resultado;
                i+=3;
            }
            if (!encontrado) {
                encontrado=tablero[0]*tablero[4]*tablero[8]==resultado;
                if (!encontrado) {
                    encontrado=tablero[2]*tablero[4]*tablero[6]==resultado;
                    if (encontrado) {
                        if (tablero[2]==VACIA) {
                            devolver=2;
                        } else if (tablero[4]==VACIA) {
                            devolver=4;
                        } else {
                            devolver=6;
                        }
                    }
                } else {
                    if (tablero[0]==VACIA) {
                        devolver=0;
                    } else if (tablero[4]==VACIA) {
                        devolver=4;
                    } else {
                        devolver=8;
                    }
                }
            } else {
                i-=3;
                if (tablero[i]==VACIA) {
                    devolver=i;
                } else if (tablero[i+1]==VACIA) {
                    devolver=i+1;
                } else {
                    devolver=i+2;
                }
            }
        } else {
            i--;
            if (tablero[i]==VACIA) {
                devolver=i;
            } else if (tablero[i+3]==VACIA) {
                devolver=i+3;
            } else {
                devolver=i+6;
            }
        }
        return devolver;
    }

}
Categorías:programas, sobre mí, videojocs
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Comenta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: