/** * El nodo hijo pasado es el ultimo movimiento del jugador pasado en parametro, los hijos de este * nodo son los posibles movimientos del OTRO jugador, donde NO puede ganar este que estamos * probando. * * @param nodo * @param jugador * @param profundidad * @return */ public int getCantidadVictoriasAPartirDe(Arbol.Nodo<Jugada> nodo, int jugador, int profundidad) { if (nodo.getHijos().estaVacia()) { if (nodo.getValor().haGanado(jugador)) return (10 - profundidad); int otroJugador = (jugador == COMPUTADORA ? JUGADOR : COMPUTADORA); if (nodo.getValor().haGanado(otroJugador)) return (profundidad - 10); return 0; } int total = 0; Iterator<Arbol.Nodo<Jugada>> iter = nodo.getHijos().iterator(); while (iter.hasNext()) { Arbol.Nodo<Jugada> nodoHijo = iter.next(); total += getCantidadVictoriasAPartirDe(nodoHijo, jugador, profundidad + 1); } return total; }
/** * Crea un arbol de TODOS los posibles movimientos a partir de una jugada. Este metodo puede ser * bastantee pesado ya que puede crear un arbol de varios miles de nodos al menos para la primera * jugada. Alternativamente luego de cada jugada cambia de jugador para simular TODAS las posibles * jugadas. * * @param movida * @param jugador * @return */ public Arbol<Jugada> crearArbol(Jugada movida, int jugador) { Arbol<Jugada> result = new Arbol<Jugada>(); Arbol.Nodo<Jugada> nodoRaiz = result.insertarHijo(null, movida); Cadena<Jugada> posiblesJugadas = movida.getPosiblesJugadas(jugador); int otroJugador = (jugador == JUGADOR ? COMPUTADORA : JUGADOR); Iterator<Jugada> iter = posiblesJugadas.iterator(); while (iter.hasNext()) { Jugada hijo = iter.next(); Arbol.Nodo<Jugada> nodoHijo = result.insertarHijo(nodoRaiz, hijo); Arbol<Jugada> arbolHijo = crearArbol(hijo, otroJugador); nodoHijo.colocarHijosDeRaizDeArbol(arbolHijo); } return result; }
/** * Elige una jugada a partir del arbol de decision obtenido para el jugador pasado en parametro. * Para esto lo que hace es contar la cantidad de victorias que le da cada uno de los hijos de la * raiz (las posibles jugadas). Luego, lo unico que se hace es elegir el hijo que da la mayor * cantidad de victorias. * * @param arbolDecision * @param jugador * @return */ private Jugada elegirJugada(Arbol<Jugada> arbolDecision, int jugador) { int maxCantidadVictorias = Integer.MIN_VALUE; Jugada elegida = null; Cadena<Arbol.Nodo<Jugada>> posibles = arbolDecision.getRaiz().getHijos(); Iterator<Arbol.Nodo<Jugada>> iter = posibles.iterator(); while (iter.hasNext()) { Arbol.Nodo<Jugada> nodo = iter.next(); logger.debug("Jugada: \n" + nodo.getValor()); int cantidadVictorias = getCantidadVictoriasAPartirDe(nodo, jugador, 1); logger.debug("Tiene " + cantidadVictorias + " victorias posibles"); if (cantidadVictorias >= maxCantidadVictorias) { elegida = nodo.getValor(); maxCantidadVictorias = cantidadVictorias; } } return elegida; }