76. Inteligencia Artificial (5).Comiendo piezas
- 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 aprendimos a generar movimientos aleatorios en nuestro tablero, que en realidad es una matriz.En esta ocasión nuestro agente tiene como objetivo comer fichas del rival en función del peso que tengan asignado.
- Para ello hemos asignado a cada pieza del rival un valor:
- Peón: 100 puntos
- Caballo:320 puntos
- Alfil:325 puntos
- Torre:500 puntos
- Reina: 975 puntos
- Rey: 32767 puntos
- En función de los valores que tengan asignadas las piezas nuestro agente tratara de comer una pieza u otra en función del valor que tenga asignada.En el vídeo lo podemos ver más claro:
- En siguientes entradas iremos mejorando nuestro jugador para que además de intentar comer piezas del rival tenga en cuenta las posibles consecuencias de hacerlo.Por el momento os dejo el código de lo visto en el vídeo:
- Nueva clase MovimientoSeleccionado.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AjedrezIA
{
public class MovimientoSeleccionado
{
int valorMovimiento;
int posicionDestino;
public int ValorMovimiento { get => valorMovimiento; set => valorMovimiento = value; }
public int PosicionDestino { get => posicionDestino; set => posicionDestino = value; }
public MovimientoSeleccionado()
{
valorMovimiento = 0;
posicionDestino = 0;
}
}
}
- Métodos utilizados en este capítulo:
//Obtener todos los posibles movimientos de todas las piezas negras y de momento generao un movimiento aleatorio
public void generarMovimientoAleatorio()
{
int posinicial = 0;
ArrayList arrayPiezas = new ArrayList();
ArrayList arrayPosInicialPiezas = new ArrayList();
ArrayList arrayValorMovimiento = new ArrayList();
if (motor.tablero.jaqueNegro)
{
//Ver que hacemos en caso de jaque al rey
}
else
{
//Recorremos el tablero y guardamos la posicion de las piezas negras con algun movimiento valido en el caso que no sea jaque
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));
}
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 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 )
{
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)
{
valorMovimientoAux = c.pieza.valorPieza;
if (valorMovimientoAux > mov.ValorMovimiento)
mov.ValorMovimiento = valorMovimientoAux;
mov.PosicionDestino = posicionpiezaBlanca;
}
posicionpiezaBlanca++;
}
}
return mov;
}
No hay comentarios:
Publicar un comentario