CACHE_LINE_ALIGNMENT
const uint8_t MainSearchPhaseTable[] = { PH_TT_MOVES, PH_GOOD_CAPTURES, PH_KILLERS, PH_NONCAPTURES, PH_BAD_CAPTURES, PH_STOP};
- const uint8_t EvasionsPhaseTable[] = { PH_EVASIONS, PH_STOP};
+ const uint8_t EvasionsPhaseTable[] = { PH_TT_MOVES, PH_EVASIONS, PH_STOP};
const uint8_t QsearchWithChecksPhaseTable[] = { PH_TT_MOVES, PH_QCAPTURES, PH_QCHECKS, PH_STOP};
const uint8_t QsearchWithoutChecksPhaseTable[] = { PH_TT_MOVES, PH_QCAPTURES, PH_STOP};
}
finished = false;
lastBadCapture = badCaptures;
- if (ss)
+ pinned = p.pinned_pieces(pos.side_to_move());
+
+ if (ss && !p.is_check())
{
ttMoves[1].move = (ss->mateKiller == ttm)? MOVE_NONE : ss->mateKiller;
searchTT |= ttMoves[1].move;
} else
ttMoves[1].move = killers[0].move = killers[1].move = MOVE_NONE;
- Color us = pos.side_to_move();
-
- dc = p.discovered_check_candidates(us);
- pinned = p.pinned_pieces(us);
-
if (p.is_check())
phasePtr = EvasionsPhaseTable;
else if (d > Depth(0))
- phasePtr = MainSearchPhaseTable + !searchTT;
+ phasePtr = MainSearchPhaseTable;
else if (d == Depth(0))
- phasePtr = QsearchWithChecksPhaseTable + !searchTT;
+ phasePtr = QsearchWithChecksPhaseTable;
else
- phasePtr = QsearchWithoutChecksPhaseTable + !searchTT;
+ phasePtr = QsearchWithoutChecksPhaseTable;
- phasePtr--;
+ phasePtr += !searchTT - 1;
go_next_phase();
}
case PH_GOOD_CAPTURES:
lastMove = generate_captures(pos, moves);
score_captures();
- sort_moves(moves, lastMove);
return;
case PH_KILLERS:
// to get SEE move ordering.
curMove = badCaptures;
lastMove = lastBadCapture;
- sort_moves(badCaptures, lastMove);
return;
case PH_EVASIONS:
assert(pos.is_check());
- lastMove = generate_evasions(pos, moves, pinned);
+ lastMove = generate_evasions(pos, moves);
score_evasions();
- sort_moves(moves, lastMove);
return;
case PH_QCAPTURES:
lastMove = generate_captures(pos, moves);
score_captures();
- sort_moves(moves, lastMove);
return;
case PH_QCHECKS:
// Perhaps we should order moves move here? FIXME
- lastMove = generate_non_capture_checks(pos, moves, dc);
+ lastMove = generate_non_capture_checks(pos, moves);
return;
case PH_STOP:
if (move_is_promotion(m))
cur->score = QueenValueMidgame;
else
- cur->score = int(pos.midgame_value_of_piece_on(move_to(m)))
- -int(pos.type_of_piece_on(move_from(m)));
+ cur->score = pos.midgame_value_of_piece_on(move_to(m))
+ - pos.type_of_piece_on(move_from(m));
}
}
hs += 1000;
// pst based scoring
- cur->score = hs + pos.pst_delta<Position::MidGame>(piece, from, to);
+ cur->score = hs + mg_value(pos.pst_delta(piece, from, to));
}
}
void MovePicker::score_evasions() {
-
+ // Try good captures ordered by MVV/LVA, then non-captures if
+ // destination square is not under attack, ordered by history
+ // value, and at the end bad-captures and non-captures with a
+ // negative SEE. This last group is ordered by the SEE score.
Move m;
+ int seeScore;
for (MoveStack* cur = moves; cur != lastMove; cur++)
{
m = cur->move;
- if (m == ttMoves[0].move)
- cur->score = 2 * HistoryMax;
- else if (!pos.square_is_empty(move_to(m)))
- {
- int seeScore = pos.see(m);
- cur->score = seeScore + (seeScore >= 0 ? HistoryMax : 0);
- } else
+ if ((seeScore = pos.see_sign(m)) < 0)
+ cur->score = seeScore;
+ else if (pos.move_is_capture(m))
+ cur->score = pos.midgame_value_of_piece_on(move_to(m))
+ - pos.type_of_piece_on(move_from(m)) + HistoryMax;
+ else
cur->score = H.move_ordering_score(pos.piece_on(move_from(m)), move_to(m));
}
}
Move MovePicker::get_next_move() {
- assert(!pos.is_check() || *phasePtr == PH_EVASIONS || *phasePtr == PH_STOP);
- assert( pos.is_check() || *phasePtr != PH_EVASIONS);
-
Move move;
while (true)
{
while (curMove != lastMove)
{
- move = (curMove++)->move;
-
switch (phase) {
case PH_TT_MOVES:
+ move = (curMove++)->move;
if ( move != MOVE_NONE
&& move_is_legal(pos, move, pinned))
return move;
break;
case PH_GOOD_CAPTURES:
+ move = pick_best(curMove++, lastMove).move;
if ( move != ttMoves[0].move
&& move != ttMoves[1].move
&& pos.pl_move_is_legal(move, pinned))
break;
case PH_KILLERS:
+ move = (curMove++)->move;
if ( move != MOVE_NONE
&& move != ttMoves[0].move
&& move != ttMoves[1].move
break;
case PH_NONCAPTURES:
+ move = (curMove++)->move;
if ( move != ttMoves[0].move
&& move != ttMoves[1].move
&& move != killers[0].move
return move;
break;
- case PH_EVASIONS:
case PH_BAD_CAPTURES:
+ move = pick_best(curMove++, lastMove).move;
return move;
+ case PH_EVASIONS:
case PH_QCAPTURES:
+ move = pick_best(curMove++, lastMove).move;
+ if ( move != ttMoves[0].move
+ && pos.pl_move_is_legal(move, pinned))
+ return move;
+ break;
+
case PH_QCHECKS:
- // Maybe postpone the legality check until after futility pruning?
+ move = (curMove++)->move;
if ( move != ttMoves[0].move
&& pos.pl_move_is_legal(move, pinned))
return move;