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; }
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); }
//-------------------------------------------------------------- // 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; } } } }