Skip to content
Open

Ttpv #72

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ int Searcher::quiescence_search(int alpha, int beta, SearchStack *ss)
bool tt_hit = !ss->exclude_tt_move && tt_entry.hash_equals(board) && tt_entry.flag() != BOUND::NONE;
Move tt_move = ss->exclude_tt_move ? NO_MOVE : tt_entry.best_move;

bool ttPV = tt_hit && tt_entry.ttPV();

// tt cutoff
// if the tt_entry matches, we can use the score, and the depth is the same or greater, we can just cut the search short
if (!inPV && !ss->exclude_tt_move && tt_entry.hash_equals(board) && tt_entry.can_use_score(alpha, beta))
Expand Down Expand Up @@ -202,7 +204,7 @@ int Searcher::quiescence_search(int alpha, int beta, SearchStack *ss)
bound_flag = BOUND::FAIL_HIGH;
}

transposition_table.insert(board, best_move, best_score, uncorrected_static_eval, 0, ss->ply, age, bound_flag);
transposition_table.insert(board, best_move, best_score, uncorrected_static_eval, 0, ss->ply, age, ttPV, bound_flag);
}

// TODO: add check moves
Expand Down Expand Up @@ -249,15 +251,15 @@ int Searcher::negamax(int alpha, int beta, int depth, bool cutnode, SearchStack
return 0;
}

// bool inPV = beta - alpha > 1;

// we check if the TT has seen this before
TT_Entry tt_entry = transposition_table.probe(board);

bool tt_hit = !ss->exclude_tt_move && tt_entry.hash_equals(board) && tt_entry.flag() != BOUND::NONE;
Move tt_move = ss->exclude_tt_move ? NO_MOVE : tt_entry.best_move;
bool has_tt_move = tt_entry.flag() != BOUND::NONE && tt_entry.hash_equals(board) && tt_entry.best_move != NO_MOVE;

ss->ttPV = ss->exclude_tt_move ? ss->ttPV : inPV || (tt_hit && tt_entry.ttPV());

// tt cutoff
// if the tt_entry matches, we can use the score, and the depth is the same or greater, we can just cut the search short
if (!inPV && !ss->exclude_tt_move && tt_entry.hash_equals(board) && tt_entry.can_use_score(alpha, beta) && tt_entry.depth >= depth)
Expand Down Expand Up @@ -403,8 +405,8 @@ int Searcher::negamax(int alpha, int beta, int depth, bool cutnode, SearchStack

if (score >= probcut_beta)
{
// update tranposition table
transposition_table.insert(board, curr_move, score, uncorrected_static_eval, depth - 3, ss->ply, age, BOUND::FAIL_HIGH);
// update tranposition table (we are never in PV in probcut)
transposition_table.insert(board, curr_move, score, uncorrected_static_eval, depth - 3, ss->ply, age, nonPV, BOUND::FAIL_HIGH);

return score;
}
Expand Down Expand Up @@ -578,7 +580,7 @@ int Searcher::negamax(int alpha, int beta, int depth, bool cutnode, SearchStack
reduction -= history_score / 10'000;

if (inPV)
reduction -= 1;
--reduction;

// Late Move Reduction: we've ordered the move in order of importance. We reduce the
// the depths of later moves because they are less important
Expand Down Expand Up @@ -720,7 +722,7 @@ int Searcher::negamax(int alpha, int beta, int depth, bool cutnode, SearchStack
bound_flag = BOUND::FAIL_LOW;
}
if (best_score != (-INF - 1))
transposition_table.insert(board, best_move, best_score, uncorrected_static_eval, depth, ss->ply, age, bound_flag);
transposition_table.insert(board, best_move, best_score, uncorrected_static_eval, depth, ss->ply, age, ss->ttPV, bound_flag);
}

// update corrhist if we're not in check
Expand Down
1 change: 1 addition & 0 deletions src/search_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class SearchStack
// used for lazy updates,
bool updated_accumulator = false;
bool in_check = false;
bool ttPV = false;
int ply;
Killers killers;
MoveList pv;
Expand Down
22 changes: 14 additions & 8 deletions src/transposition_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ TT_Entry::TT_Entry()
flag_and_age = BOUND::NONE;
}

