|
1 | 1 | #include "eval.h" |
2 | 2 |
|
3 | | -std::map<unsigned long long, int> transposition; |
4 | | -int eval(chess::Board board){ |
5 | | - if (transposition.count(board.hash())) return transposition[board.hash()]; |
6 | | - U64 hash=board.hash(); |
7 | | - //Game over |
8 | | - if (board.inCheck()&&board.isGameOver().first!=chess::GameResultReason::NONE)return MAX; |
9 | | - else if (board.isGameOver().first!=chess::GameResultReason::NONE)return 0; |
10 | | - int eval=0; |
11 | | - //Material |
12 | | - eval+=Pawn*board.pieces(chess::PieceType::underlying::PAWN,chess::Color::underlying::WHITE).count(); |
13 | | - eval+=Knight*board.pieces(chess::PieceType::underlying::KNIGHT,chess::Color::underlying::WHITE).count(); |
14 | | - eval+=Bishop*board.pieces(chess::PieceType::underlying::BISHOP,chess::Color::underlying::WHITE).count(); |
15 | | - eval+=Rook*board.pieces(chess::PieceType::underlying::ROOK,chess::Color::underlying::WHITE).count(); |
16 | | - eval+=Queen*board.pieces(chess::PieceType::underlying::QUEEN,chess::Color::underlying::WHITE).count(); |
17 | | - eval-=Pawn*board.pieces(chess::PieceType::underlying::PAWN,chess::Color::underlying::BLACK).count(); |
18 | | - eval-=Knight*board.pieces(chess::PieceType::underlying::KNIGHT,chess::Color::underlying::BLACK).count(); |
19 | | - eval-=Bishop*board.pieces(chess::PieceType::underlying::BISHOP,chess::Color::underlying::BLACK).count(); |
20 | | - eval-=Rook*board.pieces(chess::PieceType::underlying::ROOK,chess::Color::underlying::BLACK).count(); |
21 | | - eval-=Queen*board.pieces(chess::PieceType::underlying::QUEEN,chess::Color::underlying::BLACK).count(); |
22 | | - //Pawns |
23 | | - eval -= isolated(board); |
24 | | - eval -= dblisolated(board); |
25 | | - eval -= weaks(board); |
26 | | - eval -= blockage(board); |
27 | | - eval += pawnIslands(board); |
28 | | - eval -= holes(board); |
29 | | - eval += pawnRace(board); |
30 | | - eval -= underpromote(board); |
31 | | - eval -= weakness(board); |
32 | | - eval += pawnShield(board); |
33 | | - eval += pawnStorm(board); |
34 | | - eval += pawnLevers(board); |
35 | | - eval += outpost(board); |
36 | | - eval -= evaluatePawnRams(board); |
37 | | - eval += evaluateUnfreePawns(board); |
38 | | - eval += evaluateOpenPawns(board); |
39 | | - eval -= evaluateBadBishops(board); |
40 | | - eval += evaluateFianchetto(board); |
41 | | - eval -= evaluateTrappedPieces(board); |
42 | | - eval -= evaluateKnightForks(board); |
43 | | - eval += evaluateRooksOnFiles(board); |
| 3 | +std::unordered_map<U64, int> transposition; // Faster lookup |
| 4 | + |
| 5 | +// Declare only missing functions |
| 6 | +int evaluatePawnStructure(const chess::Board& board); |
| 7 | +int evaluatePieces(const chess::Board& board); |
| 8 | + |
| 9 | +int eval(const chess::Board& board) { |
| 10 | + U64 hash = board.hash(); |
| 11 | + |
| 12 | + // Faster lookup & insertion |
| 13 | + auto [it, inserted] = transposition.emplace(hash, 0); |
| 14 | + if (!inserted) return it->second; // Already exists, return stored evaluation |
| 15 | + |
| 16 | + if (board.inCheck() && board.isGameOver().first != chess::GameResultReason::NONE) return MAX; |
| 17 | + if (board.isGameOver().first != chess::GameResultReason::NONE) return 0; |
| 18 | + |
| 19 | + // Precompute piece counts (avoid multiple function calls) |
| 20 | + int pieceCount[10] = { |
| 21 | + board.pieces(chess::PieceType::PAWN, chess::Color::WHITE).count(), |
| 22 | + board.pieces(chess::PieceType::KNIGHT, chess::Color::WHITE).count(), |
| 23 | + board.pieces(chess::PieceType::BISHOP, chess::Color::WHITE).count(), |
| 24 | + board.pieces(chess::PieceType::ROOK, chess::Color::WHITE).count(), |
| 25 | + board.pieces(chess::PieceType::QUEEN, chess::Color::WHITE).count(), |
| 26 | + board.pieces(chess::PieceType::PAWN, chess::Color::BLACK).count(), |
| 27 | + board.pieces(chess::PieceType::KNIGHT, chess::Color::BLACK).count(), |
| 28 | + board.pieces(chess::PieceType::BISHOP, chess::Color::BLACK).count(), |
| 29 | + board.pieces(chess::PieceType::ROOK, chess::Color::BLACK).count(), |
| 30 | + board.pieces(chess::PieceType::QUEEN, chess::Color::BLACK).count(), |
| 31 | + }; |
| 32 | + |
| 33 | + // Compute material score |
| 34 | + int eval = (Pawn * (pieceCount[0] - pieceCount[5])) + |
| 35 | + (Knight * (pieceCount[1] - pieceCount[6])) + |
| 36 | + (Bishop * (pieceCount[2] - pieceCount[7])) + |
| 37 | + (Rook * (pieceCount[3] - pieceCount[8])) + |
| 38 | + (Queen * (pieceCount[4] - pieceCount[9])); |
| 39 | + |
| 40 | + // Evaluate positional aspects |
| 41 | + eval += evaluatePawnStructure(board); |
| 42 | + eval += evaluatePieces(board); |
44 | 43 | eval += evaluateKingSafety(board); |
45 | | - eval += evaluateKingPawnTropism(board); |
46 | | - eval += evaluateKingMobility(board); |
47 | | - eval += evaluateSpaceControl(board); |
48 | | - eval -= evaluateTactics(board); |
49 | | - board.pop(); |
50 | | - eval -= -isolated(board); |
51 | | - eval -= -dblisolated(board); |
52 | | - eval -= -weaks(board); |
53 | | - eval -= -blockage(board); |
54 | | - eval += -pawnIslands(board); |
55 | | - eval -= -holes(board); |
56 | | - eval += -pawnRace(board); |
57 | | - eval -= -underpromote(board); |
58 | | - eval -= -weakness(board); |
59 | | - eval += -pawnShield(board); |
60 | | - eval += -pawnStorm(board); |
61 | | - eval += -pawnLevers(board); |
62 | | - eval += -outpost(board); |
63 | | - eval -= -evaluatePawnRams(board); |
64 | | - eval += -evaluateUnfreePawns(board); |
65 | | - eval += -evaluateOpenPawns(board); |
66 | | - eval -= -evaluateBadBishops(board); |
67 | | - eval += -evaluateFianchetto(board); |
68 | | - eval -= -evaluateTrappedPieces(board); |
69 | | - eval -= -evaluateKnightForks(board); |
70 | | - eval += -evaluateRooksOnFiles(board); |
71 | | - eval += -evaluateKingSafety(board); |
72 | | - eval += -evaluateKingPawnTropism(board); |
73 | | - eval += -evaluateKingMobility(board); |
74 | | - eval += -evaluateSpaceControl(board); |
75 | | - eval -= -evaluateTactics(board); |
76 | | - transposition[hash]=eval; |
77 | | - return eval; |
| 44 | + eval += evaluateTactics(board); |
| 45 | + |
| 46 | + it->second = eval; // Store result |
| 47 | + return eval; |
| 48 | +} |
| 49 | + |
| 50 | +// Use `const chess::Board&` to avoid copies |
| 51 | +int evaluatePawnStructure(const chess::Board& board) { |
| 52 | + chess::Board b=board; |
| 53 | + return -(isolated(board) + dblisolated(board) + weaks(board) + blockage(board) + |
| 54 | + holes(board) + underpromote(b) + weakness(board) + evaluatePawnRams(board)) + |
| 55 | + (pawnIslands(board) + pawnRace(board) + pawnShield(board) + pawnStorm(board) + |
| 56 | + pawnLevers(board) + outpost(board) + evaluateUnfreePawns(board) + evaluateOpenPawns(board)); |
| 57 | +} |
| 58 | + |
| 59 | +// Use `const chess::Board&` to avoid copies |
| 60 | +int evaluatePieces(const chess::Board& board) { |
| 61 | + return -(evaluateBadBishops(board) + evaluateTrappedPieces(board) + evaluateKnightForks(board)) + |
| 62 | + (evaluateFianchetto(board) + evaluateRooksOnFiles(board)); |
78 | 63 | } |
0 commit comments