Xiangiqgame
AI engine for Xiangqi
Loading...
Searching...
No Matches
zobrist.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
8#include <array>
9#include <atomic>
11#include <chrono>
16#include <mutex>
17#include <optional>
18#include <random>
19#include <shared_mutex>
20#include <thread>
21#include <vector>
22
24namespace boardstate {
25
29template <typename KeyType>
31private:
33 array<array<KeyType, gameboard::kNumFiles>, gameboard::kNumRanks>;
34 using TeamZarray_t = array<PieceZarray_t, gameboard::kNumPieceTypeVals>;
35 using GameZarray_t = array<TeamZarray_t, 2>;
36
38 KeyType turn_key_;
39 uint32_t seed_;
40 KeyType board_state_;
41
42public:
45 ZobristCalculator(uint32_t seed = std::random_device{}())
46 : zarray_{}
47 , turn_key_{}
48 , board_state_{}
49 , seed_{seed} {
51 turn_key_ = key_generator.GenerateKey();
52 zarray_ = CreateGameZarray(key_generator);
53 };
54
55 // Getters
56 KeyType board_state() const { return board_state_; }
57 GameZarray_t zarray() const { return zarray_; }
58 KeyType turn_key() const { return turn_key_; }
59 uint32_t seed() const { return seed_; }
60
61 // Calculation methods
62
65 }
66
67 void UpdateBoardState(const gameboard::ExecutedMove &executed_move) {
68 UpdateBoardStateInternal(executed_move);
69 }
70
71 KeyType GetHashValueAt(PieceColor color, PieceType piece_type, BoardSpace space) {
72 return zarray_[GetZColorIndexOf(color)][piece_type][space.rank][space.file];
73 }
74
75private:
79 ) {
80 GameZarray_t game_zarray{};
81 for (auto color_idx = 0; color_idx < 2; color_idx++) {
82 for (auto piece_id = 1; piece_id < kNumPieceTypeVals; piece_id++) {
83 for (auto rank = 0; rank < kNumRanks; rank++) {
84 for (auto file = 0; file < kNumFiles; file++) {
85 game_zarray[color_idx][piece_id][rank][file] = key_generator.GenerateKey();
86 }
87 }
88 }
89 }
90 return game_zarray;
91 }
92
93 // Calculation methods
94
96 board_state_ = 0;
97 for (size_t rank = 0; rank < gameboard::kNumRanks; rank++) {
98 for (size_t file = 0; file < gameboard::kNumFiles; file++) {
99 if (board_map[rank][file].piece_color != 0) {
101 board_map[rank][file].piece_color,
102 board_map[rank][file].piece_type,
103 gameboard::BoardSpace{(int)rank, (int)file}
104 );
105 }
106 }
107 }
108 }
109
112 executed_move.moving_piece.piece_color,
113 executed_move.moving_piece.piece_type,
114 executed_move.spaces.start
115 );
116
117 // if capture piece, remove from board
120 executed_move.destination_piece.piece_color,
121 executed_move.destination_piece.piece_type,
122 executed_move.spaces.end
123 );
124 }
125
126 // moving piece to new space
128 executed_move.moving_piece.piece_color,
129 executed_move.moving_piece.piece_type,
130 executed_move.spaces.end
131 );
132
133 // change state now that its other player's turn
135 }
136};
137
141template <typename KeyType, size_t NumConfKeys>
143private:
145 std::array<ZobristCalculator<KeyType>, NumConfKeys> confirmation_calculators_;
146 std::optional<uint32_t> prng_seed_;
147
148public:
151 const ZobristCalculator<KeyType> primary_calculator,
152 const std::array<ZobristCalculator<KeyType>, NumConfKeys> &confirmation_calculators
153 )
154 : primary_calculator_{primary_calculator}
155 , confirmation_calculators_(confirmation_calculators) {}
156
158 explicit ZobristComponent(uint32_t prng_seed = std::random_device{}())
159 : ZobristComponent(std::mt19937{prng_seed}) {
161 }
162
163 // Getters
164 KeyType primary_board_state() { return primary_calculator_.board_state(); }
165 std::array<KeyType, NumConfKeys> confirmation_board_states() {
167 }
168 KeyType primary_calculator_seed() { return primary_calculator_.seed(); }
169 std::array<uint32_t, NumConfKeys> confirmation_calculator_seeds() const {
171 }
172 std::string primary_board_state_hex_str() const {
174 }
175 uint32_t prng_seed() { return prng_seed_.value_or(0); }
176
177 // Calculation methods
178 void UpdateBoardStates(const ExecutedMove &executed_move) {
179 UpdateBoardStatesInternal(executed_move);
180 }
181
182 void FullBoardStateCalc(const BoardMap_t &board_map) {
184 }
185
186private:
189 explicit ZobristComponent(std::mt19937 prng)
190 : primary_calculator_{(uint32_t)prng()}
192 for (auto i = 0; i < NumConfKeys; i++) {
194 }
195 }
196
197 // Internal getters
198 std::array<KeyType, NumConfKeys> confirmation_board_states_internal() {
199 std::array<KeyType, NumConfKeys> confirmation_states;
200 for (auto i = 0; i < NumConfKeys; ++i) {
201 confirmation_states[i] = confirmation_calculators_[i].board_state();
202 }
203 return confirmation_states;
204 }
205
206 std::array<uint32_t, NumConfKeys> confirmation_calculator_seeds_internal() const {
207 std::array<uint32_t, NumConfKeys> seeds;
208 for (auto i = 0; i < NumConfKeys; ++i) {
209 seeds[i] = confirmation_calculators_[i].seed();
210 }
211 }
212
213 // Internal calculation methods
214 void UpdateBoardStatesInternal(const ExecutedMove &executed_move) {
215 primary_calculator_.UpdateBoardState(executed_move);
216 for (auto &calculator : confirmation_calculators_) {
217 calculator.UpdateBoardState(executed_move);
218 }
219 }
220
221 void FullBoardStateCalcInternal(const BoardMap_t &board_map) {
222 primary_calculator_.FullBoardStateCalc(board_map);
223 for (auto &calculator : confirmation_calculators_) {
224 calculator.FullBoardStateCalc(board_map);
225 }
226 }
227};
228
233template <typename KeyType, size_t NumConfKeys>
235private:
237 std::array<KeyType, NumConfKeys> confirmation_keys_;
239
240public:
243 std::array<KeyType, NumConfKeys> confirmation_keys,
245 )
249
251
252 std::array<KeyType, NumConfKeys> confirmation_keys() { return confirmation_keys_; }
253
255
258 }
259
260 bool ConfirmationKeysMatchExpected(std::array<KeyType, NumConfKeys> expected_keys) {
261 for (auto i = 0; i < NumConfKeys; ++i) {
262 if (expected_keys[i] != confirmation_keys_[i]) {
263 return false;
264 }
265 }
266 return true;
267 }
268
271 }
272};
273
278template <typename KeyType, size_t NumConfKeys>
280 std::unordered_map<KeyType, TranspositionTableEntry<KeyType, NumConfKeys>> data_;
282
283public:
285
287 KeyType primary_board_state,
288 DepthType remaining_search_depth,
289 std::array<KeyType, NumConfKeys> expected_keys
290 ) {
292 auto tr_table_entry_it = data_.find(primary_board_state);
293 if (tr_table_entry_it != data_.end()) {
294 auto tr_table_entry = tr_table_entry_it->second;
295 if (tr_table_entry.remaining_search_depth() >= remaining_search_depth) {
296 tr_table_entry.set_last_access_index(move_counter_);
297 result.set_found(true);
298 result.set_minimax_calc_result(tr_table_entry.minimax_calc_result());
299 }
300 if (result.found() and
301 !tr_table_entry.ConfirmationKeysMatchExpected(expected_keys)) {
302 result.set_known_collision(true);
303 }
304 }
305 return result;
306 }
307
309 KeyType primary_board_state,
310 DepthType search_depth,
312 moveselection::EqualScoreMoves &similar_moves,
313 const std::array<KeyType, NumConfKeys> &confirmation_keys
314 ) {
315 data_.insert_or_assign(
316 primary_board_state,
318 moveselection::MinimaxCalcResult{search_depth, result_type, similar_moves},
319 confirmation_keys,
321 }
322 );
323 }
324
325 size_t size() { return data_.size(); }
326
328
329 MoveCountType NumIdleMovesAt(KeyType board_state) {
330 auto tr_table_entry_it = data_.at(board_state);
331 return NumMovesSinceLastUseOf(tr_table_entry_it->second);
332 }
333
334private:
337 ) {
338 return move_counter_ - tr_table_entry.last_access_index();
339 }
340};
341
344 mutable std::mutex tr_table_mutex_;
345
346public:
350
351 std::unique_lock<std::mutex> GetExclusiveLock() {
352 return std::unique_lock<std::mutex>(tr_table_mutex_);
353 }
354};
355
357template <typename KeyType, size_t NumConfKeys>
361 std::thread pruning_thread_;
362 std::atomic<bool> keep_running_;
363
364public:
367
370 TranspositionTableGuard &tr_table_guard
371 )
372 : tr_table_{tr_table}
373 , tr_table_guard_{tr_table_guard}
375 , keep_running_{true} {}
376
378 if (pruning_thread_.joinable()) {
379 pruning_thread_.join();
380 }
381 }
382
383 void Start() {
385 }
386
387 void Stop() { keep_running_ = false; }
388
389 // void IncrementMoveCounter() { move_count_++; }
390
391private:
393 // TODO: Implement me!
394 std::cout << "Pruning!" << std::endl;
395 }
396
398 std::this_thread::sleep_for(std::chrono::microseconds(200));
399 auto lock = tr_table_guard_.GetExclusiveLock();
401 }
402
404 while (keep_running_) {
406 }
407 }
408};
409
414template <typename KeyType, size_t NumConfKeys>
416 : public BoardStateCoordinator<ZobristCoordinator<KeyType, NumConfKeys>, KeyType> {
421
422public:
425
427 : zobrist_component_{std::move(zobrist_component)}
428 , tr_table_{}
431 // tr_table_pruner_.Start();
432 }
433
435 uint32_t primary_seed,
436 std::array<uint32_t, NumConfKeys> confirmation_seeds
437 )
439 ZobristComponent<KeyType, NumConfKeys>{primary_seed, confirmation_seeds}
440 ) {}
441
442 explicit ZobristCoordinator(uint32_t prng_seed = (uint32_t)std::random_device{}())
443 : ZobristCoordinator(ZobristComponent<KeyType, NumConfKeys>{prng_seed}) {}
444
445 KeyType ImplementGetState() { return zobrist_component_.primary_board_state(); }
446
447 void ImplementUpdateBoardState(const ExecutedMove &executed_move) {
448 zobrist_component_.UpdateBoardStates(executed_move);
449 }
450
452 zobrist_component_.FullBoardStateCalc(board_map);
453 }
454
456 DepthType search_depth,
458 moveselection::EqualScoreMoves &similar_moves,
459 MoveCountType access_index
460 ) {
461 tr_table_.RecordData(
462 zobrist_component_.primary_board_state(),
463 search_depth,
464 result_type,
465 similar_moves,
466 zobrist_component_.confirmation_board_states()
467 );
468 }
469
471 DepthType search_depth,
472 MoveCountType access_index
473 ) {
474 return tr_table_.GetDataAt(
475 zobrist_component_.primary_board_state(),
476 search_depth,
477 zobrist_component_.confirmation_board_states()
478 );
479 }
480
481 size_t ImplementGetTrTableSize() { return tr_table_.size(); }
482
484 // tr_table_pruner_.IncrementMoveCounter();
485 tr_table_.IncrementMoveCounter();
486 }
487
488 const std::string board_state_hex_str() {
489 return IntToHexString(zobrist_component_.primary_board_state());
490 }
491
492 uint32_t zkeys_seed() { return zobrist_component_.prng_seed(); }
493};
494
495} // namespace boardstate
Constants, typedefs, and simple structs used by gameboard::GameBoard.
Definition of BoardStateCoordinator.
CRTP Interface with methods to calculate / read / update hash values representing a board state; and ...
Generates pseudorandom integers.
IntType GenerateKey()
Generates a pseudorandom IntType value using mt19937.
Data structure to hold calculation results that get entered into a boardstate::TranspositionTable.
Definition: zobrist.hpp:234
std::array< KeyType, NumConfKeys > confirmation_keys()
Definition: zobrist.hpp:252
TranspositionTableEntry(moveselection::MinimaxCalcResult minimax_calc_result, std::array< KeyType, NumConfKeys > confirmation_keys, MoveCountType last_access_index)
Definition: zobrist.hpp:241
void set_last_access_index(MoveCountType last_access_index)
Definition: zobrist.hpp:256
moveselection::MinimaxCalcResult minimax_calc_result_
Definition: zobrist.hpp:236
moveselection::MinimaxCalcResult minimax_calc_result()
Definition: zobrist.hpp:250
std::array< KeyType, NumConfKeys > confirmation_keys_
Definition: zobrist.hpp:237
bool ConfirmationKeysMatchExpected(std::array< KeyType, NumConfKeys > expected_keys)
Definition: zobrist.hpp:260
Contains std::mutex that other classes lock before accessing TranspositionTable.
Definition: zobrist.hpp:343
TranspositionTableGuard & operator=(const TranspositionTableGuard &)=delete
std::unique_lock< std::mutex > GetExclusiveLock()
Definition: zobrist.hpp:351
TranspositionTableGuard(const TranspositionTableGuard &)=delete
Removes old entries from TranspositionTable to prevent excessive memory use.
Definition: zobrist.hpp:358
TranspositionTablePruner(const TranspositionTablePruner &)=delete
TranspositionTablePruner & operator=(const TranspositionTablePruner &)=delete
TranspositionTablePruner(TranspositionTable< KeyType, NumConfKeys > &tr_table, TranspositionTableGuard &tr_table_guard)
Definition: zobrist.hpp:368
std::atomic< bool > keep_running_
Definition: zobrist.hpp:362
TranspositionTable< KeyType, NumConfKeys > & tr_table_
Definition: zobrist.hpp:359
TranspositionTableGuard & tr_table_guard_
Definition: zobrist.hpp:360
Stores and manages key-value pairs consisting of a board_state (from a boardstate::ZobristComponent) ...
Definition: zobrist.hpp:279
void RecordData(KeyType primary_board_state, DepthType search_depth, moveselection::MinimaxResultType result_type, moveselection::EqualScoreMoves &similar_moves, const std::array< KeyType, NumConfKeys > &confirmation_keys)
Definition: zobrist.hpp:308
MoveCountType NumMovesSinceLastUseOf(const TranspositionTableEntry< KeyType, NumConfKeys > &tr_table_entry)
Definition: zobrist.hpp:335
std::unordered_map< KeyType, TranspositionTableEntry< KeyType, NumConfKeys > > data_
Definition: zobrist.hpp:280
moveselection::TranspositionTableSearchResult GetDataAt(KeyType primary_board_state, DepthType remaining_search_depth, std::array< KeyType, NumConfKeys > expected_keys)
Definition: zobrist.hpp:286
MoveCountType NumIdleMovesAt(KeyType board_state)
Definition: zobrist.hpp:329
Uses Zobrist hashing to calculate a "reasonably unique" integer value for each board configuration en...
Definition: zobrist.hpp:30
ZobristCalculator(uint32_t seed=std::random_device{}())
Constructs a ZobristCalculator.
Definition: zobrist.hpp:45
void UpdateBoardStateInternal(const gameboard::ExecutedMove &executed_move)
Definition: zobrist.hpp:110
void UpdateBoardState(const gameboard::ExecutedMove &executed_move)
Definition: zobrist.hpp:67
void FullBoardStateCalc(const gameboard::BoardMap_t &board_map)
Definition: zobrist.hpp:63
array< array< KeyType, gameboard::kNumFiles >, gameboard::kNumRanks > PieceZarray_t
Definition: zobrist.hpp:33
void FullBoardStateCalInternal(const gameboard::BoardMap_t &board_map)
Definition: zobrist.hpp:95
array< TeamZarray_t, 2 > GameZarray_t
Definition: zobrist.hpp:35
uint32_t seed() const
Definition: zobrist.hpp:59
static const GameZarray_t CreateGameZarray(PseudoRandomKeyGenerator< KeyType > &key_generator)
Static helper method for building 4-D array of Zobrist keys in constuctor.
Definition: zobrist.hpp:77
KeyType turn_key() const
Definition: zobrist.hpp:58
KeyType board_state() const
Definition: zobrist.hpp:56
GameZarray_t zarray() const
Definition: zobrist.hpp:57
KeyType GetHashValueAt(PieceColor color, PieceType piece_type, BoardSpace space)
Definition: zobrist.hpp:71
array< PieceZarray_t, gameboard::kNumPieceTypeVals > TeamZarray_t
Definition: zobrist.hpp:34
Container for one or more boardstate::ZobristCalculator objects.
Definition: zobrist.hpp:142
ZobristComponent(uint32_t prng_seed=std::random_device{}())
Constructs ZobristComponent using 32-bit unsigned in as a PRNG seed.
Definition: zobrist.hpp:158
std::optional< uint32_t > prng_seed_
Definition: zobrist.hpp:146
std::array< ZobristCalculator< KeyType >, NumConfKeys > confirmation_calculators_
Definition: zobrist.hpp:145
std::array< uint32_t, NumConfKeys > confirmation_calculator_seeds() const
Definition: zobrist.hpp:169
std::string primary_board_state_hex_str() const
Definition: zobrist.hpp:172
ZobristComponent(std::mt19937 prng)
Constructs ZobristComponent from a std::mt19937 pseudorandom number generator.
Definition: zobrist.hpp:189
void FullBoardStateCalcInternal(const BoardMap_t &board_map)
Definition: zobrist.hpp:221
void UpdateBoardStates(const ExecutedMove &executed_move)
Definition: zobrist.hpp:178
std::array< KeyType, NumConfKeys > confirmation_board_states_internal()
Definition: zobrist.hpp:198
void FullBoardStateCalc(const BoardMap_t &board_map)
Definition: zobrist.hpp:182
std::array< KeyType, NumConfKeys > confirmation_board_states()
Definition: zobrist.hpp:165
std::array< uint32_t, NumConfKeys > confirmation_calculator_seeds_internal() const
Definition: zobrist.hpp:206
ZobristCalculator< KeyType > primary_calculator_
Definition: zobrist.hpp:144
ZobristComponent(const ZobristCalculator< KeyType > primary_calculator, const std::array< ZobristCalculator< KeyType >, NumConfKeys > &confirmation_calculators)
Constructs ZobristComponent from existing ZobristCalculator objects.
Definition: zobrist.hpp:150
void UpdateBoardStatesInternal(const ExecutedMove &executed_move)
Definition: zobrist.hpp:214
Implements the BoardStateCoordinator interface, providing a moveselection::MinimaxMoveEvaluator with ...
Definition: zobrist.hpp:416
void ImplementFullBoardStateCalc(const BoardMap_t &board_map)
Definition: zobrist.hpp:451
ZobristCoordinator(uint32_t primary_seed, std::array< uint32_t, NumConfKeys > confirmation_seeds)
Definition: zobrist.hpp:434
TranspositionTable< KeyType, NumConfKeys > tr_table_
Definition: zobrist.hpp:418
void ImplementRecordTrData(DepthType search_depth, moveselection::MinimaxResultType result_type, moveselection::EqualScoreMoves &similar_moves, MoveCountType access_index)
Definition: zobrist.hpp:455
moveselection::TranspositionTableSearchResult ImplementGetTrData(DepthType search_depth, MoveCountType access_index)
Definition: zobrist.hpp:470
TranspositionTablePruner< KeyType, NumConfKeys > tr_table_pruner_
Definition: zobrist.hpp:420
ZobristComponent< KeyType, NumConfKeys > zobrist_component_
Definition: zobrist.hpp:417
ZobristCoordinator(uint32_t prng_seed=(uint32_t) std::random_device{}())
Definition: zobrist.hpp:442
ZobristCoordinator & operator=(const ZobristCoordinator &)=delete
ZobristCoordinator(ZobristComponent< KeyType, NumConfKeys > zobrist_component)
Definition: zobrist.hpp:426
const std::string board_state_hex_str()
Definition: zobrist.hpp:488
void ImplementUpdateBoardState(const ExecutedMove &executed_move)
Definition: zobrist.hpp:447
ZobristCoordinator(const ZobristCoordinator &)=delete
TranspositionTableGuard tr_table_guard_
Definition: zobrist.hpp:419
Holds a gameboard::MoveCollection in which all gameboard::Move have the same value (as perceived by a...
Data structure that holds a moveselection::EqualScoreMoves and other search-related info obtained fro...
Container for storing a moveselection::MinimaxCalcResult retrieved by a call to boardstate::SingleZob...
Data structs used by moveselection::MinimaxEvaluator.
uint16_t DepthType
uint16_t MoveCountType
Declaration of boardstate::KeyGenerator and implementation of its template methods.
Definitions and implementations of gameboard::Move and other move-related structs.
Calculate / manage board state and associate Minimax results.
std::string IntToHexString(IntType num)
size_t GetZColorIndexOf(PieceColor color)
Definition: game_piece.hpp:77
const BoardIndexType kNumFiles
const BoardIndexType kNumRanks
array< array< GamePiece, kNumFiles >, kNumRanks > BoardMap_t
2-D array of gameboard::GamePiece objects.
const int kNumPieceTypeVals
Definition: game_piece.hpp:23
A pair of coordinate (rank, and file) with properties determined by comparison with values of gameboa...
A change in the state of a gameboard::GameBoard represented by a gameboard::Move, and each of the gam...
gameboard::GamePiece moving_piece
gameboard::GamePiece destination_piece
PieceColor piece_color
Definition: game_piece.hpp:44
gameboard::BoardSpace end
gameboard::BoardSpace start