示例#1
0
        public override int descartarUnaCarta()
        {
            // Dependiendo el valor de la función heuristica, si es a favor de la IA, se muestra de color verde, sino de rojo.

            Console.WriteLine("Turno IA\nCartas disponibles:");

            foreach (var carta in estado.getCartasIA()) // Se recorren todas las cartas que tenga disponible la IA
            {
                var funcHeuristicaAux = 0;

                foreach (var nodo in jugadaActual.getHijos())
                {
                    if (carta == nodo.getDatoRaiz().getCarta())
                    {
                        funcHeuristicaAux = nodo.getDatoRaiz().getFuncHeursitica();
                    }
                }

                if (funcHeuristicaAux == 1)
                {
                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                    Console.Write("(" + carta + ", " + "+" + funcHeuristicaAux + ") ");
                    Console.ResetColor();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.Write("(" + carta + ", " + funcHeuristicaAux + ") ");
                    Console.ResetColor();
                }
            }
            return(_descartarUnaCarta(jugadaActual));
        }
示例#2
0
 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);
     }
 }
示例#3
0
        public override int descartarUnaCarta()
        {
            int cartaJugada = 0;

            //la primera vez referencia es null(recien arranca el arbol minimax)
            foreach (ArbolGeneral <DatosJugada> cartas in referencia.getHijos())         //itera el nivel de cartas del humano (cuando referencia es el nivel de cartas de cumputer,
                                                                                         //referencia.getHijos sera de nuevo un nivel de cartas del humano)
            {
                if (cartas.getDatoRaiz().carta == UltimaCartaHumano)                     //busca la arbol que tenga como dato la carta que tiro el humano y se poseciona ahí
                {
                    referencia = cartas;                                                 //Nos ubicamos en los hijos del arbol correspondiente a la carta que tiro el humano
                    foreach (ArbolGeneral <DatosJugada> cartatirar in cartas.getHijos()) //itera el nivel de cartas de computer que corresponde al arbol de la carta que tiro el humano.
                    {
                        if (cartatirar.getDatoRaiz().valorDeConveniencia == 1)
                        {
                            referencia  = cartatirar;           //deja ubicado el arbol en el nivel de computer
                            cartaJugada = cartatirar.getDatoRaiz().carta;

                            return(cartaJugada);
                        }
                        else
                        {
                            //Si no encuentra con valor 1 tirara la primera que encuentre
                        }
                        {
                            referencia  = cartatirar;  //deja ubicado el arbol en el nivel de computer
                            cartaJugada = cartatirar.getDatoRaiz().carta;
                        }
                    }
                }
            }
            //referencia.porNiveles();

            return(cartaJugada);
        }
示例#4
0
        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 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);
 }
示例#6
0
        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());
        }
 private void setEstado(int carta)
 {
     foreach (var nodo in estado.getHijos())
     {
         if (nodo.getDatoRaiz() == carta)
         {
             estado = nodo;
         }
     }
 }
示例#8
0
        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.
        }
示例#9
0
        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);
        }
示例#10
0
        public override void incializar(List <int> cartasPropias, List <int> cartasOponente, int limite)
        {
            DatosJugada datosJugada = new DatosJugada(0, limite, true);

            minimax = new ArbolGeneral <DatosJugada>(datosJugada);
            bool turno = true; //esta variable se debe declarar como atributo de clase

            naipes = cartasPropias;

            crearArbol(cartasPropias, cartasOponente, limite, turno, minimax);
            Console.WriteLine(minimax.getHijos().Count);
        }
示例#11
0
        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....");
            }
        }
示例#12
0
        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 ArbolGeneral <Carta> _consultaB(ArbolGeneral <Carta> jugadaActual)
        {
            Console.Write("Ingrese una secuencia de cartas separadas por comas: ");
            string numeros = Console.ReadLine();

            string[]             cartas = numeros.Split(',');                    // se Splitea las cartas que haya escrito el usuario en la secuencia
            ArbolGeneral <Carta> aux    = jugadaActual;                          // aux apunta a la jugada actual

            foreach (string carta in cartas)                                     // se recorre carta de la secuencia
            {
                foreach (ArbolGeneral <Carta> hijo in aux.getHijos())            //se reccoren los hijos del arbol aux
                {
                    if (hijo.getDatoRaiz().getCarta() == Convert.ToInt32(carta)) // si existe
                    {
                        aux = hijo;                                              // Aux apunta a la carta actual
                        break;
                    }
                }
            }
            return(aux);
        }
        private List <ArbolGeneral <Carta> > _consultaA(ArbolGeneral <Carta> jugadaActual)
        {
            camino.Add(jugadaActual);

            if (jugadaActual.esHoja()) // Si se encuentra un nodo hoja, se lo agrega y se agrega un separador.
            {
                // camino.Add(new ArbolGeneral<Carta>(new Carta(0, 0)));
                imprimir(camino);
                Console.WriteLine();
            }
            else
            {
                foreach (ArbolGeneral <Carta> hijo in jugadaActual.getHijos())
                {
                    _consultaA(hijo);
                    camino.Remove(hijo);
                }
            }

            return(camino);
        }
示例#15
0
        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========================================================================================================================");
        }
示例#16
0
        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);
        }
示例#17
0
        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 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);
                    }
                }
            }
        }
示例#19
0
        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.
            }
        }
示例#20
0
        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);
        }