Example #1
0
int EvalNormal::Result() const {
  const Side side = board_->SideToMove();
  MoveArray move_array;
  movegen_->GenerateMoves(&move_array);
  if (move_array.size() == 0) {
    const U64 attack_map = ComputeAttackMap(*board_, OppositeSide(side));
    if (attack_map & board_->BitBoard(PieceOfSide(KING, side))) {
      return -WIN;
    } else {
      return DRAW; // stalemate
    }
  }
  return -1;
}
Example #2
0
int EvalNormal::Evaluate() {
  const Side side = board_->SideToMove();
  MoveArray move_array;
  movegen_->GenerateMoves(&move_array);
  if (move_array.size() == 0) {
    const U64 attack_map = ComputeAttackMap(*board_, OppositeSide(side));
    if (attack_map & board_->BitBoard(PieceOfSide(KING, side))) {
      return -WIN;
    } else {
      return DRAW; // stalemate
    }
  }
  int score = MATERIAL_FACTOR * PieceValDifference();
  for (size_t i = 0; i < move_array.size(); ++i) {
    const Move& move = move_array.get(i);
    board_->MakeMove(move);
    U64 attack_map = ComputeAttackMap(*board_, side);
    if (attack_map & board_->BitBoard(PieceOfSide(KING, OppositeSide(side)))) {
      MoveArray opp_move_array;
      movegen_->GenerateMoves(&opp_move_array);
      if (opp_move_array.size() == 0) {
        score = WIN;
      }
    }
    board_->UnmakeLastMove();
  }
  if (score == WIN) {
    return score;
  }

  U64 self_pawns = board_->BitBoard(PieceOfSide(PAWN, side));
  int self_pawns_strength = 0;
  while (self_pawns) {
    const int lsb_index = Lsb1(self_pawns);
    self_pawns_strength += sq_strength[lsb_index];
    self_pawns ^= (1ULL << lsb_index);
  }

  U64 opp_pawns = board_->BitBoard(PieceOfSide(PAWN, OppositeSide(side)));
  int opp_pawns_strength = 0;
  while (opp_pawns) {
    const int lsb_index = Lsb1(opp_pawns);
    opp_pawns_strength += sq_strength[lsb_index];
    opp_pawns ^= (1ULL << lsb_index);
  }

  const int pawns_strength =
      (self_pawns_strength - opp_pawns_strength) *
      ((board_->Ply() <= 10) ? OPENING_PAWNS_STRENGTH_FACTOR
                             : MIDDLE_PAWNS_STRENGTH_FACTOR);

  if (board_->Ply() > 8) {
    const int main_row = ((side == Side::WHITE) ? 0 : 7);
    // Better to move the bishop.
    if ((board_->BitBoard(PieceOfSide(BISHOP, side)) &
         ((1ULL << INDX(main_row, 2)) | (1ULL << INDX(main_row, 5))))) {
      score -= 5;
    }

    // Better to move the knight.
    if ((board_->BitBoard(PieceOfSide(KNIGHT, side)) &
         ((1ULL << INDX(main_row, 1)) | (1ULL << INDX(main_row, 6))))) {
      score -= 5;
    }
  }

  return score + pawns_strength + (move_array.size() / 15);
}
Example #3
0
    //--------------------------------------------------------------
    //  The following function should return true if the Move
    //  was read successfully, or false to abort the game.
    //  The move does not have to be legal; if an illegal move
    //  is returned, the caller will repeatedly call until a
    //  legal move is obtained.
    //--------------------------------------------------------------
    virtual bool ReadMove ( 
        ChessBoard  &board, 
        int         &source, 
        int         &dest, 
        SQUARE      &promPieceIndex )   // set to 0 (P_INDEX) if no promotion, or call to PromotePawn is needed; set to N_INDEX..Q_INDEX to specify promotion.
    {
        promPieceIndex = P_INDEX;

        bool boardWasAlreadyPrinted = AutoPrintBoard;

        // accept either of the following two formats: e2e4, g7g8q
        while (true)
        {
            if (IsFirstPrompt)
            {
                IsFirstPrompt = false;
                TheTerminal.printline("Enter 'help' for info and more options.");
            }
            TheTerminal.print("Your move? ");
            std::string line = TheTerminal.readline();

            // =================================================================
            // REMEMBER:  Update "PrintHelp()" every time you add a command!
            // =================================================================

            if (line == "board")
            {
                ReallyDrawBoard(board);
                boardWasAlreadyPrinted = true;
            }
            else if (line == "help")
            {
                PrintHelp();
            }
            else if (line == "new")
            {                
                if (human)
                {
                    human->SetQuitReason(qgr_startNewGame);     // suppress saying that the player resigned
                }
                return false;   // Start a new game.
            }
            else if (line == "quit")
            {
                throw "Chess program exited.";
            }
            else if (line == "show")
            {
                AutoPrintBoard = true;
                if (!boardWasAlreadyPrinted)
                {
                    ReallyDrawBoard(board);
                    boardWasAlreadyPrinted = true;
                }
            }
            else if (line == "swap")
            {
                if (game)
                {
                    humanSide = OppositeSide(humanSide);
                    if (humanSide == SIDE_WHITE)
                    {
                        game->SetPlayers(human, computer);
                    }
                    else
                    {
                        game->SetPlayers(computer, human);
                    }
                    TheTerminal.print("You are now playing as ");
                    TheTerminal.print(SideName(humanSide));
                    TheTerminal.printline(".");

                    source = 0;
                    dest = SPECIAL_MOVE_NULL;
                    return true;
                }
            }
            else if (line == "time")
            {
                // Adjust computer's think time.
                TheTerminal.print("The computer's max think time is now ");
                TheTerminal.printChessTime(ComputerThinkTime);
                TheTerminal.printline(".");
                TheTerminal.print("Enter new think time (0.1 .. 600): ");
                std::string line = TheTerminal.readline();
                double thinkTime = atof(line.c_str());
                if ((thinkTime >= 0.1) && (thinkTime < 600.0))
                {
                    ComputerThinkTime = static_cast<int>(100.0*thinkTime + 0.5);    // round seconds to integer centiseconds
                    if (computer)
                    {
                        computer->SetTimeLimit(ComputerThinkTime);
                    }
                }
                else
                {
                    TheTerminal.printline("Invalid think time - ignoring.");
                }
            }
            else
            {
                if (ParseFancyMove(line.c_str(), board, source, dest, promPieceIndex))
                {
                    return true;
                }
            }
        }
    }