Improve generalization to non-standard board sizes
authorFabian Fichter <ianfab@users.noreply.github.com>
Thu, 3 Jan 2019 21:45:50 +0000 (22:45 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Thu, 3 Jan 2019 21:45:50 +0000 (22:45 +0100)
Remove assumptions about 8x8 board size from evaluation code.

losalamos
LLR: 3.02 (-2.94,2.94) [-10.00,5.00]
Total: 152 W: 83 L: 30 D: 39

capablanca
LLR: 3.00 (-2.94,2.94) [-10.00,5.00]
Total: 362 W: 180 L: 123 D: 59

minishogi
LLR: 2.95 (-2.94,2.94) [-10.00,5.00]
Total: 288 W: 163 L: 102 D: 23

src/evaluate.cpp
src/pawns.cpp

index e544705..a1d5839 100644 (file)
@@ -286,12 +286,14 @@ namespace {
         if (relative_rank(Us, pos.square<KING>(Us), pos.max_rank()) == RANK_1)
             kingRing[Us] |= shift<Up>(kingRing[Us]);
 
-        if (file_of(pos.square<KING>(Us)) == FILE_H)
+        if (file_of(pos.square<KING>(Us)) == pos.max_file())
             kingRing[Us] |= shift<WEST>(kingRing[Us]);
 
         else if (file_of(pos.square<KING>(Us)) == FILE_A)
             kingRing[Us] |= shift<EAST>(kingRing[Us]);
 
+        kingRing[Us] &= pos.board_bb();
+
         kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
         kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
     }
@@ -474,8 +476,8 @@ namespace {
   Score Evaluation<T>::king() const {
 
     constexpr Color    Them = (Us == WHITE ? BLACK : WHITE);
-    constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
-                                           : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
+    Rank r = relative_rank(Us, std::min(Rank((pos.max_rank() - 1) / 2 + 1), pos.max_rank()), pos.max_rank());
+    Bitboard Camp = AllSquares ^ forward_ranks_bb(Us, r);
 
     if (!pos.count<KING>(Us) || !pos.checking_permitted())
         return SCORE_ZERO;
@@ -567,7 +569,8 @@ namespace {
         }
     }
 
-    Bitboard kf = KingFlank[file_of(ksq)];
+    File f = std::max(std::min(file_of(ksq), File(pos.max_file() - 1)), FILE_B);
+    Bitboard kf = pos.max_file() == FILE_H ? KingFlank[f] : file_bb(f) | adjacent_files_bb(f);
 
     // Penalty when our king is on a pawnless flank
     if (!(pos.pieces(PAWN) & kf))
@@ -576,7 +579,7 @@ namespace {
     // Find the squares that opponent attacks in our king flank, and the squares
     // which are attacked twice in that flank but not defended by our pawns.
     b1 = attackedBy[Them][ALL_PIECES] & kf & Camp;
-    b2 = b1 & attackedBy2[Them] & ~attackedBy[Us][PAWN];
+    b2 = b1 & attackedBy2[Them] & ~(attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN]);
 
     // King tropism, to anticipate slow motion attacks on our king
     score -= CloseEnemies * (popcount(b1) + popcount(b2)) * (1 + pos.captures_to_hand() + !!pos.max_check_count());
index 04b727b..1aa4829 100644 (file)
@@ -244,7 +244,7 @@ Value Entry::evaluate_shelter(const Position& pos, Square ksq) {
   if (shift<Down>(theirPawns) & (FileABB | FileHBB) & BlockRanks & ksq)
       safety += Value(374);
 
-  File center = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));
+  File center = std::max(FILE_B, std::min(File(pos.max_file() - 1), file_of(ksq)));
   for (File f = File(center - 1); f <= File(center + 1); ++f)
   {
       b = ourPawns & file_bb(f);
@@ -253,7 +253,7 @@ Value Entry::evaluate_shelter(const Position& pos, Square ksq) {
       b = theirPawns & file_bb(f);
       int theirRank = b ? relative_rank(Us, frontmost_sq(Them, b), pos.max_rank()) : 0;
 
-      int d = std::min(f, ~f);
+      int d = std::min(std::min(f, File(pos.max_file() - f)), FILE_D);
       // higher weight for pawns on second rank and missing shelter in drop variants
       safety += ShelterStrength[d][ourRank] * (1 + (pos.captures_to_hand() && ourRank <= RANK_2));
       safety -= (ourRank && (ourRank == theirRank - 1)) ? BlockedStorm[theirRank]
@@ -282,10 +282,16 @@ Score Entry::do_king_safety(const Position& pos, Square ksq) {
 
   // If we can castle use the bonus after the castling if it is bigger
   if (pos.can_castle(MakeCastling<Us, KING_SIDE>::right))
-      bonus = std::max(bonus, evaluate_shelter<Us>(pos, relative_square(Us, SQ_G1)));
+  {
+      Square s = make_square(pos.castling_kingside_file(), Us == WHITE ? RANK_1 : pos.max_rank());
+      bonus = std::max(bonus, evaluate_shelter<Us>(pos, s));
+  }
 
   if (pos.can_castle(MakeCastling<Us, QUEEN_SIDE>::right))
-      bonus = std::max(bonus, evaluate_shelter<Us>(pos, relative_square(Us, SQ_C1)));
+  {
+      Square s = make_square(pos.castling_queenside_file(), Us == WHITE ? RANK_1 : pos.max_rank());
+      bonus = std::max(bonus, evaluate_shelter<Us>(pos, s));
+  }
 
   return make_score(bonus, -16 * minKingPawnDistance);
 }