Xiangiqgame
AI engine for Xiangqi
Loading...
Searching...
No Matches
game_board_for_concepts.hpp
Go to the documentation of this file.
1#pragma once
2
6#include <functional>
7#include <map>
8#include <memory>
11
12namespace gameboard {
13
15extern const int kRepeatPeriodsToCheck[3];
16extern const int kRepeatPeriodsMaxAllowed;
17extern const int kMaxMovesWithoutCapture;
18
21
25 vector<function<void(const ExecutedMove &)>> move_callbacks_;
26 std::map<PieceColor, std::vector<ExecutedMove>> move_log_;
28
29public:
30 static std::shared_ptr<GameBoardForConcepts> Create(
31 const BoardMapInt_t &starting_board = kStandardInitialBoard
32 ) {
33 return std::shared_ptr<GameBoardForConcepts>(new GameBoardForConcepts(starting_board)
34 );
35 }
36
37 inline const BoardMap_t &map() const { return board_map_; }
38
39 inline const std::map<PieceColor, std::vector<ExecutedMove>> &move_log() const {
40 return move_log_;
41 }
42
43 void AttachMoveCallback(const function<void(const ExecutedMove &)> &callback) {
44 move_callbacks_.emplace_back(callback);
45 }
46
47 inline PieceColor GetColor(const BoardSpace &space) const {
48 return board_map_[space.rank][space.file].piece_color;
49 }
50
51 bool IsInCheck(PieceColor color) { return IsInCheckInternal(color); }
52
53 ExecutedMove ExecuteMove(const Move &move) { return ExecuteMoveInternal(move); }
54
56
57 inline std::vector<BoardSpace> GetAllSpacesOccupiedBy(const PieceColor color) const {
59 }
60
61 inline PieceType GetType(const BoardSpace &space) const {
62 return board_map_[space.rank][space.file].piece_type;
63 }
64
66 return CalcFinalMovesOfInternal(color);
67 }
68
69 inline bool IsCaptureMove(const ExecutedMove &executed_move) const {
70 return executed_move.destination_piece != PieceColor::kNul;
71 }
72
73 void UndoMove(const ExecutedMove &executed_move) {
74 return UndoMoveInternal(executed_move);
75 }
76
77 inline GamePiece GetOccupantAt(const BoardSpace &space) const {
78 return board_map_[space.rank][space.file];
79 }
80
81private:
84 GameBoardForConcepts(const BoardMapInt_t starting_board)
85 : board_map_{int_board_to_game_pieces(starting_board)}
88 , move_callbacks_{} {}
89
91
92 // initialize MoveCollection where we will store allowed moves
93 MoveCollection validated_moves{};
94
95 // if board meets "draw" condition, no moves allowed, so return empty collection
96 if (IsDraw()) {
97 return validated_moves;
98 }
99
100 auto un_tested_moves = move_calculator_.CalcAllMovesNoCheckTest(color, board_map_);
101
102 validated_moves.moves.reserve(un_tested_moves.moves.size());
103
104 for (auto move : un_tested_moves.moves) {
105 auto executed_move = ExecuteMove(move);
106 auto resulting_opponent_moves =
108 auto resulting_gen_position = get_general_position(board_map_, color);
109
110 if (not resulting_opponent_moves.ContainsDestination(resulting_gen_position) and
111 not ViolatesRepeatRule(color)) {
112 validated_moves.Append(move);
113 }
114
115 UndoMove(executed_move);
116 }
117 return validated_moves;
118 }
119
121 auto gen_position = get_general_position(board_map_, color);
122 auto opponent_moves =
124 return opponent_moves.ContainsDestination(gen_position);
125 }
126
128 auto moving_piece = GetOccupantAt(move.start);
129 auto destination_piece = GetOccupantAt(move.end);
130 SetOccupantAt(move.end, moving_piece);
132
133 auto executed_move =
134 ExecutedMove{move, moving_piece, destination_piece, moves_since_last_capture_};
135 UpdateStateTracker(executed_move);
136 AddToMoveLog(executed_move);
137 if (!IsCaptureMove(executed_move)) {
139 } else {
141 }
142
143 return executed_move;
144 }
145
146 inline std::vector<BoardSpace> GetAllSpacesOccupiedByInternal(const PieceColor color
147 ) const {
148 vector<BoardSpace> occupied_spaces;
149 occupied_spaces.reserve(16);
150 for (auto rank = 0; rank < kNumRanks; rank++) {
151 for (auto file = 0; file < kNumFiles; file++) {
152 if (GetColor(BoardSpace{rank, file}) == color) {
153 occupied_spaces.emplace_back(BoardSpace{rank, file});
154 }
155 }
156 }
157 return occupied_spaces;
158 }
159
160 void UndoMoveInternal(const ExecutedMove &executed_move) {
161 SetOccupantAt(executed_move.spaces.start, executed_move.moving_piece);
162 SetOccupantAt(executed_move.spaces.end, executed_move.destination_piece);
163 UpdateStateTracker(executed_move);
165 RemoveFromMoveLog(executed_move);
166 };
167
168 void UpdateStateTracker(const ExecutedMove &executed_move) {
169
170 for (const auto &callback : move_callbacks_) {
171 callback(executed_move);
172 }
173 }
174
175 void SetOccupantAt(const BoardSpace &space, GamePiece piece) {
176 board_map_[space.rank][space.file] = piece;
177 }
178
179 void AddToMoveLog(const ExecutedMove &executed_move) {
180 auto piece_color = executed_move.moving_piece.piece_color;
181 move_log_[piece_color].push_back(executed_move);
182 }
183
184 void RemoveFromMoveLog(const ExecutedMove &executed_move) {
185 auto piece_color = executed_move.moving_piece.piece_color;
186 auto last_move_by_color = move_log_[piece_color].back();
187 if (!(executed_move == last_move_by_color)) {
188 throw runtime_error("Last move in log does not match move to be removed");
189 }
190 move_log_[piece_color].pop_back();
191 }
192
194 for (auto period_length : kRepeatPeriodsToCheck) {
195 auto lookback_length = (kRepeatPeriodsMaxAllowed + 1) * period_length;
197 move_log_[color],
198 lookback_length,
199 period_length
200 )) {
201 return true;
202 }
203 }
204 return false;
205 }
206};
207
209public:
210 std::shared_ptr<GameBoardForConcepts> Create(
211 const BoardMapInt_t &starting_board = kStandardInitialBoard
212 ) {
213 return GameBoardForConcepts::Create(starting_board);
214 }
215
216
217};
218
219
220
221} // namespace gameboard
Constants, typedefs, and simple structs used by gameboard::GameBoard.
std::shared_ptr< GameBoardForConcepts > Create(const BoardMapInt_t &starting_board=kStandardInitialBoard)
Must comply with SpaceInfoProviderConcept; stores piece positions, and exposes methods for calculatin...
MoveCollection CalcFinalMovesOf(PieceColor color)
ExecutedMove ExecuteMove(const Move &move)
GamePiece GetOccupantAt(const BoardSpace &space) const
std::vector< BoardSpace > GetAllSpacesOccupiedBy(const PieceColor color) const
std::map< PieceColor, std::vector< ExecutedMove > > move_log_
PieceColor GetColor(const BoardSpace &space) const
MoveCollection CalcFinalMovesOfInternal(PieceColor color)
void AddToMoveLog(const ExecutedMove &executed_move)
GameBoardForConcepts(const BoardMapInt_t starting_board)
Initializes a gameboard::GameBoard from array of pieces represented as integers.
std::vector< BoardSpace > GetAllSpacesOccupiedByInternal(const PieceColor color) const
void SetOccupantAt(const BoardSpace &space, GamePiece piece)
void UpdateStateTracker(const ExecutedMove &executed_move)
ExecutedMove ExecuteMoveInternal(const Move &move)
void AttachMoveCallback(const function< void(const ExecutedMove &)> &callback)
vector< function< void(const ExecutedMove &)> > move_callbacks_
void RemoveFromMoveLog(const ExecutedMove &executed_move)
PieceType GetType(const BoardSpace &space) const
const std::map< PieceColor, std::vector< ExecutedMove > > & move_log() const
void UndoMove(const ExecutedMove &executed_move)
void UndoMoveInternal(const ExecutedMove &executed_move)
bool IsCaptureMove(const ExecutedMove &executed_move) const
static std::shared_ptr< GameBoardForConcepts > Create(const BoardMapInt_t &starting_board=kStandardInitialBoard)
Calculates legal gameboard::Move objects for of a gameboard::GameBoard with a particular state.
MoveCollection CalcAllMovesNoCheckTest(PieceColor color, const BoardMap_t &board_map)
uint16_t MoveCountType
Definition of gameboard::MoveCalculator.
Definitions and implementations of gameboard::Move and other move-related structs.
Tracking piece positions and determining legal moves.
const BoardMapInt_t kStandardInitialBoard
Starting board represented as 2-D array of integers.
BoardSpace get_general_position(const BoardMap_t &board_map, const PieceColor color)
array< array< int, kNumFiles >, kNumRanks > BoardMapInt_t
2-D array of integers; can be converted to gameboard::BoardMap_t using gameboard::int_board_to_game_p...
const BoardIndexType kNumFiles
const BoardIndexType kNumRanks
PieceColor opponent_of(PieceColor color)
BoardMap_t int_board_to_game_pieces(const BoardMapInt_t int_board)
array< array< GamePiece, kNumFiles >, kNumRanks > BoardMap_t
2-D array of gameboard::GamePiece objects.
const int kRepeatPeriodsToCheck[3]
Max allowed repetitions of prohibited move sequence lengths.
const int kMaxMovesWithoutCapture
const int kRepeatPeriodsMaxAllowed
Repeated move sequence lengths forbidden under move repetition rules.
bool hasRepeatingPattern(const std::vector< T > &vec, int lookback_length, int period)
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
MoveCountType moves_since_last_capture
gameboard::GamePiece destination_piece
A Xiangqi game piece described by its gameboard::PieceType and its gameboard::PieceColor.
Definition: game_piece.hpp:42
PieceColor piece_color
Definition: game_piece.hpp:44
A container for multiple gameboard::Move objects.
bool ContainsDestination(const gameboard::BoardSpace &space)
A gameboard::BoardSpace pair (start and end).
gameboard::BoardSpace end
gameboard::BoardSpace start