From a518bf7b29ed902e27d7705ef462c05890676d2b Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Wed, 26 Dec 2018 13:58:29 +0100 Subject: [PATCH] Evaluate mobility of pieces in hand 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 | 26 +++++++++++++++++++++++++- src/movegen.cpp | 19 +++---------------- src/position.h | 26 ++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 4d5f390..7b431fa 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -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 void initialize(); template Score pieces(PieceType Pt); + template Score hand(PieceType pt); template Score king() const; template Score threats() const; template 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 template + Score Evaluation::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 template @@ -1026,6 +1045,11 @@ namespace { for (PieceType pt = KNIGHT; pt < KING; ++pt) score += pieces(pt) - pieces(pt); + // Evaluate pieces in hand once attack tables are complete + if (pos.piece_drops()) + for (PieceType pt = KNIGHT; pt < KING; ++pt) + score += hand(pt) - hand(pt); + score += (mobility[WHITE] - mobility[BLACK]) * (1 + pos.captures_to_hand() + pos.must_capture()); score += king< WHITE>() - king< BLACK>() diff --git a/src/movegen.cpp b/src/movegen.cpp index 98fc09d..19834bd 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -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(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(pos, moveList, pt, target & ~pos.pieces(~Us) & pos.drop_region(Us)); + moveList = generate_drops(pos, moveList, pt, target & ~pos.pieces(~Us)); if (Type != QUIET_CHECKS && Type != EVASIONS && pos.count(Us)) { diff --git a/src/position.h b/src/position.h index c9163fb..c351f86 100644 --- a/src/position.h +++ b/src/position.h @@ -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(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; -- 1.7.0.4