}
// 5-6. Halfmove clock and fullmove number
- ss >> std::skipws >> st->rule50 >> startPosPly;
+ ss >> std::skipws >> st->rule50 >> gamePly;
// Convert from fullmove starting from 1 to ply starting from 0,
// handle also common incorrect FEN with fullmove = 0.
- startPosPly = std::max(2 * (startPosPly - 1), 0) + int(sideToMove == BLACK);
+ gamePly = std::max(2 * (gamePly - 1), 0) + int(sideToMove == BLACK);
st->key = compute_key();
st->pawnKey = compute_pawn_key();
ss << '-';
ss << (ep_square() == SQ_NONE ? " - " : " " + square_to_string(ep_square()) + " ")
- << st->rule50 << " " << 1 + (startPosPly - int(sideToMove == BLACK)) / 2;
+ << st->rule50 << " " << 1 + (gamePly - int(sideToMove == BLACK)) / 2;
return ss.str();
}
// Update side to move
k ^= Zobrist::side;
- // Increment the 50 moves rule draw counter. Resetting it to zero in the
- // case of a capture or a pawn move is taken care of later.
+ // Increment ply counters.In particular rule50 will be later reset it to zero
+ // in case of a capture or a pawn move.
+ gamePly++;
st->rule50++;
st->pliesFromNull++;
// Update piece list, move the last piece at index[capsq] position and
// shrink the list.
//
- // WARNING: This is a not revresible operation. When we will reinsert the
+ // WARNING: This is a not reversible operation. When we will reinsert the
// captured piece in undo_move() we will put it at the end of the list and
// not in its original place, it means index[] and pieceList[] are not
// guaranteed to be invariant to a do_move() + undo_move() sequence.
// Finally point our state pointer back to the previous state
st = st->previous;
+ gamePly--;
assert(pos_is_ok());
}
/// Position::is_draw() tests whether the position is drawn by material,
/// repetition, or the 50 moves rule. It does not detect stalemates, this
/// must be done by the search.
-template<bool CheckRepetition, bool CheckThreeFold>
+template<bool SkipRepetition>
bool Position::is_draw() const {
+ // Draw by material?
if ( !pieces(PAWN)
&& (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMg))
return true;
+ // Draw by the 50 moves rule?
if (st->rule50 > 99 && (!checkers() || MoveList<LEGAL>(*this).size()))
return true;
- if (CheckRepetition)
+ // Draw by repetition?
+ if (!SkipRepetition)
{
- int i = 4, e = std::min(st->rule50, st->pliesFromNull), cnt;
+ int i = 4, e = std::min(st->rule50, st->pliesFromNull);
if (i <= e)
{
StateInfo* stp = st->previous->previous;
- for (cnt = 0; i <= e; i += 2)
- {
+ do {
stp = stp->previous->previous;
- if (stp->key == st->key && (!CheckThreeFold || ++cnt >= 2))
+ if (stp->key == st->key)
return true;
- }
+
+ i += 2;
+
+ } while (i <= e);
}
}
}
// Explicit template instantiations
-template bool Position::is_draw<true, true>() const;
-template bool Position::is_draw<true, false>() const;
-template bool Position::is_draw<false,false>() const;
+template bool Position::is_draw<false>() const;
+template bool Position::is_draw<true>() const;
/// Position::flip() flips position with the white and black sides reversed. This
thisThread = pos.this_thread();
nodes = pos.nodes_searched();
chess960 = pos.is_chess960();
- startPosPly = pos.startpos_ply_counter();
+ gamePly = pos.game_ply();
for (Square s = SQ_A1; s <= SQ_H8; s++)
if (!pos.is_empty(s))