Support pieces in hand for NNUE
authorFabian Fichter <ianfab@users.noreply.github.com>
Sat, 28 Aug 2021 08:42:16 +0000 (10:42 +0200)
committerFabian Fichter <ianfab@users.noreply.github.com>
Sat, 28 Aug 2021 11:10:32 +0000 (13:10 +0200)
This enables to consider pieces in hand in NNUE evaluation.

src/nnue/features/half_ka_v2_variants.cpp
src/nnue/features/half_ka_v2_variants.h
src/variant.h

index d351209..9e7a990 100644 (file)
@@ -40,6 +40,11 @@ namespace Stockfish::Eval::NNUE::Features {
     return IndexType(orient(perspective, s, pos) + pos.variant()->pieceSquareIndex[perspective][pc] + ksq * pos.variant()->nnuePieceIndices);
   }
 
+  // Index of a feature for a given king position and another piece on some square
+  inline IndexType HalfKAv2Variants::make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos) {
+    return IndexType(handCount + pos.variant()->pieceHandIndex[perspective][pc] + ksq * pos.variant()->nnuePieceIndices);
+  }
+
   // Get a list of indices for active features
   void HalfKAv2Variants::append_active_indices(
     const Position& pos,
@@ -53,6 +58,14 @@ namespace Stockfish::Eval::NNUE::Features {
       Square s = pop_lsb(bb);
       active.push_back(make_index(perspective, s, pos.piece_on(s), oriented_ksq, pos));
     }
+
+    // Indices for pieces in hand
+    if (pos.piece_drops() || pos.seirawan_gating())
+      for (Color c : {WHITE, BLACK})
+          for (PieceType pt : pos.piece_types())
+              for (int i = 0; i < pos.count_in_hand(c, pt); i++)
+                  active.push_back(make_index(perspective, i, make_piece(c, pt), oriented_ksq, pos));
+
   }
 
   // append_changed_indices() : get a list of indices for recently changed features
@@ -71,8 +84,12 @@ namespace Stockfish::Eval::NNUE::Features {
       Piece pc = dp.piece[i];
       if (dp.from[i] != SQ_NONE)
         removed.push_back(make_index(perspective, dp.from[i], pc, oriented_ksq, pos));
+      else if (pos.piece_drops() && dp.dirty_num == 1)
+        removed.push_back(make_index(perspective, dp.handCount[i], dp.handPiece[i], oriented_ksq, pos));
       if (dp.to[i] != SQ_NONE)
         added.push_back(make_index(perspective, dp.to[i], pc, oriented_ksq, pos));
+      else if (pos.captures_to_hand() && i == 1)
+        added.push_back(make_index(perspective, dp.handCount[i] - 1, dp.handPiece[i], oriented_ksq, pos));
     }
   }
 
index b46a004..e55ebcb 100644 (file)
@@ -44,6 +44,9 @@ namespace Stockfish::Eval::NNUE::Features {
     // Index of a feature for a given king position and another piece on some square
     static IndexType make_index(Color perspective, Square s, Piece pc, Square ksq, const Position& pos);
 
+    // Index of a feature for a given king position and another piece in hand
+    static IndexType make_index(Color perspective, int handCount, Piece pc, Square ksq, const Position& pos);
+
    public:
     // Feature name
     static constexpr const char* Name = "HalfKAv2(Friend)";
index a11e6c1..fa1ce9d 100644 (file)
@@ -140,6 +140,7 @@ struct Variant {
   int nnueSquares;
   int nnuePieceIndices;
   int pieceSquareIndex[COLOR_NB][PIECE_NB];
+  int pieceHandIndex[COLOR_NB][PIECE_NB];
   int nnueMaxPieces;
   bool endgameEval = false;
 
@@ -199,7 +200,9 @@ struct Variant {
                 : extinctionPieceTypes.find(COMMONER) != extinctionPieceTypes.end() ? COMMONER
                 : NO_PIECE_TYPE;
       nnueSquares = (maxRank + 1) * (maxFile + 1);
-      nnuePieceIndices = (2 * pieceTypes.size() - 1) * nnueSquares;
+      int nnuePockets = pieceDrops ? 2 * int(maxFile + 1) : 0;
+      int nnueNonDropPieceIndices = (2 * pieceTypes.size() - 1) * nnueSquares;
+      nnuePieceIndices = nnueNonDropPieceIndices + 2 * (pieceTypes.size() - 1) * nnuePockets;
       int i = 0;
       for (PieceType pt : pieceTypes)
       {
@@ -207,6 +210,8 @@ struct Variant {
           {
               pieceSquareIndex[c][make_piece(c, pt)] = 2 * i * nnueSquares;
               pieceSquareIndex[c][make_piece(~c, pt)] = (2 * i + (pt != nnueKing)) * nnueSquares;
+              pieceHandIndex[c][make_piece(c, pt)] = 2 * i * nnuePockets + nnueNonDropPieceIndices;
+              pieceHandIndex[c][make_piece(~c, pt)] = (2 * i + 1) * nnuePockets + nnueNonDropPieceIndices;
           }
           i++;
       }