TT_Entry::TT_Entry(const Board &board, Move best_move, int16_t score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, uint8_t flag)
TT_Entry::TT_Entry(const Board &board, Move best_move, int16_t score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, bool inPV, uint8_t flag)
{
this->hash = static_cast<uint16_t>(board.hash);
this->best_move = best_move;
Expand All @@ -36,18 +36,24 @@ TT_Entry::TT_Entry(const Board &board, Move best_move, int16_t score, int16_t st
}

// basically mod 64
uint8_t modular_age = age & 63;
this->flag_and_age = (modular_age << 2) | flag;
uint8_t modular_age = age & 31;
this->flag_and_age = (modular_age << 3) | (inPV << 2) | flag;
}

uint8_t TT_Entry::flag() const
{
return this->flag_and_age & 3;
return flag_and_age & 3;
}

bool TT_Entry::ttPV() const
{
// gets the 3rd bit
return flag_and_age & 4;
}

uint8_t TT_Entry::age() const
{
return this->flag_and_age >> 2;
return this->flag_and_age >> 3;
}

bool TT_Entry::can_use_score(int alpha, int beta) const
Expand Down Expand Up @@ -108,7 +114,7 @@ void TranspositionTable::prefetch(const Board &board)
__builtin_prefetch(&hashtable[hash_location]);
}

void TranspositionTable::insert(const Board &board, Move best_move, int16_t best_score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, uint8_t flag)
void TranspositionTable::insert(const Board &board, Move best_move, int16_t best_score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, bool inPV, uint8_t flag)
{
uint64_t hash_location = index(board);

Expand Down Expand Up @@ -144,8 +150,8 @@ void TranspositionTable::insert(const Board &board, Move best_move, int16_t best
entry.score = best_score;
}

uint8_t modular_age = age & 63;
entry.flag_and_age = (modular_age << 2) | flag;
uint8_t modular_age = age & 31;
entry.flag_and_age = (modular_age << 3) | (inPV << 2) | flag;
}

TT_Entry &TranspositionTable::probe(const Board &board)
Expand Down
7 changes: 4 additions & 3 deletions src/transposition_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ class TT_Entry
Move best_move;
int16_t score;
uint8_t depth;
// least 2 significant bits is the flag, and the rest stores the age, or the number of times we've called "go"
// least 2 significant bits is the flag, next bit stores ttpv (1 for PV), and the rest stores the age, or the number of times we've called "go"
uint8_t flag_and_age;
int16_t static_eval;

// dummy tt entry that allows us to find the size of the TT
TT_Entry();
TT_Entry(const Board &board, Move best_move, int16_t score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, uint8_t flag);
TT_Entry(const Board &board, Move best_move, int16_t score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, bool inPV, uint8_t flag);
uint8_t flag() const;
// moded to 64
uint8_t age() const;
bool ttPV() const;
inline bool hash_equals(const Board &board) const { return static_cast<uint16_t>(board.hash) == hash; }
bool can_use_score(int alpha, int beta) const;
// converts the score into the TT into a score that can used to detect and play mates
Expand All @@ -40,7 +41,7 @@ class TranspositionTable
// clears the transposition table
void resize(size_t size);
void prefetch(const Board &board);
void insert(const Board &board, Move best_move, int16_t best_score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, uint8_t flag);
void insert(const Board &board, Move best_move, int16_t best_score, int16_t static_eval, uint8_t depth, uint8_t ply, uint32_t age, bool inPV, uint8_t flag);
void clear();
// prints out permille what percent of the hashtable is full
int hash_full();
Expand Down