mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:17:44 +00:00
LibChess: Only save hash of board state for repetition checking
This more than doubles the number of nodes that MCTS can search for a given time limit, and greatly reduces memory usage.
This commit is contained in:
parent
675b8ba995
commit
57bb4d1aec
2 changed files with 9 additions and 10 deletions
|
@ -579,14 +579,12 @@ bool Board::apply_move(const Move& move, Color color)
|
||||||
|
|
||||||
bool Board::apply_illegal_move(const Move& move, Color color)
|
bool Board::apply_illegal_move(const Move& move, Color color)
|
||||||
{
|
{
|
||||||
Board clone = *this;
|
auto state = Traits<Board>::hash(*this);
|
||||||
clone.m_previous_states = {};
|
|
||||||
clone.m_moves = {};
|
|
||||||
auto state_count = 0;
|
auto state_count = 0;
|
||||||
if (m_previous_states.contains(clone))
|
if (m_previous_states.contains(state))
|
||||||
state_count = m_previous_states.get(clone).value();
|
state_count = m_previous_states.get(state).value();
|
||||||
|
|
||||||
m_previous_states.set(clone, state_count + 1);
|
m_previous_states.set(state, state_count + 1);
|
||||||
m_moves.append(move);
|
m_moves.append(move);
|
||||||
|
|
||||||
m_turn = opposing_color(color);
|
m_turn = opposing_color(color);
|
||||||
|
@ -758,7 +756,7 @@ Board::Result Board::game_result() const
|
||||||
if (m_moves_since_capture == 50 * 2)
|
if (m_moves_since_capture == 50 * 2)
|
||||||
return Result::FiftyMoveRule;
|
return Result::FiftyMoveRule;
|
||||||
|
|
||||||
auto repeats = m_previous_states.get(*this);
|
auto repeats = m_previous_states.get(Traits<Board>::hash(*this));
|
||||||
if (repeats.has_value()) {
|
if (repeats.has_value()) {
|
||||||
if (repeats.value() == 3)
|
if (repeats.value() == 3)
|
||||||
return Result::ThreeFoldRepetition;
|
return Result::ThreeFoldRepetition;
|
||||||
|
|
|
@ -172,7 +172,8 @@ private:
|
||||||
bool m_black_can_castle_kingside { true };
|
bool m_black_can_castle_kingside { true };
|
||||||
bool m_black_can_castle_queenside { true };
|
bool m_black_can_castle_queenside { true };
|
||||||
|
|
||||||
HashMap<Board, int> m_previous_states;
|
// We trust that hash collisions will not happen to save lots of memory and time.
|
||||||
|
HashMap<unsigned, int> m_previous_states;
|
||||||
Vector<Move> m_moves;
|
Vector<Move> m_moves;
|
||||||
friend struct Traits<Board>;
|
friend struct Traits<Board>;
|
||||||
};
|
};
|
||||||
|
@ -276,7 +277,7 @@ void Board::generate_moves(Callback callback, Color color) const
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct AK::Traits<Chess::Piece> : public GenericTraits<Chess::Piece> {
|
struct AK::Traits<Chess::Piece> : public GenericTraits<Chess::Piece> {
|
||||||
static unsigned hash(Chess::Piece piece)
|
static unsigned hash(const Chess::Piece& piece)
|
||||||
{
|
{
|
||||||
return pair_int_hash(static_cast<u32>(piece.color), static_cast<u32>(piece.type));
|
return pair_int_hash(static_cast<u32>(piece.color), static_cast<u32>(piece.type));
|
||||||
}
|
}
|
||||||
|
@ -284,7 +285,7 @@ struct AK::Traits<Chess::Piece> : public GenericTraits<Chess::Piece> {
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct AK::Traits<Chess::Board> : public GenericTraits<Chess::Board> {
|
struct AK::Traits<Chess::Board> : public GenericTraits<Chess::Board> {
|
||||||
static unsigned hash(Chess::Board chess)
|
static unsigned hash(const Chess::Board chess)
|
||||||
{
|
{
|
||||||
unsigned hash = 0;
|
unsigned hash = 0;
|
||||||
hash = pair_int_hash(hash, static_cast<u32>(chess.m_white_can_castle_queenside));
|
hash = pair_int_hash(hash, static_cast<u32>(chess.m_white_can_castle_queenside));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue