Código fuente del juego de ajedrez móvil
Primero comprenda la estructura de los datos:
Primero debe mirar lo que hay en MantisChessDef.h; de lo contrario, se perderá.
Y las coordenadas del tablero:
El tamaño del tablero es 9x10. Para facilitar la programación, se especifica que cada lado del tablero tiene un límite de elemento.
El tamaño del tablero (incluidos los bordes) pasa a ser de 11x12. El eje x del tablero de ajedrez está hacia la derecha y el eje y está hacia abajo.
El negro siempre está arriba. Las coordenadas del coche negro en la esquina superior izquierda en la salida estándar son (1, 1).
Esta situación está representada por las siguientes tres variables:
punto estático g punto pieza de ajedrez [32]; //coordenadas del ajedrez
static int g _ iChessmanMap [11][12]; //Estado de la posición de ajedrez
static int g_iSide//¿A quién le toca?
Los primeros tres parámetros de varias funciones en la parte inteligente son esto. Debería ser fácil de entender, ¿verdad?
-
Función de búsqueda:
En primer lugar, mis amigos a menudo me preguntan sobre el principio, pero les revelo el código fuente para su referencia, no para ningún tutoriales, así que no quiero hablar de esas cosas teóricas.
El principio básico es la búsqueda α-β, que se menciona en muchos libros de texto de inteligencia artificial. Si no lo has leído, busca un libro y léelo.
Aunque la mayoría de las palabras de estos libros son oscuras y difíciles de entender, al fin y al cabo son claras.
Si no tienes un libro, usa tu discreción y encuéntralo tú mismo. No me lo pidas porque yo tampoco lo tengo.
Aquí solo analizo la función de búsqueda:
Comprenda la búsqueda α-β y luego mire este árbol de juegos para ver cómo programar.
Para ser claros, utilizamos un número entero para representar la situación.
Cuanto mayor sea el número, más favorable será la situación para el jugador, y 0 significa que ambos bandos son igualmente poderosos.
1a(1)┬2a(-1)┬3a(-1)
│ └ 3b( 1)
└ 2b(-5) ┬ 3c( 2)
├ 3d(-4)
└ 3e( 5)
Al analizar este árbol, existe una característica de este tipo: el valor del nodo padre = -MAX (valor del nodo hijo).
También sabemos que 1, cada nodo corresponde a una situación. 2. El valor del nodo inferior es el "valor estimado".
Entonces podemos escribir pseudocódigo:
Pseudocódigo: busca las ramas debajo de un nodo y obtiene el valor de este nodo.
Parámetros: situación, profundidad de búsqueda
Valor de retorno: el valor del nodo.
Int search(case, int profundidad)
{
if (profundidad!=0) // no es un nodo inferior.
{
Enumerar todos los nodos secundarios (enumerar todos los métodos);
Int count=número de nodos secundarios;
int valor máximo =-∞;
for(int I = 0; I lt count; I)//Atravesar todos los nodos.
{
Calcular el estado del nodo secundario;
Maxvalue=max(maxvalue, search(estado del nodo secundario, profundidad-1));
}
valor de retorno-max;
}
Else //Es el nodo inferior.
{
Devuelve el valor estimado
}
}
Este es el marco de la búsqueda; Algoritmo de recursividad.
Las funciones inteligentes de MantisChessThink.cpp están todas en MantisChessThink.cpp, donde buscar es buscar, que es similar a la búsqueda anterior. Déjame copiarlo y hacer un comentario:
int Search(int tmap[11][12], POINT tmanposition[32], int amptside, int man, POINT point, int upmax, int Depth)
{
//Los primeros tres parámetros son la situación.
//El hombre y el punto son métodos de caminata que se utilizan para calcular la situación de este nodo. Aquí, el cálculo se coloca al comienzo de la función, que es diferente del pseudocódigo anterior.
//upmax: capa superior-superior, valor máximo-máximo, que se utiliza para la poda α-β, que se discutirá más adelante.
//profundidad: profundidad de búsqueda
int ate, cur, maxvalue, curvalue, xs, ys
int count
//# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
ate = 32
//Mover la pieza de ajedrez:
xs=tmanposition[man]. x;ys=tmanposición[hombre]. y; //Coordenadas originales
if(SideOfMan[tmap[point . x][point . y]]= =! Tside) //El punto objetivo tiene la pieza de ajedrez del oponente.
{
ate = tmap[point . x][point . y]; //Registra las piezas capturadas
if(ate==0 | | comió==16)
{
Devuelve 9999;
}
posición tman [comió]. x = 0; //Se captura la pieza de ajedrez en el punto objetivo.
}
tmap[point . x][point . y]= man; //Estas dos líneas son:
tmap[xs][ys] = 32; //Movimiento en el mapa
tman position[man]= punto;
tside=! tside
//####################################### # #########################################
Profundidad- ;
if(profundidad gt0) //No es el nodo inferior.
{
Pieza de ajedrez de inteligencia[125];
PUNTO objetivo PUNTO[125];
If (enumlist (tmap, tmanposition , tside,chesman,targetpoint,count))//Enumerar todos los nodos secundarios (enumerar todas las rutas).
{
//@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@
//Esto es poda (no poda α-β). El principio es utilizar una búsqueda superficial para obtener el valor con un gran error antes de la búsqueda formal.
//Luego, los nodos secundarios se ordenan según estos valores y solo se retienen los mejores nodos S_WIDTH para la búsqueda formal.
//Evidentemente, esta poda tiene ciertos riesgos.
if(profundidad gt= 2 amp ampcount gtS_WIDTH 2)
{
int valor[125];
cur = 0;
valor máximo =-10000;
mientras(cur lt; recuento)
{
curvalue=Buscar(tmap, tmanposition, tside, chessman[cur], targetpoint[cur], -10000, profundidad-2);
valor[cur]= valorcur;
if (valor de curva gtmax valor)valor máximo = curvalue;
cur;
}
* Mantis _ clasificación rápida (valor, pieza de ajedrez, punto objetivo, 0, cuenta-1); Ordenar
count = S _ WIDTH//Recortar
}
//@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@
valor máximo =-10000
cur = 0
mientras(cur lt; recuento)
{
curvalue=Buscar(tmap, tmanposition, tside, chessman[cur], targetpoint[cur], maxvalue, profundidad);
if (valor de curva gtmax value)max value = curvalue;
if (valor de curva gt=-up max)goto _ end sub; //poda α-β, se cortarán aquellos que cumplan con las condiciones de poda. Aquí se usa la declaración goto, no me imites.
cur;
}
}
else valor máximo = 9800
}
Else //Es el nodo subyacente.
{
maxvalue=Value(tmap, tmanposition, tside // Valoración
}
_ENDSUB:
//Volver a la situación anterior de restaurar el nodo principal.
//######################################## # ########################################
el lugar del hombre. x = xs//Estas dos líneas son:
La posición del hombre.
y = ys//Recuperación facial
tmap[xs][ys]= man; //Recuperar en el mapa
If (ate!=32)
{
posición tman[ate]= punto;
tmap[punto . x][punto ]= comido;
}
<. p>else tmap[punto . x][punto y]= 32;tside=! tside
//####################################### # #########################################
regresar- valor máximo;
}
El código anterior utiliza poda α-β, como se puede ver en un ejemplo:
Sigue siendo este árbol de juego, atravesado de arriba a abajo.
1a(1)┳2a(-1)┳3a(-1)
┃ ┗ 3b( 1)
┗ 2b(-5) ┯ 3c( 2)
├ 3d(-4)
└ 3e( 5)
Upmax=-1 después del recorrido 2a, 3c devuelve 2b después del recorrido, Encontré que 3c = 2>-upmax, entonces no te preocupes por 3d y 3e, porque no importa cuáles sean sus valores, 2b =-max (3c, 3d, 3e)
En otras palabras , 2b se puede cortar de forma segura. Esta es la poda alfa-beta.
A juzgar por el código anterior, mi algoritmo de ajedrez de mantisa no es diferente de la búsqueda de poda estándar α-β, excepto que se agregan clasificación y poda.
Lo encontré en Internet. Jaja, estoy de acuerdo.
0|Comentarios
2012-4-14 23:25 lee xye | Nivel 6
Incluso si se proporciona este código fuente directo, supongo que puedo No leo.
0|Comentarios