// Routine qui obtient une commande a partir de la console. // Pour interfacer le moteur avec tout autre interface, on peut passer // directement la fonction engine. void Entree( char* o_szCommande ) { static char szText[255]; // En mode xboard on n'affiche pas la demande de commande. if ( !xboard ) { // Les blancs ou les noirs. if ( wtm ) sprintf( szText, "Blanc (%d): ", cb.NoCoups/2+1); else sprintf( szText, "Noir (%d): ", cb.NoCoups/2+1); printf( "%s", szText ); } strcpy( o_szCommande, "" ); do { scanf( "%s", o_szCommande ); journal.Log("entree: %s", o_szCommande); } while( strlen( o_szCommande ) == 0 ); }
// Algorithme de recherche MinMax avec des coupes Alpha-Beta. int Search(int depth, int ply, int wtm, int alpha, int beta, bool do_null) { register int Valeur, AlphaInitiale, check_ext = 0, extension = 0, MoveCherche, danger = 0; if ( ply >= MAXPLY-1 ) return beta; iNodes++; // Si on n'est pas en mode Analyse, Reste-t-il du temps? if ( interrupted || (timeabort && !g_bModeAnalyse) ) { return beta; } AlphaInitiale = alpha; // Calculer le temps restant. if ( (iNodes & 0xFF ) == 0xFF ) { if ( TimeCheck() ) { timeabort = true; } // Verifier si il y a quelque chose dans le tampon // d'entree. if ( inter() ) { char buf[10]; int c = fgetc(stdin); if (c == 10) { c = fgetc(stdin); ungetc(c, stdin); if (c == '.') { scanf("%s", &buf); printf( "stat01: %d %d %d %d %d\n", (TempsCenti()-timestamp), iNodes, iProfondeurIteration, cb.MoveList[1].nbmove - cb.MoveList[1].currmove-1, cb.MoveList[1].nbmove ); journal.Log("received a dot\n"); } else { interrupted = true; } } else { ungetc(c, stdin); interrupted = true; } } } // Verifier si ce n'est pas une nulle. if (Repetition(wtm)) { //if ( 0 < beta ) { // pv[ply-1][ply-1] = cb.CurrentPath.moves[ply-1]; return 0; // if ( wtm ) { // return DRAWSCORE; // } // else { // return -DRAWSCORE; // } //} } // Regarder dans la table de transposition pour voir si cette position // n'a pas deja ete calculer. #ifdef TRANSPOSITION switch( TableTrans->Lookup( cb, ply, depth, wtm, alpha, beta, danger ) ) { case SCORE_EXACTE: return alpha; case BORNE_SUPERIEUR: return alpha; case BORNE_INFERIEUR: return beta; case EVITER_NULL: do_null = false; } #endif #ifdef NULL_MOVE // En premier, on essai le NULL MOVE. if ( do_null ) { int nbPiece = wtm?cb.TotalMaterielBlanc:cb.TotalMaterielNoir; if ( !cb.inCheck[ply] && nbPiece > 5 && depth > 3 && alpha == beta-1) { int EnPassantB = cb.EnPassantB[ply+1]; int EnPassantN = cb.EnPassantN[ply+1]; cb.EnPassantB[ply+1] = -1; cb.EnPassantN[ply+1] = -1; Valeur = -Search(depth-3, ply+1, !wtm, -beta, -beta+1, false); cb.EnPassantB[ply+1] = EnPassantB; cb.EnPassantN[ply+1] = EnPassantN; if ( Valeur >= beta ) { #ifdef TRANSPOSITION TableTrans->StoreRefutation( cb, ply, depth, wtm, Valeur, alpha, beta, danger ); #endif return Valeur; } if ( Valeur <= -MATE+50 ) danger = 1; } } #endif // Internal Iterative Deepening. /* if ( depth > 2 && ((!(ply&1) && alpha==root_alpha && beta==root_beta) || ((ply&1) && alpha==-root_beta && beta==-root_alpha)) && cb.HashMove[ply].From == 0 && cb.HashMove[ply].To == 0 ) { Valeur = ABSearch( cb, depth-2, ply, wtm, alpha, beta, true ); if ( Valeur <= alpha ) { Valeur = ABSearch( cb, depth-2, ply, wtm, -MATE, beta, true ); } else { if ( Valeur < beta ) { cb.HashMove[ply] = pv[ply-1][ply]; } else cb.HashMove[ply] = cb.CurrentPath.moves[ply]; } }*/ #ifdef TRANSPOSITION Phase[ply] = HASH_MOVE; #else // if ( ((!(ply&1) && alpha==root_alpha && beta==root_beta) || // ( (ply&1) && alpha==-root_beta && beta==-root_alpha)) ) Phase[ply] = PV_MOVE; // else // Phase[ply] = GENERATE_CAPTURE_MOVES; #endif // Maintenant, evaluer chaque coup. MoveCherche = 0; while( Phase[ply] != NO_MORE_MOVES && !interrupted ) { if ( NextMove( cb, ply, wtm ) ) { // Si // On execute le coup. MakeMove(ply, cb.MoveList[ply].CurrentMove(), wtm); // Mettre le coup dans le chemin actuel. cb.CurrentPath.moves[ply] = cb.MoveList[ply].moves[cb.MoveList[ply].currmove]; if (!Check(wtm)) { MoveCherche++; // Si le coup met en echec etendre la recherche d'une profondeur // pour qu'il puisse en sortir. if (Check(!wtm) ) { cb.inCheck[ply+1] = true; extension = 1; cb.RaisonExtension[ply] = EXTENSION_ECHEC; } else { extension = 0; cb.inCheck[ply+1] = false; cb.RaisonExtension[ply] = PAS_EXTENSION; } // Si le coup est une recapture // etendre la recherche d'une profondeur. if ( cb.CurrentPath.moves[ply].Capture && abs(ValeurPiece[cb.CurrentPath.moves[ply-1].Capture] - ValeurPiece[cb.CurrentPath.moves[ply].Capture]) <= 20 && (cb.CurrentPath.moves[ply-1].To == cb.CurrentPath.moves[ply].To) && cb.RaisonExtension[ply-1] != EXTENSION_RECAPTURE) { extension = 1; cb.RaisonExtension[ply] = EXTENSION_RECAPTURE; } // Si on est sur le point de promouvoir un pion, étendre la recherche // pour voir si c'est une menace. if ( extension == 0 && cb.CurrentPath.moves[ply].Piece == 1 && PromoteExtension[ cb.CurrentPath.moves[ply].To ] ) { extension = 1; cb.RaisonExtension[ply] = EXTENSION_PROMOTION; } // Si on pousse un pion passe, pousser la recherche plus // loin pour voir si c'est un danger. if ( cb.CurrentPath.moves[ply].Piece == pion ) if ( wtm ) { if ( cb.CurrentPath.moves[ply].To <= H5 ) if ( cb.PionPasseB[cb.CurrentPath.moves[ply].To&7] ) { extension = 1; cb.RaisonExtension[ply] = EXTENSION_PIONPASSE; } } else { if ( cb.CurrentPath.moves[ply].To >= A4 ) if ( cb.PionPasseN[cb.CurrentPath.moves[ply].To&7] ) { extension = 1; cb.RaisonExtension[ply] = EXTENSION_PIONPASSE; } } // Razoring trick. Idee prise dans Crafty. if ( depth == 2 && !cb.inCheck[ply] && extension == 0 ) { int valeur; if ( wtm ) valeur = Eval(ply, wtm, alpha, beta); else valeur = -Eval(ply, wtm, alpha, beta); if ( valeur+50 < alpha ) extension = -1; } // On l'explore. // Si c'est la variation principale, Fenetre normale, sinon, // fenetre est n et n+1. int inpv = 1; if (ply&1) { if ( alpha != root_alpha || beta != root_beta ) inpv = 0; } else { if ( alpha != -root_beta || beta != -root_alpha ) inpv = 0; } if ( inpv ) { Valeur = -ABSearch(depth-1+extension+danger, ply+1, !wtm, -beta, -alpha, true); } else { Valeur = -ABSearch(depth-1+extension+danger, ply+1, !wtm, -alpha-1, -alpha, true); if ( Valeur > alpha && Valeur < beta ) { pvsresearch++; Valeur = -ABSearch(depth-1+extension+danger, ply+1, !wtm, -beta, -alpha, true); } } } else { Valeur = -INFINI; } cb.MoveList[ply].CurrentMove().Score = Valeur; // On defait le coup. UnmakeMove(ply, cb.MoveList[ply].CurrentMove(), wtm); if (interrupted) return Valeur; #ifdef DEBUG Consistence( cb, cb.MoveList[ply].CurrentMove() ); #endif // Est-il meilleur que notre valeur actuelle? if ( Valeur > alpha ) { if ( Valeur >= beta ) { #ifdef TRANSPOSITION TableTrans->StoreRefutation( cb, ply, depth, wtm, Valeur, alpha, beta, check_ext ); #endif g_iRefutation++; // Verifier si on peu l'utiliser comme killer move. if ( Phase[ply] == NON_CAPTURE_MOVES ) { cb.AddKiller( &cb.CurrentPath.moves[ply-1], ply-1 ); } else { if ( Phase[ply] == KILLER_MOVE_2 ) cb.Killers[ply-1][0].Score++; else if ( Phase[ply] == GENERATE_NON_CAPTURE_MOVES ) cb.Killers[ply-1][1].Score++; } return Valeur; } pv[ply][ply] = cb.CurrentPath.moves[ply]; pv_length[ply] = pv_length[ply+1]; memcpy(&pv[ply][ply+1], &pv[ply+1][ply+1], sizeof(TMove)*(pv_length[ply]-ply)); alpha = Valeur; } } // if } // Verifier si il y a mat ou pat. if ( MoveCherche == 0 ) { if (!Check(wtm)) { pv[ply][ply] = cb.CurrentPath.moves[ply]; return 0; // if ( wtm ) { // return DRAWSCORE; // } // else { // return -DRAWSCORE; // } } else { if ( ply < iMateInPly ) iMateInPly = ply; alpha = -MATE+iMateInPly; } } #ifdef TRANSPOSITION TableTrans->StoreBest( cb, ply, depth, wtm, alpha, AlphaInitiale, danger ); #endif return alpha; }
// Cette routine verifie si une commande est execute, l'execute et // retourne true. Sinon elle retourne false pour que le moteur sache // que c'est un coup. bool Option( const char* i_szCommande, char* o_szReponse ) { strcpy( o_szReponse, "" ); if ( strcmp( i_szCommande, "quit" ) == 0 ) { char szBoard[1000]; char szText[10]; strcpy( szBoard, "" ); for( int i=A8; i<=H1; i++ ) { sprintf( szText, "%+2d", cb.board[i] ); strcat( szBoard, szText ); if ( i % 8 == 7 ) strcat( szBoard, "\n" ); } journal.Log( szBoard ); return true; } if (strcmp(i_szCommande, "eval") == 0) { int score = Eval(1, wtm, -INFINI, INFINI); printf("score = %d\n", score); journal.Log("score = %d", score); return true; } if (strcmp(i_szCommande, "board") == 0) { for(int i=A8; i<=H1; i++) { printf(" %2d ", cb.board[i]); if (i % 8 == 7) printf("\n"); } return true; } // On verifie la commande. // On demande le mode xboard. // Il n'y a pas de possibilite de retourne au mode normal. if ( strcmp( i_szCommande, "xboard" ) == 0 ) { journal.Log( "Interface graphique: Winboard" ); xboard = 1; return true; } // On demande une nouvelle partie. if ( strcmp( i_szCommande, "new" ) == 0 ) { cb.InitialiseBoard(); cb.InitialiseBitboard(); wtm = true; Moteur = false; Force = false; iEngTime = 5*60*100; // 5 minutes par defaut. iOppTime = 5*60*100; return true; } // Le moteur est mis en mode edit. // Permet d'entrer une position specifique. if ( strcmp( i_szCommande, "edit" ) == 0 ) { journal.Log( "Edit." ); g_bEdit = true; g_bBlanche = true; return true; } // Chargement d'une position. if ( strcmp( i_szCommande, "loadpos" ) == 0 ) { char szFichier[60]; printf( "Entrez le nom de fichier: " ); scanf( "%s", szFichier ); if (ChargePosition( cb, szFichier)) printf( "Chargement ok." ); else printf( "Chargement pas reussi." ); return true; } // Le moteur est mis en mode d'analyse. if ( strcmp( i_szCommande, "analyze" ) == 0 ) { journal.Log( "Analyse." ); Moteur = true; g_bModeAnalyse = true; Force = true; return true; } // On demande une mise à jour d'analyse. if (strcmp(i_szCommande, ".") == 0) { if (g_bModeAnalyse) return true; else return false; } // Do whisper. if ( strcmp( i_szCommande, "dowhisper" ) == 0 ) { whisper = true; } // Do whisper. if ( strcmp( i_szCommande, "nowhisper" ) == 0 ) { whisper = false; } // Le moteur doit etre sortie du mode d'analyse. if ( strcmp( i_szCommande, "exit" ) == 0 ) { journal.Log( "Exit." ); Moteur = false; Force = false; g_bModeAnalyse = false; return true; } // Le moteur joue le joueur courant. if ( strcmp( i_szCommande, "go" ) == 0 ) { journal.Nouveau(); journal.Log( "Demarrage." ); // Je sais que c'est une option et que je devrais retourner true, mais // je retourne false c'est pour forcer le moteur a jouer son coup. #ifdef ICSTALK printf("tellics set 1 %s", nomProgramme); printf("tellics say Hello from %s", nomProgramme ); #endif Moteur = true; Force = false; return false; } // Les blancs jouent les prochains. if ( strcmp( i_szCommande, "white" ) == 0 ) { journal.Log( "Les blancs jouent." ); wtm = true; return true; } // Les noirs jouent les prochains. if ( strcmp( i_szCommande, "black" ) == 0 ) { journal.Log( "Les noirs jouent." ); wtm = false; return true; } // Met le moteur avec un peu de random, pas implante. if ( strcmp( i_szCommande, "random" ) == 0 ) { return true; } // On set le level. if ( strcmp( i_szCommande, "level" ) == 0 ) { char szNbCoups[10], szNbMinute[10], szIncrement[10]; scanf("%s", szNbCoups); scanf("%s", szNbMinute); scanf("%s", szIncrement); iNbCoups = atoi(szNbCoups); iEngTime = atoi(szNbMinute) * 60 * 100; if (iNbCoups == 0) iNbCoups = 80; return true; } // Show thinking. if ( strcmp( i_szCommande, "post" ) == 0 ) { Post = true; return true; } // No show thinking. if ( strcmp( i_szCommande, "nopost" ) == 0 ) { Post = false; return true; } // Le moteur peu penser sur le temps du joueur au prochain coup. if ( strcmp( i_szCommande, "hard" ) == 0 ) { printf( "(no pondering)\n" ); return true; } // Le moteur ne pense que sur son temps. if ( strcmp( i_szCommande, "easy" ) == 0 ) { printf( "(no pondering)\n" ); return true; } if (strcmp(i_szCommande, "st") == 0) { scanf("%d", &iMoveTime); journal.Log("move time = %d", iMoveTime); return true; } // Set l'horloge. if ( strcmp( i_szCommande, "time" ) == 0 ) { scanf( "%d", &iEngTime ); char szTemp[20]; sprintf( szTemp, "%d", iEngTime ); journal.Log( "time = %d", iEngTime ); return true; } // La deuxieme horloge. if ( strcmp( i_szCommande, "otim" ) == 0 ) { scanf( "%d", &iOppTime ); journal.Log("otime = %d", iOppTime); return true; } if ( strcmp( i_szCommande, "name" ) == 0 ) { char szName[40]; scanf( "%s", szName ); journal.Log( "name = %s", szName ); TSeeker::stop(); return true; } if ( strcmp( i_szCommande, "rating" ) == 0 ) { int myrating, rating; scanf( "%d", &myrating ); journal.Log( "my rating = %d", myrating ); scanf( "%d", &rating ); journal.Log( "Opponent rating = %d", rating ); return true; } if ( strcmp( i_szCommande, "protover" ) == 0 ) { float version; scanf( "%f", &version ); journal.Log( "proto version: %f\n", version ); return true; } // Le moteur est mis off-line. Les prochains coups recus doit // etre verifier pour validite mais le moteur ne reponds pas par un // coup et ne pense pas non plus (no pondering) if ( strcmp( i_szCommande, "force" ) == 0 ) { Force = true; return true; } // La partie est finie, on recoit le resultat. // Pas implante. if ( strcmp( i_szCommande, "result" ) == 0 ) { char szTemp[255]; fgets( szTemp, sizeof( szTemp ), stdin ); TSeeker::start(); return true; } // // Generation de la librairie d'ouverture de depart. // if ( strcmp( i_szCommande, "createbook" ) == 0 ) { char szText[255]; scanf( "%s", szText ); CreateStartBook( szText ); return true; } return false; }
// Routine pour l'aide au debogage. void Consistence( TChessBoard& i_CBoard, TMove& move ) { // Pour chaque case de l'echiquier, verifier si les bitboards sont // consistent avec. bool bConsistent = true; for( int i=A8; i<=H1; i++ ) { // Case vide. if ( i_CBoard.board[i] == 0 ) { bConsistent = bConsistent && (mask[i] & i_CBoard.piece) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et piece." ); bConsistent = bConsistent && (mask[i] & i_CBoard.pieceb) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceb." ); bConsistent = bConsistent && (mask[i] & i_CBoard.piecen) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et piecen." ); bConsistent = bConsistent && (mask[Rotate90LMap[i]] & i_CBoard.pieceR90L) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR90L." ); bConsistent = bConsistent && (mask[Rotate45LRealMap[i]] & i_CBoard.pieceR45L) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR45L." ); bConsistent = bConsistent && (mask[Rotate45RRealMap[i]] & i_CBoard.pieceR45R) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR45R." ); bConsistent = bConsistent && (mask[i] & i_CBoard.vide) == mask[i]; if ( !bConsistent ) journal.Log( "Inconsistence entre board et vide." ); bConsistent = bConsistent && (mask[i] & i_CBoard.pionb) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pionb." ); bConsistent = bConsistent && (mask[i] & i_CBoard.pionn) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pionn." ); bConsistent = bConsistent && (mask[i] & i_CBoard.cavalierb) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et cavalierb." ); bConsistent = bConsistent && (mask[i] & i_CBoard.cavaliern) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et cavaliern." ); bConsistent = bConsistent && (mask[i] & i_CBoard.foub) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et foub." ); bConsistent = bConsistent && (mask[i] & i_CBoard.foun) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et foun." ); bConsistent = bConsistent && (mask[i] & i_CBoard.tourb) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et tourb." ); bConsistent = bConsistent && (mask[i] & i_CBoard.tourn) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et tourn." ); bConsistent = bConsistent && (mask[i] & i_CBoard.dameb) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et dameb." ); bConsistent = bConsistent && (mask[i] & i_CBoard.damen) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et damen." ); bConsistent = bConsistent && (mask[i] & i_CBoard.roib) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et roib." ); bConsistent = bConsistent && (mask[i] & i_CBoard.roin) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et roin." ); if ( !bConsistent ) { char Erreur[255]; sprintf( Erreur, "From: %d To: %d Piece: %d Capture: %d EnPassant: %d Promotion: %d", move.From, move.To, move.Piece, move.Capture, move.EnPassant, move.Promotion ); journal.Log( "Erreur: La case du board est vide." ); journal.Log( Erreur ); sprintf( Erreur, "Case %d contient %d", i, i_CBoard.board[i] ); journal.Log( Erreur ); GetCurrent( ChessBoard, Erreur, 4 ); journal.Log( Erreur ); exit(1); } } // Avec une piece blanche. else if ( i_CBoard.board[i] > 0 ) { bConsistent = bConsistent && mask[i] & i_CBoard.piece; if ( !bConsistent ) journal.Log( "Inconsistence entre board et piece." ); bConsistent = bConsistent && mask[i] & i_CBoard.pieceb; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceb." ); bConsistent = bConsistent && mask[Rotate90LMap[i]] & i_CBoard.pieceR90L; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR90L b." ); bConsistent = bConsistent && mask[Rotate45LRealMap[i]] & i_CBoard.pieceR45L; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR45L b." ); bConsistent = bConsistent && mask[Rotate45RRealMap[i]] & i_CBoard.pieceR45R; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR45R b." ); bConsistent = bConsistent && (mask[i] & i_CBoard.vide) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et vide." ); switch( i_CBoard.board[i] ) { case pion: bConsistent = bConsistent && mask[i] & i_CBoard.pionb; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pionb." ); break; case cavalier: bConsistent = bConsistent && mask[i] & i_CBoard.cavalierb; if ( !bConsistent ) journal.Log( "Inconsistence entre board et cavalierb." ); break; case fou: bConsistent = bConsistent && mask[i] & i_CBoard.foub; if ( !bConsistent ) journal.Log( "Inconsistence entre board et foub." ); break; case tour: bConsistent = bConsistent && mask[i] & i_CBoard.tourb; if ( !bConsistent ) journal.Log( "Inconsistence entre board et tourb." ); break; case dame: bConsistent = bConsistent && mask[i] & i_CBoard.dameb; if ( !bConsistent ) journal.Log( "Inconsistence entre board et dameb." ); break; case roi: bConsistent = bConsistent && mask[i] & i_CBoard.roib; if ( !bConsistent ) journal.Log( "Inconsistence entre board et roib." ); break; } if ( !bConsistent ) { char Erreur[255]; sprintf( Erreur, "From: %d To: %d Piece: %d Capture: %d EnPassant: %d Promotion: %d", move.From, move.To, move.Piece, move.Capture, move.EnPassant, move.Promotion ); journal.Log( "Erreur: La case du board contient une piece blanche." ); journal.Log( Erreur ); sprintf( Erreur, "Case %d contient %d", i, i_CBoard.board[i] ); journal.Log( Erreur ); GetCurrent( ChessBoard, Erreur, 4 ); journal.Log( Erreur ); exit(1); } } // Avec une piece noire. else { bConsistent = bConsistent && mask[i] & i_CBoard.piece; if ( !bConsistent ) journal.Log( "Inconsistence entre board et piece." ); bConsistent = bConsistent && mask[i] & i_CBoard.piecen; if ( !bConsistent ) journal.Log( "Inconsistence entre board et piecen." ); bConsistent = bConsistent && mask[Rotate90LMap[i]] & i_CBoard.pieceR90L; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR90L n." ); bConsistent = bConsistent && mask[Rotate45LRealMap[i]] & i_CBoard.pieceR45L; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR45L n." ); bConsistent = bConsistent && mask[Rotate45RRealMap[i]] & i_CBoard.pieceR45R; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pieceR45R n." ); bConsistent = bConsistent && (mask[i] & i_CBoard.vide) == 0; if ( !bConsistent ) journal.Log( "Inconsistence entre board et vide." ); switch( i_CBoard.board[i] ) { case -pion: bConsistent = bConsistent && mask[i] & i_CBoard.pionn; if ( !bConsistent ) journal.Log( "Inconsistence entre board et pionn." ); break; case cavalier: bConsistent = bConsistent && mask[i] & i_CBoard.cavaliern; if ( !bConsistent ) journal.Log( "Inconsistence entre board et cavaliern." ); break; case -fou: bConsistent = bConsistent && mask[i] & i_CBoard.foun; if ( !bConsistent ) journal.Log( "Inconsistence entre board et foun." ); break; case -tour: bConsistent = bConsistent && mask[i] & i_CBoard.tourn; if ( !bConsistent ) journal.Log( "Inconsistence entre board et tourn." ); break; case -dame: bConsistent = bConsistent && mask[i] & i_CBoard.damen; if ( !bConsistent ) journal.Log( "Inconsistence entre board et damen." ); break; case -roi: bConsistent = bConsistent && mask[i] & i_CBoard.roin; if ( !bConsistent ) journal.Log( "Inconsistence entre board et roin." ); break; } if ( !bConsistent ) { char Erreur[255]; sprintf( Erreur, "From: %d To: %d Piece: %d Capture: %d EnPassant: %d Promotion: %d", move.From, move.To, move.Piece, move.Capture, move.EnPassant, move.Promotion ); journal.Log( "Erreur: La case du board contient une piece noire." ); journal.Log( Erreur ); sprintf( Erreur, "Case %d contient %d", i, i_CBoard.board[i] ); journal.Log( Erreur ); GetCurrent( ChessBoard, Erreur, 4 ); journal.Log( Erreur ); exit(1); } } } }