package clases; import java.util.Arrays; import java.util.ArrayList; import java.util.List; import java.util.Random; import clases.Carta; //import com.roshka.bootcamp004.poker.MyClass; public class Poker { // TH, TC, 5S, 5H, AD, AH, 2S public String mejorJugada(Carta[] mano) { ArrayList candidatas = new ArrayList(); ArrayList mejores = new ArrayList(); String mejoresString=""; Carta[] cartas = mano; //Crea una mano de 5 cartas que va a seguir igual siempre Carta [] manoPrincipal = new Carta[5]; //Crea una mano de 5 cartas que va a variar para crear las //distintas combinaciones Carta [] manoVariante = new Carta[5]; //Carga las primeras 5 cartas en la mano for (int i = 0; i < 5; i++) { manoPrincipal[i] = new Carta(cartas[i].valor+cartas[i].palo); } manoVariante = manoPrincipal.clone(); //Se agrega la primera combinación a las manos candidatas candidatas.add(manoVariante.clone()); //Las dos ultimas cartas las guarda en variables diferentes Carta x = cartas[5]; Carta y = cartas[6]; //Se crean las combinaciones for (int i = 0; i < 5; i++) { //Rota la x manoVariante[i] = x; //Agrego una copia de la mano variante para no tener problemas //Con la modificacion de los valores //Por el tema de paso por referencia candidatas.add(manoVariante.clone()); //Es para no repetir combinaciones. Esta repeticion //se da en la cuarta iteración //if(i!=4){ for(int j = i; j < 5; j++){ //Se usa una variable auxiliar para volver a poner el valor //que se cambió como estaba Carta aux = manoVariante[j]; //Rota la y cuando la x está rotando manoVariante[j]= y; //Se agrega una copia a las candidatas candidatas.add(manoVariante.clone()); //Vuelve la mano variante a su estado original manoVariante[j] = aux; } /*}else{ //Solo faltaría agregar una rotación, cuando la y está al final manoVariante[i]=y; candidatas.add(manoVariante.clone()); }*/ manoVariante = manoPrincipal.clone(); } /* for (int i = 0; i < candidatas.size(); i++) { System.out.println("Combinacion número: "+(i+1)); System.out.println(candidatas.get(i)[0].valor+candidatas.get(i)[0].palo); System.out.println(candidatas.get(i)[1].valor+candidatas.get(i)[1].palo); System.out.println(candidatas.get(i)[2].valor+candidatas.get(i)[2].palo); System.out.println(candidatas.get(i)[3].valor+candidatas.get(i)[3].palo); System.out.println(candidatas.get(i)[4].valor+candidatas.get(i)[4].palo); System.out.println("******"); } */ //System.out.println(candidatas.size()); //Crea una instancia de MyClass, que contiene //el método que elige cuál es la mejor jugada //MyClass mc = new MyClass(); //Crea un vector string con los índices de los ganadores String[] mejoresCombinaciones = ganadores(candidatas).split(" "); //System.out.println("Cantidad de ganadores: "+ mejoresCombinaciones.length); //System.out.println("Indice de los ganadores: "+mc.ganadores(candidatas)); //Imprime las mejores combinaciones /*for (int j = 0; j < mejoresCombinaciones.length; j++) { //Convierte los indices de los ganadores que están en String //a int int index = Integer.parseInt(mejoresCombinaciones[j]); for (int i = 0; i < 5; i++) { System.out.print(candidatas.get(index)[i].valor+candidatas.get(index)[i].palo+" "); } System.out.println(); }*/ for (int j = 0; j < mejoresCombinaciones.length; j++) { //Convierte los indices de los ganadores que están en String //a int int index = Integer.parseInt(mejoresCombinaciones[j]); mejores.add(candidatas.get(index).clone()); } //Carga mejoresString, que contiene los resultados del vector mejores //pero en String, todo concatenado //También imprime el contenido de "mejores" for (int j = 0; j < mejores.size(); j++) { //Convierte los indices de los ganadores que están en String //a int //int index = Integer.parseInt(mejoresCombinaciones[j]); for (int i = 0; i < 5; i++) { mejoresString += mejores.get(j)[i].valor+mejores.get(j)[i].palo; //System.out.print(candidatas.get(j)[i].valor+candidatas.get(j)[i].palo); if(i!=4){ //System.out.print(","); mejoresString += ","; } } //System.out.println(); if(j!=mejores.size()-1) mejoresString += ";"; } return mejoresString; //return "AD,AH,TH,TC,5S;AD,AH,TH,TC,5H"; } public String ganadores(List jugadas) { //System.out.println("Cantidad de jugadas: " + jugadas.size()); ArrayList ganadores = new ArrayList(); //Indica que es la primera mano boolean esPrimero=true; //Array para almacenar los índices ArrayList indices = new ArrayList(); //Contador que mantiene el valor del indice int index=0; for (Carta[] mano : jugadas) { // System.out.println("JUGADA ======================"); if(esPrimero){ ganadores.add(mano); indices.add(index); esPrimero=false; } else{ ArrayList calificacionMayor= calificacion(ganadores.get(ganadores.size()-1)); ArrayList calificacionActual= calificacion(mano); if(calificacionMayor.get(0)calificacionActual.get(i)){ break; } //Si la i llega al tamaño máximo del array, quiere decir //que son todos iguales else if(i==calificacionMayor.size()-1){ ganadores.add(mano); indices.add(index); } } } } index++; } //imprimirGanadores(ganadores); String stringGanadores=""; for (int i = 0; i < indices.size(); i++) { stringGanadores += indices.get(i)+" "; } return stringGanadores; } private ArrayList calificacion(Carta[] mano){ ArrayList calificacion= new ArrayList(); /** * La calificacion numérica de cada carta estará en el lugar 0 del array retornado * Escalera color -> 9 * Poker -> 8 * Full -> 7 * Color -> 6 * Escalera -> 5 * Trio -> 4 * Par Doble -> 3 * Par -> 2 * Carta alta -> 1 */ //Array para almacenar la cantidad de apariciones de cada número int[] valores = new int[13]; //Array para almacenar la cantidad de apariciones de cada palo int[] palos = new int[4]; inicializarArrays(valores, palos, mano); //Si es escalera, solo basta ver el valor de la escalera if(esEscaleraColor(valores, palos)){ int[] ordenado = ordenarMano(mano); calificacion.add(9); //Si el AS actúa como 14, entonces el AS vale 14 if(ordenado[4]==12 && ordenado[0]==0){ calificacion.add(14); } else{ calificacion.add(ordenado[4]); } } else if(esPoker(valores)){ //Si es poker, se envia la calificacion en el primer elemento, seguido del //valor que hizo que sea poker, seguido del valor diferente calificacion.add(8); if(indiceDe(4,valores)==0){ calificacion.add(14); calificacion.add(indiceDe(1,valores)); } else{ calificacion.add(indiceDe(4,valores)); if(indiceDe(1, valores)==0){ calificacion.add(14); } else{ calificacion.add(indiceDe(1, valores)); } } } else if(esFull(valores)){ //No hay empate en full, por lo tanto solo hace falta //el valor de la mano calificacion.add(7); if(indiceDe(3,valores)==0){ calificacion.add(14); calificacion.add(indiceDe(2,valores)); } else{ calificacion.add(indiceDe(3,valores)); if(indiceDe(2, valores)==0){ calificacion.add(14); } else{ calificacion.add(indiceDe(2,valores)); } } } else if(esColor(palos)){ int aux=0; calificacion.add(6); int[] ordenado = ordenarMano(mano); if(ordenado[0]==0){ calificacion.add(14); aux=1; } for (int i = 4; i >= aux; i--) { calificacion.add(ordenado[i]); } } else if(esEscalera(valores)){ int[] ordenado = ordenarMano(mano); calificacion.add(5); if(ordenado[4]==12 && ordenado[0]==1){ calificacion.add(14); } else{ calificacion.add(ordenado[4]); } } else if(esTrio(valores)){ calificacion.add(4); //Convierte el AS al mayor valor, en lugar de 1 vale 14 if(indiceDe(3,valores)==0){ calificacion.add(14); }else{ calificacion.add(indiceDe(3, valores)); } int[] ordenado = ordenarMano(mano); int aux = 0; if(ordenado[0]==0){ calificacion.add(14); aux = 1; } for (int i = 4; i >=aux; i--) { if(calificacion.get(1)!=ordenado[i]){ calificacion.add(ordenado[i]); } } } else if(esParDoble(valores)){ calificacion.add(3); //Si es un par doble de AS, se le asigna 14 if(indiceDe(2,valores)==0){ calificacion.add(14); calificacion.add(indiceDeReversa(2, valores)); } else{ calificacion.add(indiceDeReversa(2, valores)); calificacion.add(indiceDe(2, valores)); } if(indiceDe(1,valores)==0){ calificacion.add(14); } else{ calificacion.add(indiceDe(1,valores)); } } else if(esPar(valores)){ calificacion.add(2); //Si el par es de AS, se setea su valor a 14 if(indiceDe(2,valores)==0){ calificacion.add(14); } else{ calificacion.add(indiceDe(2, valores)); } int[] ordenado = ordenarMano(mano); int aux=0; if(ordenado[0]==0){ calificacion.add(14); aux=1; } for (int i = 4; i >=aux; i--) { if(calificacion.get(1)!=ordenado[i]){ calificacion.add(ordenado[i]); } } } else{ int aux=0; calificacion.add(1); //Si hay un AS, se coloca directamente después de la //calificación int[] ordenado = ordenarMano(mano); if(ordenado[0]==0){ calificacion.add(14); aux=1; } for (int i = 4; i >= aux; i--) { calificacion.add(ordenado[i]); } } return calificacion; } private int indiceDe(int elemento, int[] vector){ for (int i = 0; i < vector.length; i++) { if(vector[i]==elemento) return i; } //retorna -1 si no encuentra; return -1; } private int indiceDeReversa(int elemento, int[] vector){ for (int i = vector.length-1; i >=0; i--) { if(vector[i]==elemento) return i; } //retorna -1 si no encuentra; return -1; } private int[] ordenarMano(Carta[] mano){ int[] ordenado = new int[5]; for (int i = 0; i < 5; i++) { String valorString= mano[i].valor; if(valorString.equals("A") || valorString.equals("a")){ ordenado[i]=0; } else if(valorString.equals("T") || valorString.equals("t")){ ordenado[i]=9; } else if(valorString.equals("J") || valorString.equals("j")){ ordenado[i]=10; } else if(valorString.equals("Q") || valorString.equals("q")){ ordenado[i]=11; } else if(valorString.equals("K") || valorString.equals("k")){ ordenado[i]=12; } else{ ordenado[i] = Integer.parseInt(valorString)-1; } } Arrays.sort(ordenado); return ordenado; } private boolean esEscaleraColor(int[] valores, int[] palos){ /** * Funcionamiento: recorre el vector de valores y cuando encuentra un 1 * enciende una bandera para comenzar a contar. * Termina el ciclo cuando ya no quedan elementos o cuando encuentra un número * distinto a 1. Si este número es mayor a 1, entonces termina el ciclo. * Si el contador termina en 5, se comprueba que todos los palos sean iguales. * esto se consigue revisando si en el vector de palos hay un 5, porque esto significa * que todos fueron iguales * O si hay un 4 en el contador y una A presente, también es verdadero */ //bandera para activar sumador boolean sumadorActivo=false; //Sumador de números contiguos int sumador=0; //no se comprueba si existe A, porque despues se comprueba //si el contador llegó a 4 y existe una A, entonces es una //escalera for (int i = 1; i < 13; i++) { //Si la cantidad de aparición de un valor fue mayor a 1, //no es posible que sea una escalera if(valores[i]>1){ return false; } if(valores[i]==1){ sumadorActivo=true; } if(valores[i]==0 && sumadorActivo){ break; } if(sumadorActivo){ sumador++; } } //Si el sumador llegó a 5 entra al ciclo que comprueba //o si llegó a 4 y existe una A //si alguno de los palos vino 5 veces if(sumador==5 || (sumador==4 && valores[0]==1 && valores[9]==1 && valores[8]==0)){ for (int i = 0; i < 4; i++) { if(palos[i]==5){ return true; } } } return false; } //Comprueba si la mano es póker private boolean esPoker(int[] valores){ /** * Funcionamiento: Ordena el array de valores de forma ascendente. * Para comprobar si existe poker, basta con mirar el último elemento del array, * donde debería encontrarse un 4 */ //Clona el array de valores int [] ordenado = valores.clone(); //Ordena la copia Arrays.sort(ordenado); if(ordenado[12]==4){ return true; } return false; } private boolean esFull(int[] valores){ //Clona el array de valores int [] ordenado = valores.clone(); //Ordena la copia Arrays.sort(ordenado); if(ordenado[12]==3 && ordenado[11]==2) return true; return false; } private boolean esColor(int[] palos){ //Clona el array de valores int [] ordenado = palos.clone(); //Ordena la copia Arrays.sort(ordenado); if(ordenado[3]==5) return true; return false; } private boolean esEscalera(int[] valores){ //bandera para activar sumador boolean sumadorActivo=false; //Sumador de números contiguos int sumador=0; //no se comprueba si existe A, porque despues se comprueba //si el contador llegó a 4 y existe una A, entonces es una //escalera for (int i = 1; i < 13; i++) { //Si la cantidad de aparición de un valor fue mayor a 1, //no es posible que sea una escalera if(valores[i]>1){ return false; } if(valores[i]==1){ sumadorActivo=true; } if(valores[i]==0 && sumadorActivo){ break; } if(sumadorActivo){ sumador++; } } //Si el sumador llegó a 5 entra al ciclo que comprueba //o si llegó a 4 y existe una A if(sumador==5 || (sumador==4 && valores[0]==1 && valores[9]==1 && valores[8]==0)){ return true; } return false; } private boolean esTrio(int[] valores){ //Clona el array de valores int [] ordenado = valores.clone(); //Ordena la copia Arrays.sort(ordenado); if(ordenado[12]==3 && ordenado[11]==1 && ordenado[10]==1) return true; return false; } private boolean esParDoble(int[] valores){ //Clona el array de valores int [] ordenado = valores.clone(); //Ordena la copia Arrays.sort(ordenado); if(ordenado[12]==2 && ordenado[11]==2 && ordenado[10]==1) return true; return false; } private boolean esPar(int[] valores){ //Clona el array de valores int [] ordenado = valores.clone(); //Ordena la copia Arrays.sort(ordenado); if(ordenado[12]==2 && ordenado[11]==1 && ordenado[10]==1 && ordenado[9]==1) return true; return false; } private void inicializarArrays(int[] valores, int[] palos, Carta[] mano){ //Se coloca 1 y 14 para que sea mas facil controlar las Escaleras for (int i = 0; i < 13; i++) { valores[i]=0; } for (int i = 0; i < 4; i++) { palos[i] = 0; } //carga los vectores de cantidades de aparición for (int i = 0; i < 5; i++) { String valorString = mano[i].valor; String paloString = mano[i].palo; if(valorString.equals("A") || valorString.equals("a")){ valores[0]++; } else if(valorString.equals("T") || valorString.equals("t")){ valores[9]++; } else if(valorString.equals("J") || valorString.equals("j")){ valores[10]++; } else if(valorString.equals("Q") || valorString.equals("q")){ valores[11]++; } else if(valorString.equals("K") || valorString.equals("k")){ valores[12]++; } else if(valorString.equals("J") || valorString.equals("j")){ valores[10]++; } else{ int index = Integer.parseInt(valorString); valores[index-1]++; } //Para el array de cantidades de palos //S -> 0 //C -> 1 //H -> 2 //D -> 3 if(paloString.equals("S") || paloString.equals("s")){ palos[0]++; } else if(paloString.equals("C") || paloString.equals("c")){ palos[1]++; } else if(paloString.equals("H") || paloString.equals("h")){ palos[2]++; } else if(paloString.equals("D") || paloString.equals("d")){ palos[3]++; } } } //Este metodo genera n cantidad de cartas al azar public Carta[] generarCartas(int n) { Carta[] cartas = new Carta[n]; Random random = new Random(); String nuevaCarta = ""; int valor[] = new int[n]; int palo[] = new int[n]; for(int i=0; i