From 27904632b9361ef625b389d85505e765d80af138 Mon Sep 17 00:00:00 2001 From: Fabian Fichter Date: Fri, 8 Feb 2019 00:24:50 +0100 Subject: [PATCH] Rewrite evaluation of shogi pawns Handle shogi pawns similar to pawns, different from other pieces. Speeds up evaluation and allows improving evaluation of passed shogi pawns. shogi LLR: 2.98 (-2.94,2.94) [-10.00,5.00] Total: 596 W: 322 L: 259 D: 15 euroshogi LLR: 3.01 (-2.94,2.94) [-10.00,5.00] Total: 530 W: 285 L: 222 D: 23 minishogi LLR: -0.12 (-2.94,2.94) [-10.00,5.00] Total: 1000 W: 493 L: 503 D: 4 No functional change for non-shogi variants. --- src/evaluate.cpp | 35 +++++++++++++++++++++++++++++------ 1 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 7a7320e..f61f9af 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -277,10 +277,13 @@ namespace { mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them) | shift(pos.pieces(Them, SHOGI_PAWN))); // Initialise attackedBy bitboards for kings and pawns - attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, pos.square(Us)) : 0; - attackedBy[Us][PAWN] = pe->pawn_attacks(Us); - attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN]; - attackedBy2[Us] = attackedBy[Us][KING] & attackedBy[Us][PAWN]; + attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, pos.square(Us)) : 0; + attackedBy[Us][PAWN] = pe->pawn_attacks(Us); + attackedBy[Us][SHOGI_PAWN] = shift(pos.pieces(Us, SHOGI_PAWN)); + attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN]; + attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN]) + | (attackedBy[Us][KING] & attackedBy[Us][SHOGI_PAWN]) + | (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN]); // Init our king safety tables only if we are going to use them if ((pos.count(Us) && pos.non_pawn_material(Them) >= RookValueMg + KnightValueMg) || pos.captures_to_hand()) @@ -297,7 +300,7 @@ namespace { kingRing[Us] &= pos.board_bb(); - kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them)); + kingAttackersCount[Them] = popcount(kingRing[Us] & (pe->pawn_attacks(Them) | shift(pos.pieces(Them, SHOGI_PAWN)))); kingAttacksCount[Them] = kingAttackersWeight[Them] = 0; } else @@ -830,6 +833,25 @@ namespace { score = make_score(mg_value(score) * int(maxMg) / QueenValueMg, eg_value(score) * int(maxEg) / QueenValueEg); + // Score passed shogi pawns + const Square* pl = pos.squares(Us, SHOGI_PAWN); + Square s; + + PieceType pt = pos.promoted_piece_type(SHOGI_PAWN); + if (pt != NO_PIECE_TYPE) + { + while ((s = *pl++) != SQ_NONE) + { + if ((pos.pieces(Them, SHOGI_PAWN) & forward_file_bb(Us, s)) || relative_rank(Us, s, pos.max_rank()) == pos.max_rank()) + continue; + + Square blockSq = s + Up; + int d = std::max(pos.promotion_rank() - relative_rank(Us, s, pos.max_rank()), 1); + d += !!(pos.pieces(Us) & blockSq) + !!(attackedBy[Them][ALL_PIECES] & ~attackedBy2[Us] & blockSq); + score += make_score(PieceValue[MG][pt], PieceValue[EG][pt]) / (4 * d * d); + } + } + if (T) Trace::add(PASSED, Us, score); @@ -1050,7 +1072,8 @@ namespace { // Pieces should be evaluated first (populate attack tables). // For unused piece types, we still need to set attack bitboard to zero. for (PieceType pt = KNIGHT; pt < KING; ++pt) - score += pieces(pt) - pieces(pt); + if (pt != SHOGI_PAWN) + score += pieces(pt) - pieces(pt); // Evaluate pieces in hand once attack tables are complete if (pos.piece_drops()) -- 1.7.0.4