public void imprimirNivel(int nivel, ArbolGeneral <DatosJugada> arbol) { Cola <ArbolGeneral <DatosJugada> > c = new Cola <ArbolGeneral <DatosJugada> >(); //ArbolGeneral<DatosJugada> aux; int contador = 0; bool NivelEncontrado = false; c.encolar(referencia); c.encolar(null); while (!c.esVacia()) { arbol = c.desencolar(); if (arbol != null) { if (contador == nivel) { NivelEncontrado = true; if (arbol.getDatoRaiz().valorDeConveniencia == 1) { Console.Write(arbol.getDatoRaiz().carta + " " + "[Pierde], "); } if (arbol.getDatoRaiz().valorDeConveniencia == -1) { Console.Write(arbol.getDatoRaiz().carta + " " + "[Gana], "); } } } if (arbol == null) { if (!c.esVacia()) { c.encolar(null); } contador++; } else { if (!referencia.esHoja()) { foreach (var hijo in arbol.getHijos()) { c.encolar(hijo); } } } } if (NivelEncontrado == false) { Console.WriteLine("No se encontro la profunidad. Regresando al juego...."); } }
public void PorNiveles() { Cola <ArbolGeneral <T> > cola = new Cola <ArbolGeneral <T> >(); cola.encolar(this); while (!cola.esVacia()) { int n = cola.cantidad(); while (n > 0) { ArbolGeneral <T> p = cola.tope(); cola.desencolar(); Console.Write(p.getDatoRaiz() + " "); foreach (var v in p.getHijos()) { cola.encolar(v); } n--; } Console.WriteLine(); Console.WriteLine(); } }
public void recoridoPorNiveles(Cola <ArbolGeneral <int> > cola, Cola <ArbolGeneral <int> > colaRepe, int nivel) { if (cola.esVacia() == true) { Console.WriteLine("Se termino"); } if (cola.esVacia() == false) { while (cola.esVacia() == false) { ArbolGeneral <int> arboli = cola.desencolar(); Console.Write(arboli.getDatoRaiz() + ", "); colaRepe.encolar(arboli); } while (colaRepe.esVacia() == false) { ArbolGeneral <int> arbolito = colaRepe.desencolar(); foreach (ArbolGeneral <int> hijos in arbolito.getHijos()) { cola.encolar(hijos); } } if (nivel % 2 == 1) { Console.WriteLine("Usuario"); } if (nivel % 2 == 0) { Console.WriteLine("Computer"); } nivel++; recoridoPorNiveles(cola, colaRepe, nivel); } }
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; } } }
public override int descartarUnaCarta() { int mejoropcion = -1; ArbolGeneral <int> nueopcion = null; foreach (ArbolGeneral <int> opciones in arbol.getHijos()) { if (opciones.Raiz.Datpri > mejoropcion) { nueopcion = opciones; mejoropcion = opciones.Raiz.Datpri; } } arbol.setRaiz(nueopcion.Raiz); Console.WriteLine("La maquina escogio la carta " + nueopcion.getDatoRaiz()); return(nueopcion.getDatoRaiz()); }
public override int descartarUnaCarta() { int mejoropcion = -1; ArbolGeneral <int> nueopcion = null; foreach (ArbolGeneral <int> opciones in arbolMiniMax.getHijos()) { if (opciones.Raiz.cuantasVecesPerdio > mejoropcion) { nueopcion = opciones; mejoropcion = opciones.Raiz.CuantasVecesPerdio; } } arbolMiniMax.Raiz = nueopcion.Raiz; Console.WriteLine("La maquina escogio la carta " + nueopcion.getDatoRaiz()); return(nueopcion.getDatoRaiz()); encolarParaRecorrer(arbolMiniMax); }
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); } } }
public void recorridoEntreNiveles(int a, int b) { if (esVacio()) { return; } Cola <ArbolGeneral <T> > cola = new Cola <ArbolGeneral <T> >(); cola.encolar(this); int nivel = 0; while (!cola.esVacia()) { nivel++; int n = cola.cantidad(); while (n > 0) { ArbolGeneral <T> p = cola.tope(); cola.desencolar(); if (nivel >= a && nivel <= b) { Console.Write(p.getDatoRaiz() + " "); } if (!p.esVacio()) { foreach (var v in p.getHijos()) { cola.encolar(v); } } n--; } if (nivel >= a && nivel <= b) { Console.WriteLine(); } } }
private int _descartarUnaCarta(ArbolGeneral <Carta> raiz) { // Con el siguiente algoritmo se guardan las cartas donde la IA tiene una jugada aseguarada para ganar el juego. Random random = new Random(); List <ArbolGeneral <Carta> > opciones = new List <ArbolGeneral <Carta> >(); // Lista que almacena todas las posibilidades de victoria. int i = 0; // Se crea la lista de opciones de cartas donde la IA tiene asegurada una victoria. foreach (var hijo in raiz.getHijos()) { if (hijo.getDatoRaiz().getFuncHeursitica() == 1) // Si tiene un hijo con FH +1, entonces se lo agrega a la lista de opciones. { opciones.Add(hijo); } } if (opciones.Count == 0) // Si la IA no tiene una jugada asegurada de victoria, entonces tira la última carta. { foreach (var hijo in raiz.getHijos()) { if (hijo.getDatoRaiz().getFuncHeursitica() == -1) { jugadaActual = hijo; } } } else // Si la IA tiene opciones aseguradas para ganar. { int opcion = random.Next(1, opciones.Count); // Se crea un valor random entre 1 y la cantidad de opciones que haya. foreach (var o in opciones) // Se recorren todas las opciones. { i++; // Se incrementa el contador a medida que se recorren las opciones. if (i == opcion) // Si el contador es igual a el número de opción aleatoria. { jugadaActual = o; // Entonces, jugadaActual apunta a esa opción. break; } } } return(jugadaActual.getDatoRaiz().getCarta()); // Se retorna la carta elegida. }
public void PorNivelesMarcadoFin() { Cola <ArbolGeneral <T> > cola = new Cola <ArbolGeneral <T> >(); //Intancia una cola vacia cola.encolar(this); //Obtiene el Nodo Raiz y lo encola cola.encolar(null); //Encola null (para determinar cuando empieza el nuevo nivel) int nivel = 1; Console.WriteLine("======================================================================================================================="); Console.Write("[Nivel-" + nivel + "]: "); while (cola.esVacia() != true) { ArbolGeneral <T> NodoDesencolado = cola.desencolar(); //Quita de la cola el dato(cola[0]) y lo almacena en la variable if (NodoDesencolado == null) { cola.encolar(null); //Si el dato es NULL, encola NULL para señalar el comienzo de un nuevo nivel if (cola.tope() == NodoDesencolado) { cola.desencolar(); //Si el dato en la cola, anterior a el dato NodoDesencolado, es tambien NULL se desencola //pero no se almacena en ninguna variable temporal. } else { nivel++; //Si el dato no es NULL, es nodo, nivel incrementa y se comienza a imprimir el nuevo nivel Console.Write("\n========================================================================================================================"); Console.Write("[Nivel-" + nivel + "]: "); } } else //Si el dato desencolado es un NODO se encola e imprimen los hijos de este { foreach (var Nodo in NodoDesencolado.getHijos()) { cola.encolar(Nodo); } Console.Write("[" + NodoDesencolado.getDatoRaiz() + "]"); } } Console.Write("\n========================================================================================================================"); }
public ArbolGeneral <T> CortarArbol(int UltimaCartaUsuario) { Cola <ArbolGeneral <T> > c = new Cola <ArbolGeneral <T> >(); ArbolGeneral <T> arbolAux = new ArbolGeneral <T>(null); c.encolar(this); while (!c.esVacia()) { arbolAux = c.desencolar(); if (Convert.ToInt32(arbolAux.getDatoRaiz()) == UltimaCartaUsuario) { return(arbolAux); } if (!this.esHoja()) { foreach (var hijo in arbolAux.getHijos()) { c.encolar(hijo); } } } return(arbolAux); }
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 ConsultaB() { ArbolGeneral <DatosJugada> referencia = computer.getReferencia(); //Uso de referencia a la carta en la posicion que se encuentra el juego. bool rta = true; //Condicion para terminar las jugadas bool turno = true; computer.ImprimirCartas(); while (rta) { if (turno == true) { Console.WriteLine("Ingrese la carta que jugaría usted:"); string carta = Console.ReadLine(); bool aux = false; while (aux == false) { try { Int32.Parse(carta); aux = true; } catch (Exception) { Console.WriteLine("El valor no es correcto."); carta = Console.ReadLine(); } } foreach (var cartas in referencia.getHijos()) { if (cartas.getDatoRaiz().carta == Int32.Parse(carta)) { referencia = cartas; turno = false; Console.WriteLine("Ok"); break; //Una vez que encuentra la carta pasada se rompe el foreach y evaulua el turno } } if (referencia.getDatoRaiz().carta != Int32.Parse(carta)) //Si donde esta ubicado el arbol en ese momento no coincide con la carta entonces quiere decir que un valor es incorrecto. // O quiere decir que se paso del limite. { Console.WriteLine("La carta no esta disponible o se a alcanzado el limite del maso. Volviendo a la jugada..."); return; } } if (turno == false) { Console.WriteLine("Ingrese la carta que tiraría computer:"); string carta = Console.ReadLine(); bool aux = false; while (aux == false) { try { Int32.Parse(carta); aux = true; } catch (Exception) { Console.WriteLine("El valor no es correcto."); carta = Console.ReadLine(); } } foreach (var cartas in referencia.getHijos()) { if (cartas.getDatoRaiz().carta == Int32.Parse(carta)) { referencia = cartas; turno = true; Console.WriteLine("Ok"); break; //Una vez que encuentra la carta pasada se rompe el foreach y consulta si quiere terminar la jugada o seguir agregando mas jugadas. } } if (referencia.getDatoRaiz().carta != Int32.Parse(carta)) //Si donde esta ubicado el arbol en ese momento no coincide con la carta entonces quiere decir que un valor es incorrecto. { Console.WriteLine("La carta no esta disponible o se a alcanzado el limite del maso. Volviendo a la jugada..."); return; } } Console.WriteLine("Desea continuar la jugada?: Cualquier tecla para Si u oprima 'N' para no"); string rta2 = Console.ReadLine().ToUpper(); if (rta2 == "N") { rta = !rta; } } Console.WriteLine("Los posibles resultados para la jugada que acaba de ingresar son:"); Console.WriteLine(); computer.ImprimirHojas(referencia); //Imprime posibles resultados }
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. } } } }