mirror of
https://github.com/sockspls/badfish
synced 2025-07-11 19:49:14 +00:00
Split killer moves from non-captures
In MovePicker consider killer moves as a separate phase from non-capture picking. Note that this change guarantees that killer1 is always tried before killer2. Until now, because scoring difference of the two moves was just 1 point, if psqt tables of killer1 gave a lower value then killer2, the latter was tried as first. After 999 games at 1+0 we have Mod vs Orig: +245 =527 -227 +6 ELO Not a lot but patch is anyhow something worth to have. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
1b0888708d
commit
bdb1bfecfb
3 changed files with 29 additions and 22 deletions
|
@ -392,7 +392,6 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) {
|
|||
assert(pinned == pos.pinned_pieces(pos.side_to_move()));
|
||||
|
||||
Color us = pos.side_to_move();
|
||||
Color them = opposite_color(us);
|
||||
Square from = move_from(m);
|
||||
Piece pc = pos.piece_on(from);
|
||||
|
||||
|
@ -401,6 +400,7 @@ bool move_is_legal(const Position& pos, const Move m, Bitboard pinned) {
|
|||
if (color_of_piece(pc) != us)
|
||||
return false;
|
||||
|
||||
Color them = opposite_color(us);
|
||||
Square to = move_to(m);
|
||||
|
||||
// En passant moves
|
||||
|
|
|
@ -74,6 +74,7 @@ MovePicker::MovePicker(const Position& p, bool pv, Move ttm,
|
|||
movesPicked = 0;
|
||||
numOfMoves = 0;
|
||||
numOfBadCaptures = 0;
|
||||
checkKillers = checkLegal = false;
|
||||
|
||||
if (p.is_check())
|
||||
phaseIndex = EvasionsPhaseIndex;
|
||||
|
@ -139,6 +140,25 @@ Move MovePicker::get_next_move() {
|
|||
score_captures();
|
||||
std::sort(moves, moves + numOfMoves);
|
||||
movesPicked = 0;
|
||||
checkLegal = true;
|
||||
break;
|
||||
|
||||
case PH_KILLERS:
|
||||
movesPicked = numOfMoves = 0;
|
||||
checkLegal = false;
|
||||
if (killer1 != MOVE_NONE && move_is_legal(pos, killer1, pinned) && !pos.move_is_capture(killer1))
|
||||
moves[numOfMoves++].move = killer1;
|
||||
if (killer2 != MOVE_NONE && move_is_legal(pos, killer2, pinned) && !pos.move_is_capture(killer2) )
|
||||
moves[numOfMoves++].move = killer2;
|
||||
break;
|
||||
|
||||
case PH_NONCAPTURES:
|
||||
checkKillers = (numOfMoves != 0); // previous phase is PH_KILLERS
|
||||
numOfMoves = generate_noncaptures(pos, moves);
|
||||
score_noncaptures();
|
||||
std::sort(moves, moves + numOfMoves);
|
||||
movesPicked = 0;
|
||||
checkLegal = true;
|
||||
break;
|
||||
|
||||
case PH_BAD_CAPTURES:
|
||||
|
@ -146,13 +166,6 @@ Move MovePicker::get_next_move() {
|
|||
movesPicked = 0;
|
||||
break;
|
||||
|
||||
case PH_NONCAPTURES:
|
||||
numOfMoves = generate_noncaptures(pos, moves);
|
||||
score_noncaptures();
|
||||
std::sort(moves, moves + numOfMoves);
|
||||
movesPicked = 0;
|
||||
break;
|
||||
|
||||
case PH_EVASIONS:
|
||||
assert(pos.is_check());
|
||||
numOfMoves = generate_evasions(pos, moves, pinned);
|
||||
|
@ -258,13 +271,7 @@ void MovePicker::score_noncaptures() {
|
|||
for (int i = 0; i < numOfMoves; i++)
|
||||
{
|
||||
m = moves[i].move;
|
||||
|
||||
if (m == killer1)
|
||||
hs = HistoryMax + 2;
|
||||
else if (m == killer2)
|
||||
hs = HistoryMax + 1;
|
||||
else
|
||||
hs = H.move_ordering_score(pos.piece_on(move_from(m)), move_to(m));
|
||||
hs = H.move_ordering_score(pos.piece_on(move_from(m)), move_to(m));
|
||||
|
||||
// Ensure history is always preferred to pst
|
||||
if (hs > 0)
|
||||
|
@ -320,13 +327,15 @@ Move MovePicker::pick_move_from_list() {
|
|||
switch (PhaseTable[phaseIndex]) {
|
||||
|
||||
case PH_GOOD_CAPTURES:
|
||||
case PH_KILLERS:
|
||||
case PH_NONCAPTURES:
|
||||
while (movesPicked < numOfMoves)
|
||||
{
|
||||
Move move = moves[movesPicked++].move;
|
||||
if ( move != ttMove
|
||||
&& move != mateKiller
|
||||
&& pos.pl_move_is_legal(move, pinned))
|
||||
&& (!checkKillers || (move != killer1 && move != killer2))
|
||||
&& (!checkLegal || pos.pl_move_is_legal(move, pinned)))
|
||||
return move;
|
||||
}
|
||||
break;
|
||||
|
@ -381,9 +390,7 @@ void MovePicker::init_phase_table() {
|
|||
PhaseTable[i++] = PH_TT_MOVE;
|
||||
PhaseTable[i++] = PH_MATE_KILLER;
|
||||
PhaseTable[i++] = PH_GOOD_CAPTURES;
|
||||
// PH_KILLER_1 and PH_KILLER_2 are not yet used.
|
||||
// PhaseTable[i++] = PH_KILLER_1;
|
||||
// PhaseTable[i++] = PH_KILLER_2;
|
||||
PhaseTable[i++] = PH_KILLERS;
|
||||
PhaseTable[i++] = PH_NONCAPTURES;
|
||||
PhaseTable[i++] = PH_BAD_CAPTURES;
|
||||
PhaseTable[i++] = PH_STOP;
|
||||
|
|
|
@ -57,10 +57,9 @@ public:
|
|||
PH_TT_MOVE, // Transposition table move
|
||||
PH_MATE_KILLER, // Mate killer from the current ply
|
||||
PH_GOOD_CAPTURES, // Queen promotions and captures with SEE values >= 0
|
||||
PH_BAD_CAPTURES, // Queen promotions and captures with SEE values < 0
|
||||
PH_KILLER_1, // Killer move 1 from the current ply (not used yet).
|
||||
PH_KILLER_2, // Killer move 2 from the current ply (not used yet).
|
||||
PH_KILLERS, // Killer moves from the current ply
|
||||
PH_NONCAPTURES, // Non-captures and underpromotions
|
||||
PH_BAD_CAPTURES, // Queen promotions and captures with SEE values < 0
|
||||
PH_EVASIONS, // Check evasions
|
||||
PH_QCAPTURES, // Captures in quiescence search
|
||||
PH_QCHECKS, // Non-capture checks in quiescence search
|
||||
|
@ -91,6 +90,7 @@ private:
|
|||
int phaseIndex;
|
||||
int numOfMoves, numOfBadCaptures;
|
||||
int movesPicked;
|
||||
bool checkKillers, checkLegal;
|
||||
bool finished;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue