public ArbolGeneral <int> InstalacionHeuristica(ArbolGeneral <int> ArbolMiniMax, bool Turno, int limite) { //Si mi funcion Heuristica, es decir si la base de mi ABGeneral tiene "getDatoRaiz=-1" gana Usuario //si tiene "getDatoRaiz=-2" gana Maquina... if (limite < 0) { //En el nodo de mi arbol que se sobrepase el limite se corta y se debe poner como hijo de este el dato heuristico (-1 gano maquina,-2 gano usuario) //dependiendo de quien sea el turno. if (Turno == true) { ArbolMiniMax.ConvertirEnHoja(); //El nodo en el que se alcanza el limite se convierte en Hoja y en este se agrega el dato heuristico ArbolGeneral <int> Heuristic = new ArbolGeneral <int>(-1); ArbolMiniMax.agregarHijo(Heuristic); } else { ArbolMiniMax.ConvertirEnHoja(); ArbolGeneral <int> Heuristic = new ArbolGeneral <int>(-2); ArbolMiniMax.agregarHijo(Heuristic); } } //Mientras no se supere el limite recorro los hijos de mi nodo else { foreach (var hijo in ArbolMiniMax.getHijos()) { int LimiteAux = limite - hijo.getDatoRaiz(); InstalacionHeuristica(hijo, !Turno, LimiteAux); } } return(ArbolMiniMax); }
public ArbolGeneral <int> CompletarRama(ArbolGeneral <int> Hijo, List <int> CartasUsuario, List <int> CartasMaquina, bool Turno, int limite) { //Empieza Jugando Usuario->Turno=true(Juega Usuario)->Turno=false(Juega Maquina) List <int> cartas = new List <int>(); if (Turno == true) { cartas.AddRange(CartasUsuario); //Si Juega Usuario guardo todas las cartas de este en la variable "cartas" } else { cartas.AddRange(CartasMaquina); //Si Juega Maquina guardo todas las cartas de este en la variable "cartas" } foreach (int carta in cartas) //Recorre la lista de cartas Correspondiente al Jugador { ArbolGeneral <int> hijo = new ArbolGeneral <int>(carta); //Realiza una instancia de ArbolGeneral con DatoRaiz carta Hijo.agregarHijo(hijo); //Agrega al Arbol la instancia hijo creada anteriormente int limiteaAux = limite - carta; //Decrementa el limite en base a el dato de la carta List <int> cartasrestantes = new List <int>(); cartasrestantes.AddRange(cartas); //Guardo todas las cartas en lista cartas restantes cartasrestantes.Remove(carta); // y elimino la carta que se esta recorriendo de la lista "cartas". if (limite >= 0) //Si limite es menor a cero empieza a armar la siguiente rama { if (Turno == true) { CompletarRama(hijo, cartasrestantes, CartasMaquina, !Turno, limiteaAux); //Hace llamada recursiva cambia el turno, envia la lista con } //la carta eliminada y el limite reducido else { CompletarRama(hijo, CartasUsuario, cartasrestantes, !Turno, limiteaAux); } } } return(Hijo); }
public void generarArbol(ArbolGeneral <Jugada> nodoCarta, List <int> cartasPropias, List <int> cartasOponente, int limite) { List <int> cartasPropiasSinJugar = new List <int>(cartasPropias); cartasPropiasSinJugar.Remove(nodoCarta.getDatoRaiz().carta); int limiteActualizado = nodoCarta.getDatoRaiz().limiteActual - nodoCarta.getDatoRaiz().carta; if (limiteActualizado < 0) { if (nodoCarta.getDatoRaiz().miAI) { nodoCarta.getDatoRaiz().ganadas = -1; } else { nodoCarta.getDatoRaiz().ganadas = 1; } } else { foreach (int cartaOponente in cartasOponente) { Jugada movimientoOponente = new Jugada(cartaOponente, limiteActualizado, 0, nodoCarta.getDatoRaiz().miAI); ArbolGeneral <Jugada> nodoCartaOponente = new ArbolGeneral <Jugada>(movimientoOponente); generarArbol(nodoCartaOponente, cartasOponente, cartasPropiasSinJugar, limiteActualizado); nodoCarta.agregarHijo(nodoCartaOponente); nodoCarta.getDatoRaiz().ganadas += nodoCartaOponente.getDatoRaiz().ganadas; } } }
private void llenarArbol(ArbolGeneral <DatosJugadas> nodoCarta, List <int> cartasPropias, List <int> cartasOponente) { List <int> cartasPropiasSinJugada = new List <int>(cartasPropias); cartasPropiasSinJugada.Remove(nodoCarta.getDatoRaiz().Carta); int limiteActualizado = nodoCarta.getDatoRaiz().LimiteActual - nodoCarta.getDatoRaiz().Carta; if (limiteActualizado < 0) { nodoCarta.getDatoRaiz().Ganadas = 0; } else { foreach (int cartaOponente in cartasOponente) { DatosJugadas cartaJugadorOponente = new DatosJugadas(cartaOponente, limiteActualizado, 0, !nodoCarta.getDatoRaiz().EsAi); ArbolGeneral <DatosJugadas> nodoCartaOponente = new ArbolGeneral <DatosJugadas>(cartaJugadorOponente); llenarArbol(nodoCartaOponente, cartasOponente, cartasPropiasSinJugada); nodoCarta.agregarHijo(nodoCartaOponente); } } }
private void ArmarArbolMinimaxAux(Estatus estado, ArbolGeneral <Dupla> raiz) { if (estado.returnJuegaHumano() == true) { foreach (int carta in estado.getCartasHumano()) { ArbolGeneral <Dupla> h = new ArbolGeneral <Dupla>(new Dupla(carta, 0)); raiz.agregarHijo(h); if (estado.getLimite() - carta >= 0 && estado.getCartasIA().Count > 0) { List <int> nuevasCartaH = new List <int>(); nuevasCartaH.AddRange(estado.getCartasHumano()); nuevasCartaH.Remove(carta); Estatus estadoNuevo = new Estatus(); estadoNuevo.setCartasHumano(nuevasCartaH); estadoNuevo.setCartasIA(estado.getCartasIA()); estadoNuevo.setLimite(estado.getLimite() - carta); estadoNuevo.setJuegaHumanoFalse(); ArmarArbolMinimaxAux(estadoNuevo, h); bool existe = false; foreach (ArbolGeneral <Dupla> hijo in h.getHijos()) { if (hijo.getDatoRaiz().getValorFuncionHeuristica() == 1) { existe = true; } } if (existe == true) { h.getDatoRaiz().setFuncionHeuristica(1); } else { h.getDatoRaiz().setFuncionHeuristica(-1); } } else { h.getDatoRaiz().setFuncionHeuristica(1); } } } else { foreach (int carta in estado.getCartasIA()) { ArbolGeneral <Dupla> h = new ArbolGeneral <Dupla>(new Dupla(carta, 0)); raiz.agregarHijo(h); if (estado.getLimite() - carta >= 0 && estado.getCartasHumano().Count > 0) { List <int> nuevasCartaIA = new List <int>(); nuevasCartaIA.AddRange(estado.getCartasIA()); nuevasCartaIA.Remove(carta); Estatus estadoNuevo = new Estatus(); estadoNuevo.setCartasIA(nuevasCartaIA); estadoNuevo.setCartasHumano(estado.getCartasHumano()); estadoNuevo.setLimite(estado.getLimite() - carta); estadoNuevo.setJuegaHumanoTrue(); ArmarArbolMinimaxAux(estadoNuevo, h); bool existe = false; foreach (ArbolGeneral <Dupla> hijo in h.getHijos()) { if (hijo.getDatoRaiz().getValorFuncionHeuristica() == -1) { existe = true; } } if (existe == true) { h.getDatoRaiz().setFuncionHeuristica(-1); } else { h.getDatoRaiz().setFuncionHeuristica(1); } } else { h.getDatoRaiz().setFuncionHeuristica(-1); } } } }
private void crearArbol(List <int> cartasPropias, List <int> cartasOponente, int limite, bool turno, ArbolGeneral <DatosJugada> aux) { List <int> cartas = new List <int>(); //creo una lista vacia, que se llenara de cartas //al determinar que primero juegue el humano, siempre se ejecutará el IF if (turno) { // Si es el turno del usuario agrego las cartas del oponente cartas.AddRange(cartasOponente); } else { // Si es el turno de la IA agrego las cartas propias cartas.AddRange(cartasPropias); } //comienzo a llenar el arbol minimax con las cartas del humano (cada una sera un subarbol) foreach (int carta in cartas) //crea, por ende, 6 hijos a la raíz null del minmax { //----------------------------------------------------------------------------------- DatosJugada jugada = new DatosJugada(0, 0, true); // Creo subarboles hijos PARA cada carta ArbolGeneral <DatosJugada> hijo = new ArbolGeneral <DatosJugada>(jugada); //agrego la carta a la raiz hijo.getDatoRaiz().carta = carta; // Agrego los hijos al arbol minmax aux.agregarHijo(hijo); // Disminuyo el limite para cada carta int nuevoLimite = limite - carta; // Tendremos una lista de cartas auxiliares para hacer la llamada recursiva sin la carta que ya se jugo List <int> cartasAux = new List <int>(); cartasAux.AddRange(cartas); cartasAux.Remove(carta); //saca la primer carta que juega el humano y a partir de ahí sigue // Chequeo el limite, si no se supero hago las llamadas recursivas y cambio el turno if (nuevoLimite >= 0) { bool Noencontro_Humano = false; //Variables que serviran para la busqueda heuristica bool Noencontro_Computer = false; //---------------------------crea un nuevo nivel o no (dependiendo del if anterior) invirtiendo el turno---------------------------------------- // Si es turno del usuario, paso las cartas auxiliares como cartas del oponente if (turno) { crearArbol(cartasPropias, cartasAux, nuevoLimite, !turno, hijo); //paso como arbol, a los arboles hijos de la raiz. sucesivamente // Comparo las funciones heuristicas de los hijos foreach (var hijos in hijo.getHijos()) { // Si hay una con valor 1, se la seteo al padre //esto hace que el -1 o 1 vaya subiendo y se setee desde la hoja hasta los hijos del primer nivel if (hijos.getDatoRaiz().valorDeConveniencia == -1) { hijo.getDatoRaiz().valorDeConveniencia = -1; } else { Noencontro_Humano = true; } } if (Noencontro_Humano) { Noencontro_Humano = !Noencontro_Humano; //Si no encuentra quiere decir que no hay un hijo con valor -1 y entonces se le sete 1 al padre. hijo.getDatoRaiz().valorDeConveniencia = 1; } } // Si es el turno de la IA paso cartas auxiliares como cartas propias else { crearArbol(cartasAux, cartasOponente, nuevoLimite, !turno, hijo); // Comparo las funciones heuristicas de los hijos foreach (var hijos in hijo.getHijos()) { // Si hay una con valor -1, se la seteo al padre if (hijos.getDatoRaiz().valorDeConveniencia == 1) { hijo.getDatoRaiz().valorDeConveniencia = 1; } else { Noencontro_Computer = true; } } if (Noencontro_Computer) { Noencontro_Computer = !Noencontro_Computer; //Si no encuentra quiere decir que no hay un hijo con valor 1 y entonces se le sete 1 al padre. hijo.getDatoRaiz().valorDeConveniencia = -1; } } } //---------------------------------------------------------------------------------- // Si se supera el limite verifico quien gano (-1 gana humano, 1 gana pc) // acá se asigna el valor a las hojas ... else { if (turno) { hijo.getDatoRaiz().valorDeConveniencia = 1; //se pasa de limite el humano } else { hijo.getDatoRaiz().valorDeConveniencia = -1; //se pasa de limite la computadora } } referencia = minimax; //Referencia la vamos a usar para saber en que cartas estamos. } }
private void createArbol(Estado estado, ArbolGeneral <Carta> raiz) { if (estado.getTurnoH()) // turno del Humano { foreach (int cartaH in estado.getCartasH()) { Carta carta = new Carta(cartaH, 0); ArbolGeneral <Carta> hijo = new ArbolGeneral <Carta>(carta); raiz.agregarHijo(hijo); int nuevoLimite = estado.getLimite() - cartaH; if (nuevoLimite >= 0) // si no es el caso base, actualizo el estado y sigo armando el arbol. { List <int> nuevasCartasH = new List <int>(); nuevasCartasH.AddRange(estado.getCartasH()); nuevasCartasH.Remove(cartaH); Estado nuevoEstado = new Estado(estado.getCartasIA(), nuevasCartasH, nuevoLimite, false); createArbol(nuevoEstado, hijo); // Función heuristica MiniMax bool max = false; foreach (var nodo in hijo.getHijos()) { if (nodo.getDatoRaiz().getFuncHeursitica() == 1) // Si existe al menos un hijo con FH +1, se maximiza { max = true; break; // agrego un break para cortar la busqueda. } } if (max) { hijo.getDatoRaiz().setFuncHeuristica(1); } else { hijo.getDatoRaiz().setFuncHeuristica(-1); } } else // si es el caso base, entonces asigno la funcion heuristica al nodo hijo. { hijo.getDatoRaiz().setFuncHeuristica(1); // Pierde el humano, gana la IA. } } } else// turno de la IA { foreach (int cartaIA in estado.getCartasIA()) { Carta carta = new Carta(cartaIA, 0); ArbolGeneral <Carta> hijo = new ArbolGeneral <Carta>(carta); raiz.agregarHijo(hijo); int nuevoLimite = estado.getLimite() - cartaIA; if (nuevoLimite >= 0) // si no es el caso base, actualizo el estado y sigo armando el arbol. { List <int> nuevasCartasIA = new List <int>(); nuevasCartasIA.AddRange(estado.getCartasIA()); nuevasCartasIA.Remove(cartaIA); Estado nuevoEstado = new Estado(nuevasCartasIA, estado.getCartasH(), nuevoLimite, true); createArbol(nuevoEstado, hijo); // Se sigue armando el arbol hasta que haya un nodo hoja. // Función heuristica MiniMax bool min = false; foreach (var nodo in hijo.getHijos()) // Se recorren los hijos del hijo raiz { if (nodo.getDatoRaiz().getFuncHeursitica() == -1) // Si existe al menos un hijo con FH -1, se minimiza { min = true; break; // Agrego un break para cortar la busqueda. } } if (min) { hijo.getDatoRaiz().setFuncHeuristica(-1); } else { hijo.getDatoRaiz().setFuncHeuristica(1); } } else // si es el caso base, entonces asigno la funcion heuristica al nodo hijo. { hijo.getDatoRaiz().setFuncHeuristica(-1); // Pierde la IA, gana el Humano. } } } }
private void _inicializar(List <int> cartasPropias, List <int> cartasOponente, int limite, bool turno, ArbolGeneral <int> raiz) { //Creo una lista de cards auxiliar para no modificar las originales List <int> cards = new List <int>(); if (turno == true) //Human turn { cards.AddRange(cartasOponente); } else //AI Turn { cards.AddRange(cartasPropias); } //Para cada card foreach (var card in cards) { //Creo un arbol auxiliar con la card como dato ArbolGeneral <int> hijo = new ArbolGeneral <int>(card); //Agrego el arbol auxiliar como hijo de la raíz raiz.agregarHijo(hijo); //Disminuyo el limite int limiteaux = limite - card; //Creo una lista de cards auxiliar para eliminar la card sin perder información de la lista "cards" List <int> cartasRestantes = new List <int>(); cartasRestantes.AddRange(cards); cartasRestantes.Remove(card); //Si el límite es mayor o igual a 0 sigo agregando hijos a los subárboles if (limiteaux >= 0) { //Si es el turno del humano, llamo recursivamente a la funcion con la lista de cards auxiliares como nueva lista de cards del humano. if (turno == true) { _inicializar(cartasPropias, cartasRestantes, limiteaux, !turno, hijo); //Asignamos función heurística a cada nodo cuando volvemos de la recursión List <ArbolGeneral <int> > hijos = raiz.getHijos(); raiz.setFuncionHeuristica(-1); foreach (var h in hijos) { if (h.getFuncionHeuristicaRaiz() == 1) { raiz.setFuncionHeuristica(1); break; } } } //Si es el turno de la IA, llamamos a la función recursivamente con la lista de cartas auxiliares como nueva lista de cartas de la IA. else { _inicializar(cartasRestantes, cartasOponente, limiteaux, !turno, hijo); //Asignamos función heurística a cada nodo cuando volvemos de la recursión. List <ArbolGeneral <int> > hijos = raiz.getHijos(); raiz.setFuncionHeuristica(1); foreach (var h in hijos) { if (h.getFuncionHeuristicaRaiz() == -1) { raiz.setFuncionHeuristica(-1); break; } } } } //Si se pasó el límite else { //Asignamos función heurística a cada hoja //(1 IA Gana ; -1 Human Gana) if (turno == true) { hijo.setFuncionHeuristica(1); } else { hijo.setFuncionHeuristica(-1); } } } Game.setEstadoInicial(raiz); }