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()));
|
assert(pinned == pos.pinned_pieces(pos.side_to_move()));
|
||||||
|
|
||||||
Color us = pos.side_to_move();
|
Color us = pos.side_to_move();
|
||||||
Color them = opposite_color(us);
|
|
||||||
Square from = move_from(m);
|
Square from = move_from(m);
|
||||||
Piece pc = pos.piece_on(from);
|
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)
|
if (color_of_piece(pc) != us)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Color them = opposite_color(us);
|
||||||
Square to = move_to(m);
|
Square to = move_to(m);
|
||||||
|
|
||||||
// En passant moves
|
// En passant moves
|
||||||
|
|
|
@ -74,6 +74,7 @@ MovePicker::MovePicker(const Position& p, bool pv, Move ttm,
|
||||||
movesPicked = 0;
|
movesPicked = 0;
|
||||||
numOfMoves = 0;
|
numOfMoves = 0;
|
||||||
numOfBadCaptures = 0;
|
numOfBadCaptures = 0;
|
||||||
|
checkKillers = checkLegal = false;
|
||||||
|
|
||||||
if (p.is_check())
|
if (p.is_check())
|
||||||
phaseIndex = EvasionsPhaseIndex;
|
phaseIndex = EvasionsPhaseIndex;
|
||||||
|
@ -139,6 +140,25 @@ Move MovePicker::get_next_move() {
|
||||||
score_captures();
|
score_captures();
|
||||||
std::sort(moves, moves + numOfMoves);
|
std::sort(moves, moves + numOfMoves);
|
||||||
movesPicked = 0;
|
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;
|
break;
|
||||||
|
|
||||||
case PH_BAD_CAPTURES:
|
case PH_BAD_CAPTURES:
|
||||||
|
@ -146,13 +166,6 @@ Move MovePicker::get_next_move() {
|
||||||
movesPicked = 0;
|
movesPicked = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PH_NONCAPTURES:
|
|
||||||
numOfMoves = generate_noncaptures(pos, moves);
|
|
||||||
score_noncaptures();
|
|
||||||
std::sort(moves, moves + numOfMoves);
|
|
||||||
movesPicked = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PH_EVASIONS:
|
case PH_EVASIONS:
|
||||||
assert(pos.is_check());
|
assert(pos.is_check());
|
||||||
numOfMoves = generate_evasions(pos, moves, pinned);
|
numOfMoves = generate_evasions(pos, moves, pinned);
|
||||||
|
@ -258,13 +271,7 @@ void MovePicker::score_noncaptures() {
|
||||||
for (int i = 0; i < numOfMoves; i++)
|
for (int i = 0; i < numOfMoves; i++)
|
||||||
{
|
{
|
||||||
m = moves[i].move;
|
m = moves[i].move;
|
||||||
|
hs = H.move_ordering_score(pos.piece_on(move_from(m)), move_to(m));
|
||||||
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));
|
|
||||||
|
|
||||||
// Ensure history is always preferred to pst
|
// Ensure history is always preferred to pst
|
||||||
if (hs > 0)
|
if (hs > 0)
|
||||||
|
@ -320,13 +327,15 @@ Move MovePicker::pick_move_from_list() {
|
||||||
switch (PhaseTable[phaseIndex]) {
|
switch (PhaseTable[phaseIndex]) {
|
||||||
|
|
||||||
case PH_GOOD_CAPTURES:
|
case PH_GOOD_CAPTURES:
|
||||||
|
case PH_KILLERS:
|
||||||
case PH_NONCAPTURES:
|
case PH_NONCAPTURES:
|
||||||
while (movesPicked < numOfMoves)
|
while (movesPicked < numOfMoves)
|
||||||
{
|
{
|
||||||
Move move = moves[movesPicked++].move;
|
Move move = moves[movesPicked++].move;
|
||||||
if ( move != ttMove
|
if ( move != ttMove
|
||||||
&& move != mateKiller
|
&& move != mateKiller
|
||||||
&& pos.pl_move_is_legal(move, pinned))
|
&& (!checkKillers || (move != killer1 && move != killer2))
|
||||||
|
&& (!checkLegal || pos.pl_move_is_legal(move, pinned)))
|
||||||
return move;
|
return move;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -381,9 +390,7 @@ void MovePicker::init_phase_table() {
|
||||||
PhaseTable[i++] = PH_TT_MOVE;
|
PhaseTable[i++] = PH_TT_MOVE;
|
||||||
PhaseTable[i++] = PH_MATE_KILLER;
|
PhaseTable[i++] = PH_MATE_KILLER;
|
||||||
PhaseTable[i++] = PH_GOOD_CAPTURES;
|
PhaseTable[i++] = PH_GOOD_CAPTURES;
|
||||||
// PH_KILLER_1 and PH_KILLER_2 are not yet used.
|
PhaseTable[i++] = PH_KILLERS;
|
||||||
// PhaseTable[i++] = PH_KILLER_1;
|
|
||||||
// PhaseTable[i++] = PH_KILLER_2;
|
|
||||||
PhaseTable[i++] = PH_NONCAPTURES;
|
PhaseTable[i++] = PH_NONCAPTURES;
|
||||||
PhaseTable[i++] = PH_BAD_CAPTURES;
|
PhaseTable[i++] = PH_BAD_CAPTURES;
|
||||||
PhaseTable[i++] = PH_STOP;
|
PhaseTable[i++] = PH_STOP;
|
||||||
|
|
|
@ -57,10 +57,9 @@ public:
|
||||||
PH_TT_MOVE, // Transposition table move
|
PH_TT_MOVE, // Transposition table move
|
||||||
PH_MATE_KILLER, // Mate killer from the current ply
|
PH_MATE_KILLER, // Mate killer from the current ply
|
||||||
PH_GOOD_CAPTURES, // Queen promotions and captures with SEE values >= 0
|
PH_GOOD_CAPTURES, // Queen promotions and captures with SEE values >= 0
|
||||||
PH_BAD_CAPTURES, // Queen promotions and captures with SEE values < 0
|
PH_KILLERS, // Killer moves from the current ply
|
||||||
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_NONCAPTURES, // Non-captures and underpromotions
|
PH_NONCAPTURES, // Non-captures and underpromotions
|
||||||
|
PH_BAD_CAPTURES, // Queen promotions and captures with SEE values < 0
|
||||||
PH_EVASIONS, // Check evasions
|
PH_EVASIONS, // Check evasions
|
||||||
PH_QCAPTURES, // Captures in quiescence search
|
PH_QCAPTURES, // Captures in quiescence search
|
||||||
PH_QCHECKS, // Non-capture checks in quiescence search
|
PH_QCHECKS, // Non-capture checks in quiescence search
|
||||||
|
@ -91,6 +90,7 @@ private:
|
||||||
int phaseIndex;
|
int phaseIndex;
|
||||||
int numOfMoves, numOfBadCaptures;
|
int numOfMoves, numOfBadCaptures;
|
||||||
int movesPicked;
|
int movesPicked;
|
||||||
|
bool checkKillers, checkLegal;
|
||||||
bool finished;
|
bool finished;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue