Skip to content

Commit

Permalink
Fixed search to return score for King of the Hill win/loss condition.
Browse files Browse the repository at this point in the history
  • Loading branch information
ddugovic committed Aug 4, 2014
1 parent 463e7ab commit f94b6af
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/evaluate.cpp
Expand Up @@ -699,9 +699,9 @@ namespace {
score = pos.psq_score();

#ifdef KOTH
// Possibly redundant static evaluator
if (pos.is_koth())
{
// TODO: Do we need or want both conditions here?
if (pos.is_koth_win())
return VALUE_MATE;
if (pos.is_koth_loss())
Expand Down
8 changes: 0 additions & 8 deletions src/movepick.cpp
Expand Up @@ -302,14 +302,6 @@ void MovePicker::generate_next_stage() {
template<>
Move MovePicker::next_move<false>() {

#ifdef KOTH
assert(!pos.is_koth_win());

// Best move can only be MOVE_NONE when searching on a lost KOTH position
if (pos.is_koth_loss())
return MOVE_NONE;
#endif

Move move;

while (true)
Expand Down
19 changes: 15 additions & 4 deletions src/position.cpp
Expand Up @@ -539,6 +539,12 @@ bool Position::legal(Move m, Bitboard pinned) const {
assert(color_of(moved_piece(m)) == us);
assert(piece_on(king_square(us)) == make_piece(us, KING));

#ifdef KOTH
// If the game is already won or lost, further moves are illegal
if (is_koth() && (is_koth_win() || is_koth_loss()))
return false;
#endif

// En passant captures are a tricky special case. Because they are rather
// uncommon, we do it simply by testing whether the king is attacked after
// the move is made.
Expand Down Expand Up @@ -583,6 +589,12 @@ bool Position::pseudo_legal(const Move m) const {
Square to = to_sq(m);
Piece pc = moved_piece(m);

#ifdef KOTH
// If the game is already won or lost, further moves are illegal
if (is_koth() && (is_koth_win() || is_koth_loss()))
return false;
#endif

// Use a slower but simpler function for uncommon cases
if (type_of(m) != NORMAL)
return MoveList<LEGAL>(*this).contains(m);
Expand Down Expand Up @@ -719,10 +731,6 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI

assert(is_ok(m));
assert(&newSt != st);
#ifdef KOTH
assert(!is_koth_win());
assert(!is_koth_loss());
#endif

++nodes;
Key k = st->key;
Expand Down Expand Up @@ -1138,6 +1146,9 @@ Value Position::see(Move m) const {
bool Position::is_draw() const {

if ( !pieces(PAWN)
#ifdef KOTH
&& !is_koth()
#endif
&& (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMg))
return true;

Expand Down
22 changes: 22 additions & 0 deletions src/search.cpp
Expand Up @@ -481,6 +481,17 @@ namespace {

if (!RootNode)
{
#ifdef KOTH
// Check for an instant win (King of the Hill)
if (pos.is_koth())
{
if (pos.is_koth_win())
return mate_in(ss->ply+1);
if (pos.is_koth_loss())
return mated_in(ss->ply);
}
#endif

// Step 2. Check for aborted search and immediate draw
if (Signals.stop || pos.is_draw() || ss->ply > MAX_PLY)
return ss->ply > MAX_PLY && !inCheck ? evaluate(pos) : DrawValue[pos.side_to_move()];
Expand Down Expand Up @@ -1065,6 +1076,17 @@ namespace {
ss->currentMove = bestMove = MOVE_NONE;
ss->ply = (ss-1)->ply + 1;

#ifdef KOTH
// Check for an instant win or loss (King of the Hill)
if (pos.is_koth())
{
if (pos.is_koth_win())
return mate_in(ss->ply+1);
if (pos.is_koth_loss())
return mated_in(ss->ply);
}
#endif

// Check for an instant draw or if the maximum ply has been reached
if (pos.is_draw() || ss->ply > MAX_PLY)
return ss->ply > MAX_PLY && !InCheck ? evaluate(pos) : DrawValue[pos.side_to_move()];
Expand Down

0 comments on commit f94b6af

Please sign in to comment.