Xiangiqgame
AI engine for Xiangqi
Loading...
Searching...
No Matches
game.cpp
Go to the documentation of this file.
1#include <chrono>
2#include <cstring>
3#include <game/game.hpp>
5#include <iostream>
6#include <memory>
8#include <sstream>
9
10namespace game {
11
13 std::shared_ptr<SpaceInfoProviderBase> game_board,
14 std::unordered_map<gameboard::PieceColor, PlayerSpec> player_specs,
15 std::unordered_map<gameboard::PieceColor, std::unique_ptr<MoveEvaluatorBase>>
16 move_evaluators,
17 std::shared_ptr<GameReporterInterface> game_reporter,
18 bool report_during_game,
19 gameboard::PieceColor whose_turn
20)
21 : game_board_{game_board}
22 , player_specs_{player_specs}
23 , move_evaluators_{std::move(move_evaluators)}
24 , game_reporter_{game_reporter}
25 , report_during_game_{report_during_game}
26 , game_state_{GameState::kUnfinished}
27 , whose_turn_{whose_turn}
28 , move_log_{}
29 , game_id_{GenerateGameID()}
30 , stop_requested_{false}
31 , stop_signal_received_{std::nullopt} {}
32
34
36 if (color == gameboard::PieceColor::kRed) {
38 } else if (color == gameboard::PieceColor::kBlk) {
40 }
41}
42
43std::string Game::GenerateGameID() {
44 auto now = std::chrono::system_clock::now();
45 auto time_now = std::chrono::system_clock::to_time_t(now);
46 auto duration = now.time_since_epoch();
47 auto musec =
48 std::chrono::duration_cast<std::chrono::microseconds>(duration).count() % 1000000;
49
50 std::ostringstream oss;
51 oss << std::put_time(std::localtime(&time_now), "%Y%m%d%H%M%S");
52 oss << std::setw(3) << std::setfill('0') << musec;
53
54 return oss.str();
55}
56
58 bool obtained_valid_move = false;
59 gameboard::Move result;
60
61 while (not obtained_valid_move) {
62 auto proposed_move = move_evaluators_.at(whose_turn_)->SelectMove(available_moves);
63 if (available_moves.ContainsMove(proposed_move)) {
64 result = proposed_move;
65 obtained_valid_move = true;
66 } else {
67 move_evaluators_.at(whose_turn_)->NotifyIllegalMove();
68 }
69 }
70
71 return result;
72}
73
74void Game::PlayerTurn(const gameboard::MoveCollection &available_moves) {
75 auto valid_move = GetValidMove(available_moves);
76 auto executed_move = game_board_->ExecuteMove(valid_move);
77 move_log_.emplace_back(executed_move);
78}
79
81
82 std::unordered_map<gameboard::PieceColor, moveselection::SearchSummaries>
83 search_summaries;
84
85 auto red_search_summaries =
86 move_evaluators_.at(gameboard::PieceColor::kRed)->search_summaries();
87 if (red_search_summaries.has_value()) {
88 search_summaries.emplace(gameboard::PieceColor::kRed, *red_search_summaries);
89 }
90
91 auto black_search_summaries =
92 move_evaluators_.at(gameboard::PieceColor::kBlk)->search_summaries();
93 if (black_search_summaries.has_value()) {
94 search_summaries.emplace(gameboard::PieceColor::kBlk, *black_search_summaries);
95 }
96
98 game_summary{game_id_, game_state_, move_log_, player_specs_, search_summaries};
99
100 return game_summary;
101}
102
103void Game::RequestStop(int signal) {
104 stop_requested_ = true;
105 stop_signal_received_ = signal;
106}
107
108std::optional<int> Game::stop_signal_received() { return stop_signal_received_; }
109
112 if (stop_requested_) {
113 break;
114 }
115
116 bool is_in_check = game_board_->IsInCheck(whose_turn_);
117 game::GameStatus cur_game_status{
119 move_log_,
121 is_in_check,
122 game_board_->map()
123 };
125 game_reporter_->ReportGameInfo(cur_game_status);
126 }
127
128 auto available_moves = game_board_->CalcFinalMovesOf(whose_turn_);
129 if (available_moves.Size() == 0) {
130 if (game_board_->IsDraw()) {
132 } else {
134 }
135 break;
136 }
137 PlayerTurn(available_moves);
139 }
140 bool is_in_check = game_board_->IsInCheck(whose_turn_);
141 game::GameStatus final_game_status{
143 move_log_,
145 is_in_check,
146 game_board_->map()
147 };
148 game_reporter_->ReportGameInfo(final_game_status);
149
150 if (stop_requested_) {
152 std::cout << "Game terminated early due to signal: " << *stop_signal_received_
153 << " (" << strsignal(*stop_signal_received_) << ")" << std::endl;
154 } else {
155 std::cout << "Game terminated early." << std::endl;
156 }
157 }
158
159 return GenerateGameSummary();
160}
161
162} // namespace game
std::unordered_map< gameboard::PieceColor, PlayerSpec > player_specs_
Definition: game.hpp:22
gameboard::Move GetValidMove(const gameboard::MoveCollection &available_moves)
Definition: game.cpp:57
GameState game_state_
Definition: game.hpp:25
std::shared_ptr< GameReporterInterface > game_reporter_
Definition: game.hpp:26
bool report_during_game_
Definition: game.hpp:29
gameboard::PieceColor whose_turn_
Definition: game.hpp:27
void PlayerTurn(const gameboard::MoveCollection &available_moves)
Definition: game.cpp:74
void SetWinner(gameboard::PieceColor color)
Definition: game.cpp:35
std::optional< int > stop_signal_received_
Definition: game.hpp:32
void ChangeWhoseTurn()
Definition: game.cpp:33
std::optional< int > stop_signal_received()
Definition: game.cpp:108
std::unordered_map< gameboard::PieceColor, std::unique_ptr< MoveEvaluatorBase > > move_evaluators_
Definition: game.hpp:24
std::atomic_bool stop_requested_
Definition: game.hpp:31
std::vector< gameboard::ExecutedMove > move_log_
Definition: game.hpp:28
std::string GenerateGameID()
Definition: game.cpp:43
std::string game_id_
Definition: game.hpp:30
GameSummary Play()
Definition: game.cpp:110
std::shared_ptr< SpaceInfoProviderBase > game_board_
Definition: game.hpp:21
void RequestStop(int signal)
Definition: game.cpp:103
Game(std::shared_ptr< SpaceInfoProviderBase > game_board, std::unordered_map< gameboard::PieceColor, PlayerSpec > player_specs, std::unordered_map< gameboard::PieceColor, std::unique_ptr< MoveEvaluatorBase > > move_evaluators, std::shared_ptr< GameReporterInterface > game_reporter, bool report_during_game=true, gameboard::PieceColor whose_turn=gameboard::PieceColor::kRed)
Definition: game.cpp:12
GameSummary GenerateGameSummary()
Definition: game.cpp:80
Definition: game.hpp:19
PieceColor opponent_of(PieceColor color)
A container for multiple gameboard::Move objects.
bool ContainsMove(const Move &move) const
A gameboard::BoardSpace pair (start and end).