L'échiquier
Puisqu'un échiquier possède 64 cases, 8 colonnes et 8 rangées, on pourrait penser que d'utiliser un tableau à deux dimensions de 8 x 8 serait l'idéal. Le problème est, lorsque nous voulons stocker les coups possibles d'une pièce, nous devons stocker deux valeurs pour chaque direction possible. C'est faisable mais légèrement moins rapide. Et, croyez-moi, le "légèrement moins rapide" devient beaucoup moins rapide lorsque le moteur évalue des milliers, et même, des millions de coups. La raison est que vous devez traiter deux valeurs à chaque fois. De plus, ça se gère un peu moins facilement.
Il est préférable d'utiliser un tableau d'une seule dimension. Essayons par exemple un tableau de 64 cases à une seule dimension. Si nous voulons stocker les coups possibles d'une tour, il suffit alors d'une seule valeur.
int dirTour[] = {-1, 1, -8, 8, 0};
Pour un fou, ça serait simplement:
int dirFou[] = {-7, 7, -9, 9, 0};
Bien sûr, ces coups sont en réalité des directions que nous allons répéter pour générer chaque coup valide pour chaque direction. Nous verrons cela dans le générateur de coups.
Bon, nous avons un échiquier.
Les pièces
#define pion 1
#define cavalier 2
#define fou 3
#define tour 4
#define dame 5
#define roi 6
Nous n'avons pas besoin de définir des constantes pour les pièces noires car nous n'avons qu'à faire -pion par exemple pour représenter un pion noir.
Une chose que j'aime bien faire aussi, c'est de définir une constante pour chaque position de l'échiquier. Cela permet de bien documenter le code lorsque nous référons une case de l'échiquier.
enum {
A8, B8, C8, D8, E8, F8, G8, H8,
A7, B7, C7, D7, E7, F7, G7, H7,
A6, B6, C6, D6, E6, F6, G6, H6,
A5, B5, C5, D5, E5, F5, G5, H5,
A4, B4, C4, D4, E4, F4, G4, H4,
A3, B3, C3, D3, E3, F3, G3, H3,
A2, B2, C2, D2, E2, F2, G2, H2,
A1, B1, C1, D1, E1, F1, G1, H1 };
Plaçons maintenant les pièces dessus. Voici le code étant explicatif en lui même grâce à nos constantes.
/* Initialisation de l'échiquier. */
memset(echiquier, 0, sizeof(echiquier)); // met toutes les cases à 0.
/* Les pions. */
for(i=A7; i<=H7; i++)
echiquier[i] = -pion; // pions noirs
for(i=A2; i<=H2; i++)
echiquier[i] = pion; // pions blancs;
/* Les cavaliers */
echiquier[B8] = echiquier[G8] = -cavalier; // cavaliers noirs
echiquier[B1] = echiquier[G1] = cavalier; // cavaliers blancs
/* Les fous */
echiquier[C8] = echiquier[F8] = -fou; // fous noirs
echiquier[C1] = echiquier[F1] = fou; // fous blancs
/* Les tours */
echiquier[A8] = echiquier[H8] = -tour; // tours noires
echiquier[A1] = echiquier[H1] = tour; // tours blanches
/* Les dames */
echiquier[D8] = -dame; // dame noire
echiquier[D1] = dame; // dame blanche
/* Les rois */
echiquier[E8] = -roi; // roi noir
echiquier[E1] = roi; // roi blanc
Voici ce que ça donne lorsqu'on l'imprime:
-4 -2 -3 -5 -6 -3 -2 -4
-1 -1 -1 -1 -1 -1 -1 -1
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
4 2 3 5 6 3 2 4
Autres informations
Il faut garder aussi quelques autres informations de plus.
Par exemple, il faut connaitre la possibilité des roques, la possibilité d'un coup en passant, le joueur à jouer et le numéro du coup.
Pour le joueur à jouer, nous utilisons seulement un entier. En C, un entier représente vrai pour toutes valeurs différentes de zéro.
unsigned int baj ;
C'est une abbréviation de Blanc à jouer. La variable est à 1 si c'est au blanc à jouer, sinon elle est à zéro.
Pour le numéro du coup, un entier aussi.
unsigned int noCoup;
Pour le coup en passant, il faut garder la case où le pion aurait dû se faire capturer en passant. Cette case sera initialisée si le joueur adverse avance son pion de 2 cases sur le départ.
int enPassant; // Valeur possible de 0 à 63.
Pour terminer, les roques.
Nous avons besoin de garder la possibilité du roque blanc côté dame, roque blanc côté roi, roque noir côté dame et roque noir côté roi.
Nous n'avons besoin que d'un bit pour chacun. Prenons donc les quatres premiers bits d'un mot.
#define ROQUEBLANCDAME 0x01
#define ROQUEBLANCROI 0x02
#define ROQUENOIRDAME 0x04
#define ROQUENOIRROI 0x08
int roque;
Pour l'initialisation, voici le code:
baj = 1; /* blanc à jouer. */
enPassant = -1; /* Pas de case en passant. */
noCoup = 0; /* Aucun coup de joué. */
/* Tous les roques sont possibles. */
roque = ROQUEBLANCDAME | ROQUEBLANCROI | ROQUENOIRDAME | ROQUENOIRROI;
Je crois que c'est tout pour l'échiquier. Nous allons maintenant passer au générateur de coups.
memset(echiquier, 0, sizeof(echiquier)); // met toutes les cases à 0.
/* Les pions. */
for(i=A7; i<=H7; i++)
echiquier[i] = -pion; // pions noirs
for(i=A2; i<=H2; i++)
echiquier[i] = pion; // pions blancs;
/* Les cavaliers */
echiquier[B8] = echiquier[G8] = -cavalier; // cavaliers noirs
echiquier[B1] = echiquier[G1] = cavalier; // cavaliers blancs
/* Les fous */
echiquier[C8] = echiquier[F8] = -fou; // fous noirs
echiquier[C1] = echiquier[F1] = fou; // fous blancs
/* Les tours */
echiquier[A8] = echiquier[H8] = -tour; // tours noires
echiquier[A1] = echiquier[H1] = tour; // tours blanches
/* Les dames */
echiquier[D8] = -dame; // dame noire
echiquier[D1] = dame; // dame blanche
/* Les rois */
echiquier[E8] = -roi; // roi noir
echiquier[E1] = roi; // roi blanc
Mis à jour (Lundi, 19 Octobre 2009 17:30)