Evaluate mobility of pieces in hand
authorFabian Fichter <ianfab@users.noreply.github.com>
Wed, 26 Dec 2018 12:58:29 +0000 (13:58 +0100)
committerFabian Fichter <ianfab@users.noreply.github.com>
Wed, 26 Dec 2018 12:58:29 +0000 (13:58 +0100)
shogi
LLR: 2.96 (-2.94,2.94) [0.00,10.00]
Total: 740 W: 416 L: 305 D: 19

minishogi
LLR: 2.99 (-2.94,2.94) [0.00,10.00]
Total: 660 W: 363 L: 256 D: 41

crazyhouse STC
LLR: -2.96 (-2.94,2.94) [-10.00,5.00]
Total: 8643 W: 4154 L: 4283 D: 206
http://35.161.250.236:6543/tests/view/5c16665f6e23db24728955a2

crazyhouse LTC
LLR: -2.97 (-2.94,2.94) [-10.00,5.00]
Total: 5977 W: 2855 L: 2965 D: 157
http://35.161.250.236:6543/tests/view/5c16d1616e23db24728955ac

src/evaluate.cpp
src/movegen.cpp
src/position.h

index 4d5f390..7b431fa 100644 (file)
@@ -120,6 +120,8 @@ namespace {
       S( 79,140), S( 88,143), S( 88,148), S( 99,166), S(102,170), S(102,175),
       S(106,184), S(109,191), S(113,206), S(116,212) }
   };
+  constexpr Score MaxMobility  = S(300, 300);
+  constexpr Score DropMobility = S(10, 10);
 
   // Outpost[knight/bishop][supported by pawn] contains bonuses for minor
   // pieces if they occupy or can reach an outpost square, bigger if that
