1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
|
//-----------------------------------------------------------------------------
/** @file libpentobi_base/Game.h
@author Markus Enzenberger
@copyright GNU General Public License version 3 or later */
//-----------------------------------------------------------------------------
#ifndef LIBPENTOBI_BASE_GAME_H
#define LIBPENTOBI_BASE_GAME_H
#include "Board.h"
#include "BoardUpdater.h"
#include "PentobiTree.h"
namespace libpentobi_base {
//-----------------------------------------------------------------------------
class Game
{
public:
/** Determine a sensible value for the color to play at the current node.
If the color was explicitly set with a setup property, it will be
used. Otherwise, the effective color to play will be used, starting
with the next color of the color of the last move (see
Board::get_effective_to_play(Color)) */
static Color get_to_play_default(const Game& game);
explicit Game(Variant variant);
void init(Variant variant);
void init();
/** Initialize game from a SGF tree.
@note If the tree contains invalid properties, future calls to
goto_node() might throw an exception.
@param root The root node of the SGF tree; the ownership is transferred
to this class.
@throws SgfError if the root node contains invalid properties */
void init(unique_ptr<SgfNode>& root);
const Board& get_board() const;
Variant get_variant() const;
const SgfNode& get_current() const;
const SgfNode& get_root() const;
const PentobiTree& get_tree() const;
/** @param mv
@param always_create_new_node Always create a new child of the current
node even if a child with the move already exists. */
void play(ColorMove mv, bool always_create_new_node);
void play(Color c, Move mv, bool always_create_new_node);
/** Update game state to a node in the tree.
@throws SgfError if the game was constructed with an
external SGF tree and the tree contained invalid property values
(syntactically or semantically, like moves on occupied points). If an
exception is thrown, the current node is not changed. */
void goto_node(const SgfNode& node);
/** Undo the current move and go to parent node.
@pre get_tree().has_move(get_current())
@pre get_current()->has_parent()
@note Even if the implementation of this function calls goto_node(),
it cannot throw an InvalidProperty because the class Game ensures that
the current node is always reachable via a path of nodes with valid
move properties. */
void undo();
/** Set the current color to play.
Does not store a player property in the tree or affect what color is to
play when navigating away from and back to the current node. */
void set_to_play(Color c);
string get_charset() const;
void set_charset(const string& charset);
void remove_move_annotation(const SgfNode& node);
static double get_bad_move(const SgfNode& node);
static double get_good_move(const SgfNode& node);
static bool is_doubtful_move(const SgfNode& node);
static bool is_interesting_move(const SgfNode& node);
void set_bad_move(const SgfNode& node, double value = 1);
void set_good_move(const SgfNode& node, double value = 1);
void set_doubtful_move(const SgfNode& node);
void set_interesting_move(const SgfNode& node);
string get_comment() const;
void set_comment(const string& s);
/** Delete the current node and its subtree and go to the parent node.
@pre get_current().has_parent() */
void truncate();
void truncate_children();
/** Replace the game tree by a new one that has the current position
as a setup in its root node. */
void keep_only_position();
/** Like keep_only_position() but does not delete the children of the
current node. */
void keep_only_subtree();
void make_main_variation();
void move_up_variation();
void move_down_variation();
/** Delete all variations but the main variation.
If the current node is not in the main variation it will be changed
to the node as in libboardgame_base::back_to_main_variation() */
void delete_all_variations();
void set_modified(bool is_modified = true);
bool is_modified() const;
/** Set the AP property at the root node. */
void set_application(const string& name, const string& version = {});
string get_player_name(Color c) const;
void set_player_name(Color c, const string& name);
string get_date() const;
void set_date(const string& date);
void set_date_today();
/** Get event info (standard property EV) from root node. */
string get_event() const;
void set_event(const string& event);
/** Get round info (standard property RO) from root node. */
string get_round() const;
void set_round(const string& round);
/** Get time info (standard property TM) from root node. */
string get_time() const;
void set_time(const string& time);
bool has_setup() const;
void add_setup(Color c, Move mv);
void remove_setup(Color c, Move mv);
/** See libpentobi_base::Tree::set_player() */
void set_player(Color c);
/** See libpentobi_base::Tree::remove_player() */
void remove_player();
private:
const SgfNode* m_current;
unique_ptr<Board> m_bd;
PentobiTree m_tree;
BoardUpdater m_updater;
void update(const SgfNode& node);
};
inline double Game::get_bad_move(const SgfNode& node)
{
return SgfTree::get_bad_move(node);
}
inline const Board& Game::get_board() const
{
return *m_bd;
}
inline string Game::get_comment() const
{
return SgfTree::get_comment(*m_current);
}
inline string Game::get_date() const
{
return m_tree.get_date();
}
inline string Game::get_event() const
{
return m_tree.get_event();
}
inline const SgfNode& Game::get_current() const
{
return *m_current;
}
inline double Game::get_good_move(const SgfNode& node)
{
return SgfTree::get_good_move(node);
}
inline string Game::get_player_name(Color c) const
{
return m_tree.get_player_name(c);
}
inline string Game::get_round() const
{
return m_tree.get_round();
}
inline const SgfNode& Game::get_root() const
{
return m_tree.get_root();
}
inline string Game::get_time() const
{
return m_tree.get_time();
}
inline const PentobiTree& Game::get_tree() const
{
return m_tree;
}
inline bool Game::has_setup() const
{
return libpentobi_base::has_setup(*m_current);
}
inline Variant Game::get_variant() const
{
return m_bd->get_variant();
}
inline void Game::init()
{
init(m_bd->get_variant());
}
inline bool Game::is_doubtful_move(const SgfNode& node)
{
return SgfTree::is_doubtful_move(node);
}
inline bool Game::is_interesting_move(const SgfNode& node)
{
return SgfTree::is_interesting_move(node);
}
inline bool Game::is_modified() const
{
return m_tree.is_modified();
}
inline void Game::make_main_variation()
{
m_tree.make_main_variation(*m_current);
}
inline void Game::move_down_variation()
{
m_tree.move_down(*m_current);
}
inline void Game::move_up_variation()
{
m_tree.move_up(*m_current);
}
inline void Game::play(Color c, Move mv, bool always_create_new_node)
{
play(ColorMove(c, mv), always_create_new_node);
}
inline void Game::remove_move_annotation(const SgfNode& node)
{
m_tree.remove_move_annotation(node);
}
inline void Game::set_application(const string& name, const string& version)
{
m_tree.set_application(name, version);
}
inline void Game::set_bad_move(const SgfNode& node, double value)
{
m_tree.set_bad_move(node, value);
}
inline void Game::set_charset(const string& charset)
{
m_tree.set_charset(charset);
}
inline void Game::set_comment(const string& s)
{
m_tree.set_comment(*m_current, s);
}
inline void Game::set_date(const string& date)
{
m_tree.set_date(date);
}
inline void Game::set_event(const string& event)
{
m_tree.set_event(event);
}
inline void Game::set_date_today()
{
m_tree.set_date_today();
}
inline void Game::set_doubtful_move(const SgfNode& node)
{
m_tree.set_doubtful_move(node);
}
inline void Game::set_good_move(const SgfNode& node, double value)
{
m_tree.set_good_move(node, value);
}
inline void Game::set_interesting_move(const SgfNode& node)
{
m_tree.set_interesting_move(node);
}
inline void Game::set_modified(bool is_modified)
{
m_tree.set_modified(is_modified);
}
inline void Game::set_player_name(Color c, const string& name)
{
m_tree.set_player_name(c, name);
}
inline void Game::set_round(const string& round)
{
m_tree.set_round(round);
}
inline void Game::set_time(const string& time)
{
m_tree.set_time(time);
}
inline void Game::truncate_children()
{
m_tree.remove_children(*m_current);
}
//-----------------------------------------------------------------------------
} // namespace libpentobi_base
#endif // LIBPENTOBI_BASE_GAME_H
|