Beispiel #1
0
// 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 );
}
Beispiel #2
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;
}
Beispiel #3
0
// 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;
}
Beispiel #4
0
// 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);
      }
    }
  }
}