@@ -201,6 +203,7 @@ namespace {
   private:
     template<Color Us> void initialize();
     template<Color Us> Score pieces(PieceType Pt);
+    template<Color Us> Score hand(PieceType pt);
     template<Color Us> Score king() const;
     template<Color Us> Score threats() const;
     template<Color Us> Score passed() const;
@@ -343,7 +346,7 @@ namespace {
         if (Pt <= QUEEN)
             mobility[Us] += MobilityBonus[Pt - 2][mob];
         else
-            mobility[Us] += make_score(300, 300) * (mob - 1) / (10 + mob);
+            mobility[Us] += MaxMobility * (mob - 1) / (10 + mob);
 
         // Piece promotion bonus
         if (pos.promoted_piece_type(Pt) != NO_PIECE_TYPE)
@@ -439,6 +442,22 @@ namespace {
     return score;
   }
 
+  // Evaluation::hand() scores pieces of a given color and type in hand
+  template<Tracing T> template<Color Us>
+  Score Evaluation<T>::hand(PieceType pt) {
+
+    constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
+
+    Score score = SCORE_ZERO;
+
+    if (pos.piece_drops() && pos.count_in_hand(Us, pt))
+    {
+        Bitboard theirHalf = pos.board_bb() & ~forward_ranks_bb(Them, relative_rank(Them, Rank((pos.max_rank() - 1) / 2), pos.max_rank()));
+        mobility[Us] += DropMobility * popcount(theirHalf & ~(pos.pieces() | attackedBy[Them][ALL_PIECES]) & pos.drop_region(Us, pt));
+    }
+
+    return score;
+  }
 
   // Evaluation::king() assigns bonuses and penalties to a king of a given color
   template<Tracing T> template<Color Us>
@@ -1026,6 +1045,11 @@ namespace {
     for (PieceType pt = KNIGHT; pt < KING; ++pt)
         score += pieces<WHITE>(pt) - pieces<BLACK>(pt);
 
+    // Evaluate pieces in hand once attack tables are complete
+    if (pos.piece_drops())
+        for (PieceType pt = KNIGHT; pt < KING; ++pt)
+            score += hand<WHITE>(pt) - hand<BLACK>(pt);
+
     score += (mobility[WHITE] - mobility[BLACK]) * (1 + pos.captures_to_hand() + pos.must_capture());
 
     score +=  king<   WHITE>() - king<   BLACK>()
index 98fc09d..19834bd 100644 (file)
@@ -82,21 +82,8 @@ namespace {
   ExtMove* generate_drops(const Position& pos, ExtMove* moveList, PieceType pt, Bitboard b) {
     if (pos.count_in_hand(Us, pt))
     {
-        // Consider only drops on top of already placed pieces
-        if (pos.drop_on_top())
-            b &= shift<NORTH>(pos.pieces()) | Rank1BB;
-        if (pt == PAWN)
-        {
-            b &= ~promotion_zone_bb(Us, pos.promotion_rank(), pos.max_rank());
-            if (!pos.first_rank_drops())
-                b &= ~rank_bb(relative_rank(Us, RANK_1, pos.max_rank()));
-        }
-        if (pt == SHOGI_PAWN && !pos.shogi_doubled_pawn())
-            for (File f = FILE_A; f <= pos.max_file(); ++f)
-                if (file_bb(f) & pos.pieces(Us, pt))
-                    b &= ~file_bb(f);
-        if (pt == ROOK && pos.sittuyin_rook_drop())
-            b &= rank_bb(relative_rank(Us, RANK_1, pos.max_rank()));
+        // Restrict to valid target
+        b &= pos.drop_region(Us, pt);
 
         // Add to move list
         if (pos.drop_promoted() && pos.promoted_piece_type(pt))
@@ -349,7 +336,7 @@ namespace {
     // generate drops
     if (pos.piece_drops() && Type != CAPTURES && pos.count_in_hand(Us, ALL_PIECES))
         for (PieceType pt = PAWN; pt <= KING; ++pt)
-            moveList = generate_drops<Us, Checks>(pos, moveList, pt, target & ~pos.pieces(~Us) & pos.drop_region(Us));
+            moveList = generate_drops<Us, Checks>(pos, moveList, pt, target & ~pos.pieces(~Us));
 
     if (Type != QUIET_CHECKS && Type != EVASIONS && pos.count<KING>(Us))
     {
index c9163fb..c351f86 100644 (file)
@@ -117,6 +117,7 @@ public:
   bool first_rank_drops() const;
   bool drop_on_top() const;
   Bitboard drop_region(Color c) const;
+  Bitboard drop_region(Color c, PieceType pt) const;
   bool sittuyin_rook_drop() const;
   bool drop_opposite_colored_bishop() const;
   bool drop_promoted() const;
@@ -410,6 +411,31 @@ inline Bitboard Position::drop_region(Color c) const {
   return c == WHITE ? var->whiteDropRegion : var->blackDropRegion;
 }
 
+inline Bitboard Position::drop_region(Color c, PieceType pt) const {
+  Bitboard b = drop_region(c) & board_bb();
+
+  // Connect4-style drops
+  if (drop_on_top())
+      b &= shift<NORTH>(pieces()) | Rank1BB;
+  // Pawns on back ranks
+  if (pt == PAWN)
+  {
+      b &= ~promotion_zone_bb(c, promotion_rank(), max_rank());
+      if (!first_rank_drops())
+          b &= ~rank_bb(relative_rank(c, RANK_1, max_rank()));
+  }
+  // Doubled shogi pawns
+  if (pt == SHOGI_PAWN && !shogi_doubled_pawn())
+      for (File f = FILE_A; f <= max_file(); ++f)
+          if (file_bb(f) & pieces(c, pt))
+              b &= ~file_bb(f);
+  // Sittuyin rook drops
+  if (pt == ROOK && sittuyin_rook_drop())
+      b &= rank_bb(relative_rank(c, RANK_1, max_rank()));
+
+  return b;
+}
+
 inline bool Position::sittuyin_rook_drop() const {
   assert(var != nullptr);
   return var->sittuyinRookDrop;