Xiangiqgame
AI engine for Xiangqi
Loading...
Searching...
No Matches
bindings.cpp
Go to the documentation of this file.
1
4
5#include <pybind11/chrono.h>
6#include <pybind11/pybind11.h>
7#include <pybind11/stl.h>
8
16#include <game/game.hpp>
18#include <game/game_runner.hpp>
29#include <random>
30#include <string>
32
33namespace py = pybind11;
34using namespace py::literals;
35using namespace boardstate;
36using namespace gameboard;
37using namespace piecepoints;
38
39template <typename KeyType, size_t NumConfKeys>
40void bind_minimax_move_evaluator(py::module_ &m, const std::string &class_name) {
44 PiecePositionPoints>>(m, class_name.c_str())
45 .def(
46 py::init<PieceColor, int, GameBoard &>(),
47 "evaluating_player"_a,
48 "search_depth"_a,
49 "game_board"_a
50 )
51 .def(
52 py::init<PieceColor, int, GameBoard &, uint32_t>(),
53 "evaluating_player"_a,
54 "search_depth"_a,
55 "game_board"_a,
56 "zkeys_seed"_a
57 )
58 .def(
59 "select_move",
63 PiecePositionPoints>::SelectMove,
64 "allowed_moves"_a
65 )
66 .def_property_readonly(
67 "search_summaries",
71 PiecePositionPoints>::search_summaries
72 )
73 .def(
74 "search_depth",
78 PiecePositionPoints>::search_depth
79 )
80 .def(
81 "zobrist_key_size_bits",
85 PiecePositionPoints>::KeySizeBits
86 )
87 .def_property_readonly(
88 "zkeys_seed",
92 PiecePositionPoints>::zkeys_seed
93 )
94 .def_property_readonly(
95 "board_state_hex_str",
99 PiecePositionPoints>::board_state_hex_str
100 );
101}
102
103PYBIND11_MODULE(xiangqi_bindings, m) {
104 py::enum_<game::GameState>(m, "GameState")
105 .value("kUnfinished", game::kUnfinished)
106 .value("kDraw", game::kDraw)
107 .value("kRedWon", game::kRedWon)
108 .value("kBlkWon", game::kBlkWon);
109
110 py::enum_<game::EvaluatorType>(m, "EvaluatorType")
111 .value("kRandom", game::kRandom)
112 .value("kMinimax", game::kMinimax)
113 .value("kHuman", game::kHuman);
114
115 py::class_<game::PlayerSpec>(m, "PlayerSpec")
116 .def(
117 py::init<PieceColor, game::EvaluatorType, size_t, size_t, DepthType, uint32_t>(
118 ),
119 py::arg("color"),
120 py::arg("evaluator_type"),
121 py::arg("zobrist_key_size_bits"),
122 py::arg("zobrist_calculator_count"),
123 py::arg("minimax_search_depth"),
124 py::arg("zkeys_seed")
125 )
126 .def_readonly("color", &game::PlayerSpec::color)
127 .def_readonly("evaluator_type", &game::PlayerSpec::evaluator_type)
128 .def_readonly("zobrist_key_size_bits", &game::PlayerSpec::zobrist_key_size_bits)
129 .def_readonly(
130 "zobrist_calculator_count",
132 )
133 .def_readonly("minimax_search_depth", &game::PlayerSpec::minimax_search_depth)
134 .def_readonly("zkeys_seed", &game::PlayerSpec::zkeys_seed);
135
136 py::class_<game::GameSummary>(m, "GameSummary")
137 .def_readonly("game_id", &game::GameSummary::game_id)
138 .def_readonly("game_state", &game::GameSummary::game_state)
139 .def_readonly("move_log", &game::GameSummary::move_log)
140 .def_readonly("player_specs", &game::GameSummary::player_specs)
141 .def_readonly("search_summaries", &game::GameSummary::search_summaries);
142
143 py::class_<game::GameRunner>(m, "GameRunner")
144 .def(
145 py::init<game::PlayerSpec, game::PlayerSpec>(),
146 "red_player_spec"_a,
147 "black_player_spec"_a
148 )
149 .def("run_game", &game::GameRunner::RunGame)
150 .def_property_readonly("red_player_spec", &game::GameRunner::red_player_spec)
151 .def_property_readonly("black_player_spec", &game::GameRunner::black_player_spec);
152
153 // Define key types and their corresponding names as a tuple
154 const std::tuple<std::string, size_t> key_types[] = {
155 {"uint32_t", sizeof(uint32_t)},
156 {"uint64_t", sizeof(uint64_t)},
157 {"__uint128_t", sizeof(__uint128_t)}
158 };
159
160 py::class_<PiecePositionPoints>(m, "PiecePositionPoints").def(py::init<>());
161
162 py::class_<moveselection::PreSearchMoveSorter<GameBoard, PiecePositionPoints>>(
163 m,
164 "PreSearchMoveSorter"
165 )
166 .def(
167 py::init<GameBoard &, PiecePositionPoints &>(),
168 "game_board"_a,
169 "game_position_points"_a
170 );
171
172 py::class_<BoardSpace>(m, "BoardSpace")
173 .def(py::init<int, int>(), "rank"_a, "file"_a)
174 .def_readonly("rank", &BoardSpace::rank)
175 .def_readonly("file", &BoardSpace::file);
176
177 py::class_<GamePiece>(m, "GamePiece")
178 .def(py::init<>())
179 .def(py::init<int>(), "int_piece"_a)
180 .def(py::init<PieceType, PieceColor>(), "piece_type"_a, "piece_color"_a)
181 .def_readonly("piece_type", &GamePiece::piece_type)
182 .def_readonly("piece_color", &GamePiece::piece_color);
183
184 py::class_<Move>(m, "Move")
185 .def(py::init<BoardSpace, BoardSpace>(), "start"_a, "end"_a)
186 .def_readonly("start", &Move::start)
187 .def_readonly("end", &Move::end);
188
189 py::class_<MoveCollection>(m, "MoveCollection")
190 .def_readonly("moves", &MoveCollection::moves)
191 .def("size", &MoveCollection::Size)
192 .def("ContainsMove", &MoveCollection::ContainsMove);
193
194 py::class_<moveselection::EqualScoreMoves>(m, "EqualScoreMoves")
195 .def_readonly("shared_score", &moveselection::EqualScoreMoves::shared_score)
196 .def_property_readonly(
197 "move_collection",
199 );
200
201 py::class_<ExecutedMove>(m, "ExecutedMove")
202 .def(
203 py::init<Move, int, int>(),
204 "spaces"_a,
205 "moving_piece"_a,
206 "destination_piece"_a
207 )
208 .def_readonly("spaces", &ExecutedMove::spaces)
209 .def_readonly("moving_piece", &ExecutedMove::moving_piece)
210 .def_readonly("destination_piece", &ExecutedMove::destination_piece);
211
212 py::enum_<PieceColor>(m, "PieceColor")
213 .value("kRed", kRed)
214 .value("kNul", kNul)
215 .value("kBlk", kBlk)
216 .export_values();
217
218 py::enum_<PieceType>(m, "PieceType")
219 .value("kNnn", kNnn)
220 .value("kGen", kGen)
221 .value("kAdv", kAdv)
222 .value("kEle", kEle)
223 .value("kHor", kHor)
224 .value("kCha", kCha)
225 .value("kCan", kCan)
226 .value("kSol", kSol)
227 .export_values();
228
229 m.def("size_of_points_type", &size_of_points_type);
230 m.def("is_signed_points_type", &is_signed_points_type);
231
232 py::enum_<moveselection::MinimaxResultType>(m, "MinimaxResultType")
233 .value("Unknown", moveselection::kUnknown)
234 .value("TrTableHit", moveselection::kTrTableHit)
235 // .value("TrTableHitEvaluatorLoses", kTrTableHitEvaluatorLoses)
236 // .value("TrTableHitEvaluatorWins", kTrTableHitEvaluatorWins)
237 .value("EvaluatorLoses", moveselection::kEvaluatorLoses)
238 .value("EvaluatorWins", moveselection::kEvaluatorWins)
239 .value("Draw", moveselection::kDraw)
240 .value("FullyEvaluatedNode", moveselection::kFullyEvaluatedNode)
241 .value("StandardLeaf", moveselection::kStandardLeaf)
242 .value("AlphaPrune", moveselection::kAlphaPrune)
243 .value("BetaPrune", moveselection::kBetaPrune)
244 .export_values();
245
246 py::class_<GameBoard>(m, "GameBoard")
247 .def(py::init<>())
248 .def("map", &GameBoard::map)
249 .def("ExecuteMove", &GameBoard::ExecuteMove, "move"_a)
250 .def("UndoMove", &GameBoard::UndoMove, "executed_move"_a)
251 .def("GetAllSpacesOccupiedBy", &GameBoard::GetAllSpacesOccupiedBy, "color"_a)
252 .def("CalcFinalMovesOf", &GameBoard::CalcFinalMovesOf, "color"_a)
253 .def("IsInCheck", &GameBoard::IsInCheck, "color"_a)
254 .def("GetType", &GameBoard::GetType, "space"_a)
255 .def_property_readonly("move_log", &GameBoard::move_log)
256 .def_property_readonly("is_draw", &GameBoard::IsDraw)
257 .def("GetColor", &GameBoard::GetColor, "space"_a);
258
259 m.def("opponent_of", &opponent_of);
260
261 py::class_<moveselection::RandomMoveEvaluator<GameBoard>>(m, "RandomMoveEvaluator")
262 .def(py::init<PieceColor, GameBoard &>(), "evaluating_player"_a, "game_board"_a)
263 .def(
264 "select_move",
266 "allowed_moves"_a
267 );
268
269 py::class_<moveselection::SearchSummary>(m, "SearchSummary")
270 .def_property_readonly(
271 "num_nodes",
273 ) // Read-only access to fields
274 .def_property_readonly("time", &moveselection::SearchSummary::time)
275 .def(
276 "get_result_depth_counts",
278 )
279 .def(
280 "get_transposition_table_hits",
282 )
283 .def_property_readonly(
284 "equal_score_moves",
286 )
287 .def_property_readonly(
288 "selected_move",
290 )
291 .def_property_readonly(
292 "returned_illegal_move",
294 )
295 .def_property_readonly(
296 "num_collisions",
298 )
299 .def_property_readonly(
300 "tr_table_size_initial",
302 )
303 .def_property_readonly(
304 "tr_table_size_final",
306 );
307
308 py::class_<moveselection::SearchSummaries>(m, "SearchSummaries")
309 .def(py::init<>()) // Constructor, as needed for initialization
310 .def_readonly(
311 "first_searches",
313 ) // Read-only vectors and maps
314 .def_readonly("extra_searches", &moveselection::SearchSummaries::extra_searches);
315
316 py::class_<TranspositionTableGuard>(m, "TranspositionTableGuard").def(py::init<>());
317
318 // Evaluators without dependency injection (except GameBoard)
319 bind_minimax_move_evaluator<uint32_t, 0>(m, "MinimaxMoveEvaluator32");
320 bind_minimax_move_evaluator<uint64_t, 0>(m, "MinimaxMoveEvaluator64");
321 bind_minimax_move_evaluator<__uint128_t, 0>(m, "MinimaxMoveEvaluator128");
322 bind_minimax_move_evaluator<uint32_t, 1>(m, "MinimaxMoveEvaluator32Dual");
323 bind_minimax_move_evaluator<uint64_t, 1>(m, "MinimaxMoveEvaluator64Dual");
324 bind_minimax_move_evaluator<__uint128_t, 1>(m, "MinimaxMoveEvaluator128Dual");
325}
Definitions of classes used for storing piece points in Base Points Offset form.
void bind_minimax_move_evaluator(py::module_ &m, const std::string &class_name)
Definition: bindings.cpp:40
PYBIND11_MODULE(xiangqi_bindings, m)
Definition: bindings.cpp:103
Constants, typedefs, and simple structs used by gameboard::GameBoard.
Implements the BoardStateCoordinator interface, providing a moveselection::MinimaxMoveEvaluator with ...
Definition: zobrist.hpp:416
GameSummary RunGame()
Definition: game_runner.hpp:25
const game::PlayerSpec & red_player_spec()
Definition: game_runner.hpp:42
const game::PlayerSpec & black_player_spec()
Definition: game_runner.hpp:43
Implements SpaceInfoProvider interface; stores piece positions, and exposes methods for calculating,...
Definition: game_board.hpp:25
const std::map< PieceColor, vector< ExecutedMove > > & move_log() const
Definition: gameboard.cpp:143
bool IsInCheck(PieceColor color)
Definition: gameboard.cpp:90
const BoardMap_t & map() const
Definition: gameboard.cpp:132
Implements MoveEvaluator interface, and selects move::Move using Minimax algorithm; uses SpaceInfoPro...
Implements gameboard::MoveEvaluator interface.
ResultDepthCountsData_t GetResultDepthCounts()
ResultDepthCountsData_t GetTranspositionTableHits()
std::chrono::duration< double, std::nano > time()
Definition of gameboard::GameBoard class.
Definitions of concrete classes that implement the MoveEvaluator interface.
Calculate / manage board state and associate Minimax results.
Tracking piece positions and determining legal moves.
PieceColor opponent_of(PieceColor color)
Providing position-dependent values of pieces to objects in moveselection namespace.
Definition of piecepoints::PiecePositionPoints.
std::unordered_map< gameboard::PieceColor, moveselection::SearchSummaries > search_summaries
game::GameState game_state
std::vector< ExecutedMove > move_log
std::unordered_map< gameboard::PieceColor, PlayerSpec > player_specs
EvaluatorType evaluator_type
DepthType minimax_search_depth
gameboard::PieceColor color
gameboard::GamePiece moving_piece
gameboard::GamePiece destination_piece
PieceColor piece_color
Definition: game_piece.hpp:44
bool ContainsMove(const Move &move) const
gameboard::BoardSpace end
gameboard::BoardSpace start
std::map< MoveCountType, SearchSummary > extra_searches
std::vector< SearchSummary > first_searches
Holds a piecepoints::GamePointsArray_t of points values, and exposes a method for accessing element c...
Contains implementaion of BoardStateTracker interface as a boardstate::ZobristTracker and supporting ...