Pop

Curso programación C# - 77. Inteligencia Artificial con C# (6)- Visual Studio 2017

77. Inteligencia Artificial (6).Lógica para evitar un jaque(1)

 -  En este capítulo del curso de programación en c# con visual studio 2017 vamos a continuar con nuestra serie de entradas relacionadas con un tema de moda: la inteligencia artificial. En la entrada anterior enseñamos a nuestro agente  a comer piezas.En este capítulo trataremos de evitar el jaque que nos hagan las piezas blancas.

- En esta entrada aprenderemos a evitar el jaque del rival mediante dos mecanismos: comiendo la pieza del rival  que no está atacando o moviendo el rey a alguna casilla libre.En la siguiente entrada del blog trataremos de evitar el jaque de nuestro adversario bloqueando la trayectoria de la pieza que nos este atacando. De momento os dejo el vídeo con el código de los dos mecanismos anteriormente mencionados:



- Os pongo el código de los métodos modificado en este vídeo:

  //Obtener todos los posibles movimientos de todas las piezas negras y de momento generao un movimiento aleatorio
        #region Nuevo
        public void generarMovimientoAleatorio()
        {

            int posinicial = 0;
            ArrayList arrayPiezas = new ArrayList();
            ArrayList arrayPosInicialPiezas = new ArrayList();
            ArrayList arrayValorMovimiento = new ArrayList();


            int posicionJaque = 0;
            int posicionReyJaque = 0;
            Boolean SiJaque = false;
            Pieza piezaAux = new Pieza();
            Pieza reyAux = null;


            //Si nos dan jaque buscamos que pieza nos lo esta dando y en que posicion por si al calcular los movimientos de las piezas negras pudieramos comernos la pieza.También seleccionamos la pieza rey.
            if (motor.tablero.jaqueNegro)
            {

                foreach (Cuadrado c in motor.tablero.Escaques)
                {

                    //Guardamos en variable auxiliar la pieza rey negro
                    if (c.pieza != null && c.pieza.colorPieza == ColorPieza.Negro && c.pieza.tipoPieza == TipoPiezaAjedrez.Rey )
                                    reyAux = c.pieza;
               

                    //Buscamos que pieza nos esta dando jaque
                    if (c.pieza != null && c.pieza.colorPieza == ColorPieza.Blanco && c.pieza.DandoJaque == true)
                    {
                        SiJaque = true;
                        piezaAux = c.pieza;
                    }
                    if(!SiJaque)
                    posicionJaque++;

                    if(reyAux==null)
                    posicionReyJaque++;
                }

                if (!SiJaque)
                    posicionJaque = -1;
            }


            //Recorremos el tablero y guardamos la posicion de las piezas negras con algun movimiento valido
            foreach (Cuadrado c in motor.tablero.Escaques)
            {

                if (c.pieza != null && c.pieza.colorPieza == ColorPieza.Negro && c.pieza.movimientosValidos.Count > 0)
                {

                    arrayPiezas.Add(c.pieza);
                    arrayPosInicialPiezas.Add(posinicial);
                    arrayValorMovimiento.Add(valorMovimiento(c.pieza, motor.tablero, posicionJaque));

                }

                posinicial++;
            }



            //Recorremos el array con los valores de los movimientos y elegimos el que mayor valor tenga si no elegimos un movimiento aleatorio
            int maxValor = 0;
            int posicionArray = 0;
            for (int i = 0; i < arrayValorMovimiento.Count; i++)
            {

                if (((MovimientoSeleccionado)arrayValorMovimiento[i]).ValorMovimiento > maxValor)
                {
                    maxValor = ((MovimientoSeleccionado)arrayValorMovimiento[i]).ValorMovimiento;
                    posicionArray = i;

                }
            }


            byte columnainicio = 0;
            byte filaInicio = 0;
            byte columnaDestino = 0;
            byte filaDestino = 0;
            int posicionInicial = 0;

            //Si nos estan dando jaque y no nos podemos comer la pieza que nos lo esta dando movemos el rey
            if (SiJaque && maxValor != 100000)
            {
                Random random = new Random();
                columnainicio = Convert.ToByte(posicionReyJaque % 8);
                filaInicio = Convert.ToByte(posicionReyJaque / 8);
                int posicionAleatoriaRey = random.Next(0,reyAux.movimientosValidos.Count);
                columnaDestino = Convert.ToByte((reyAux.movimientosValidos.ElementAt(posicionAleatoriaRey) % 8));
                filaDestino = Convert.ToByte((reyAux.movimientosValidos.ElementAt(posicionAleatoriaRey) / 8));

                //Meter logica para bloquear la trayectoria de la pieza que nos esta atacando

            }
            else
            {

                //Si no nos aporta valor movemos cualquier ficha aleatoriamente
                if (maxValor > 0)
                {
                    posicionInicial = Convert.ToInt32(arrayPosInicialPiezas[posicionArray]);
                    columnainicio = Convert.ToByte(posicionInicial % 8);
                    filaInicio = Convert.ToByte(posicionInicial / 8);
                    columnaDestino = Convert.ToByte(((MovimientoSeleccionado)arrayValorMovimiento[posicionArray]).PosicionDestino % 8);
                    filaDestino = Convert.ToByte(((MovimientoSeleccionado)arrayValorMovimiento[posicionArray]).PosicionDestino / 8);
                }
                else
                {
                    //Seleccionamos aleatoriamente la pieza a mover y obtenemos columna y fila inicial
                    Random random = new Random();
                    int piezaAletoria = random.Next(0, arrayPiezas.Count);
                    posicionInicial = Convert.ToInt32(arrayPosInicialPiezas[piezaAletoria]);
                    columnainicio = Convert.ToByte(posicionInicial % 8);
                    filaInicio = Convert.ToByte(posicionInicial / 8);

                    ////Dentro de los movimientos validos selecionamos aleatoriamente alguno de ellos.Primero hacemos un random de los posible movimientos y
                    ////luego seleccionamos uno de ellos
                    int posicionAleatoria = random.Next(0, ((Pieza)arrayPiezas[piezaAletoria]).movimientosValidos.Count);
                    columnaDestino = Convert.ToByte(((Pieza)arrayPiezas[piezaAletoria]).movimientosValidos.ElementAt(posicionAleatoria) % 8);
                    filaDestino = Convert.ToByte(((Pieza)arrayPiezas[piezaAletoria]).movimientosValidos.ElementAt(posicionAleatoria) / 8);
                }
            }


            motor.moverPieza(columnainicio, filaInicio, columnaDestino, filaDestino);


        }

        //Funcion para calcular el valor de un movimiento y la posicion detino que la almacenamos en el nuevo objeto MovimientoSeleccionado
        private MovimientoSeleccionado valorMovimiento(Pieza piezaMover, Tablero tablero , int PosicionJaque )
        {
            MovimientoSeleccionado mov = new MovimientoSeleccionado();
            mov.ValorMovimiento = 0;
            int posicionpiezaBlanca = 0;
            int valorMovimientoAux = 0;
            //si en alguno de los posibles movimientos hay una pieza que se pueda comer guardamos su peso y posicion
            for (int i = 0; i < piezaMover.movimientosValidos.Count; i++)
            {
                posicionpiezaBlanca = 0;
                foreach (Cuadrado c in motor.tablero.Escaques)
                {
                    if (c.pieza != null && c.pieza.colorPieza == ColorPieza.Blanco && piezaMover.movimientosValidos.ElementAt(i)==posicionpiezaBlanca)
                    {
                        //Si nos podemos comer una pieza que nos esta haciendo jaque le damos el máximo valor
                        if (posicionpiezaBlanca == PosicionJaque)
                            valorMovimientoAux = 100000;
                        else
                        valorMovimientoAux = c.pieza.valorPieza;

                        if (valorMovimientoAux > mov.ValorMovimiento)
                            mov.ValorMovimiento = valorMovimientoAux;

                        mov.PosicionDestino = posicionpiezaBlanca;
                    }
                    posicionpiezaBlanca++;
                }
            }
            return mov;
        }





No hay comentarios:

Publicar un comentario

Curso .NET Core en C# - 34.Creamos nuestro propio log

34.Creamos nuestro propio log Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de  ASP.NET...