penguins  1.0.0
game.cc
Go to the documentation of this file.
1 #include "gui/game.hh"
2 #include "board.h"
3 #include "bot.h"
4 #include "game.h"
5 #include "gui/better_random.hh"
6 #include "gui/canvas.hh"
7 #include "gui/controllers.hh"
8 #include "gui/game_end_dialog.hh"
9 #include "gui/game_state.hh"
10 #include "gui/main.hh"
11 #include "gui/new_game_dialog.hh"
12 #include "gui/player_info_box.hh"
13 #include "penguins-version.h"
14 #include "utils.h"
15 #include <memory>
16 #include <wx/aboutdlg.h>
17 #include <wx/debug.h>
18 #include <wx/defs.h>
19 #include <wx/event.h>
20 #include <wx/font.h>
21 #include <wx/gauge.h>
22 #include <wx/gdicmn.h>
23 #include <wx/iconbndl.h>
24 #include <wx/listbox.h>
25 #include <wx/menu.h>
26 #include <wx/menuitem.h>
27 #include <wx/panel.h>
28 #include <wx/persist.h>
29 #include <wx/scrolwin.h>
30 #include <wx/sizer.h>
31 #include <wx/statbmp.h>
32 #include <wx/stattext.h>
33 #include <wx/statusbr.h>
34 #include <wx/string.h>
35 #include <wx/timer.h>
36 #include <wx/utils.h>
37 #include <wx/vector.h>
38 #include <wx/version.h>
39 #include <wx/window.h>
40 // IWYU pragma: no_include <wx/bmpbndl.h>
41 
42 GameFrame::GameFrame(wxWindow* parent, wxWindowID id) : wxFrame(parent, id, "Penguins game") {
43  this->SetIcons(wxGetApp().app_icon);
44 
45  auto menu_bar = new wxMenuBar();
46 
47  auto menu_file = new wxMenu();
48  menu_bar->Append(menu_file, "&File");
49 
50  this->menu_new_game = menu_file->Append(wxID_NEW, "&New game\tCtrl-N", "Start a new game");
51  auto on_new_game = [this](wxCommandEvent&) -> void { this->start_new_game(); };
52  this->Bind(wxEVT_MENU, on_new_game, this->menu_new_game->GetId());
53 
54  this->menu_close_game =
55  menu_file->Append(wxID_CLOSE, "&Close game\tCtrl-W", "Close the current game");
56  auto on_close_game = [this](wxCommandEvent&) -> void { this->close_game(); };
57  this->Bind(wxEVT_MENU, on_close_game, this->menu_close_game->GetId());
58 
59  menu_file->AppendSeparator();
60 
61  this->menu_exit = menu_file->Append(wxID_EXIT);
62  auto on_exit = [this](wxCommandEvent&) -> void { this->Close(true); };
63  this->Bind(wxEVT_MENU, on_exit, this->menu_exit->GetId());
64 
65  auto menu_help = new wxMenu();
66  menu_bar->Append(menu_help, "&Help");
67 
68  this->menu_about = menu_help->Append(wxID_ABOUT);
69  auto on_about = [this](wxCommandEvent&) -> void {
70  wxAboutDialogInfo info;
71  info.SetName("Penguins game");
72  info.SetVersion(PENGUINS_VERSION_STRING);
73 #if !defined(__WXOSX__)
74  info.SetIcon(wxGetApp().app_icon.GetIconOfExactSize(64));
75 #endif
76  wxAboutBox(info, this);
77  };
78  this->Bind(wxEVT_MENU, on_about, this->menu_about->GetId());
79 
80  this->SetMenuBar(menu_bar);
81 
82  this->CreateStatusBar(2);
83  int status_bar_widths[2] = { -3, -1 };
84  this->SetStatusWidths(2, status_bar_widths);
85 
86  this->progress_container = new wxWindow(this->GetStatusBar(), wxID_ANY);
87  this->progress_container->Hide();
88 
89  this->progress_bar = new wxGauge(
90  this->progress_container,
91  wxID_ANY,
92  100,
94  wxSize(200, -1),
96  );
97 
98  auto progress_hbox = new wxBoxSizer(wxHORIZONTAL);
99  progress_hbox->AddStretchSpacer(1);
100  progress_hbox->Add(this->progress_bar, wxSizerFlags(1).Centre().HorzBorder());
101  this->progress_container->SetSizer(progress_hbox);
102 
103  this->GetStatusBar()->Bind(wxEVT_SIZE, [this](wxSizeEvent& event) -> void {
104  event.Skip();
105  wxRect rect;
106  if (this->GetStatusBar()->GetFieldRect(1, rect)) {
107  // This sets both the position and the size at the same time.
108  this->progress_container->SetSize(rect);
109  }
110  });
111 
112  auto root_vbox = new wxBoxSizer(wxVERTICAL);
113  this->current_panel = new GameStartPanel(this, wxID_ANY);
114  root_vbox->Add(this->current_panel, wxSizerFlags(1).Expand());
115  this->SetSizer(root_vbox);
116  this->current_panel->update_layout();
117 }
118 
120  this->set_panel(nullptr);
121 }
122 
124  wxASSERT(this->current_panel != nullptr);
125  if (panel != nullptr) {
126  wxASSERT(this->GetSizer()->Replace(this->current_panel, panel));
127  }
128  this->current_panel->Destroy();
129  this->current_panel = panel;
130 }
131 
133  this->SetStatusText("", 0);
134  this->SetStatusText("", 1);
135  this->progress_container->Hide();
136 }
137 
139  std::unique_ptr<NewGameDialog> dialog(new NewGameDialog(this, wxID_ANY));
140  wxPersistentRegisterAndRestore(dialog.get());
141  int result = dialog->ShowModal();
142  if (result != wxID_OK) {
143  return;
144  }
145 
146  this->clear_status_bar();
147  auto panel = new GamePanel(this, wxID_ANY, dialog.get());
148  this->set_panel(panel);
149  this->current_panel->update_layout();
150  this->Update();
151  this->Centre();
152  panel->update_game_state();
153 }
154 
156  this->clear_status_bar();
157  this->set_panel(new GameStartPanel(this, wxID_ANY));
158  this->current_panel->update_layout();
159  this->Update();
160  this->Centre();
161 }
162 
164 : wxPanel(parent, id), frame(parent) {}
165 
167  this->frame->Layout();
168  this->frame->GetSizer()->SetSizeHints(this->frame);
169 }
170 
172  this->SetInitialSize(wxSize(600, 500));
173 
174  auto title_hbox = new wxBoxSizer(wxHORIZONTAL);
175 
176  auto icon_image = new wxStaticBitmap(this, wxID_ANY, wxGetApp().app_icon.GetIconOfExactSize(64));
177  title_hbox->Add(icon_image, wxSizerFlags().Centre().Border());
178 
179  auto title_label = new wxStaticText(this, wxID_ANY, "Penguins v" PENGUINS_VERSION_STRING);
180  title_label->SetFont(title_label->GetFont().MakeBold().Scale(2.0f));
181  title_hbox->Add(title_label, wxSizerFlags().Centre().Border());
182 
183  auto buttons_vbox = new wxBoxSizer(wxVERTICAL);
184 
185  auto start_game_btn = new wxButton(this, wxID_ANY, "New Game");
186  start_game_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { this->frame->start_new_game(); });
187  buttons_vbox->Add(start_game_btn, wxSizerFlags().Expand().Border());
188 
189  auto exit_btn = new wxButton(this, wxID_ANY, "Exit");
190  exit_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { this->frame->Close(true); });
191  buttons_vbox->Add(exit_btn, wxSizerFlags().Expand().Border());
192 
193  auto content_vbox = new wxBoxSizer(wxVERTICAL);
194  content_vbox->Add(title_hbox, wxSizerFlags().Centre().DoubleBorder(wxBOTTOM));
195  content_vbox->Add(buttons_vbox, wxSizerFlags().Centre().Border(wxTOP));
196 
197  auto root_vbox = new wxBoxSizer(wxVERTICAL);
198  auto root_hbox = new wxBoxSizer(wxHORIZONTAL);
199  root_hbox->Add(content_vbox, wxSizerFlags(1).Centre().Border());
200  root_vbox->Add(root_hbox, wxSizerFlags(1).Centre());
201  this->SetSizer(root_vbox);
202 
203  this->frame->menu_close_game->Enable(false);
204 
205  start_game_btn->SetFocus();
206 }
207 
209 : BaseGamePanel(parent, id) {
210  Game* game = game_new();
211  this->game.reset(game);
212  this->player_names.reserve(dialog->get_number_of_players());
213  this->player_types.reserve(dialog->get_number_of_players());
214 
215  auto bot_params = new BotParameters;
217  this->bot_params.reset(bot_params);
218 
219  game_begin_setup(game);
222  for (int i = 0; i < game->players_count; i++) {
224  this->player_names.push_back(dialog->get_player_name(i));
225  this->player_types.push_back(dialog->get_player_type(i));
226  }
227  setup_board(game, dialog->get_board_width(), dialog->get_board_height());
228  BetterRng& rng = wxGetApp().rng;
229  switch (dialog->get_board_gen_type()) {
230  case BOARD_GEN_RANDOM: generate_board_random(game, &rng); break;
231  case BOARD_GEN_ISLAND: generate_board_island(game, &rng); break;
232  case BOARD_GEN_MAX: break;
233  }
235 
236  this->progress_timer.Bind(wxEVT_TIMER, [this](wxTimerEvent&) -> void {
237  this->frame->progress_container->Show();
238  this->frame->progress_bar->Pulse();
239  });
240 
241  this->scrolled_panel = new wxScrolledWindow(this, wxID_ANY);
242  auto scroll_vbox = new wxBoxSizer(wxVERTICAL);
243  auto scroll_hbox = new wxBoxSizer(wxHORIZONTAL);
244  this->scrolled_panel->SetScrollRate(10, 10);
245  this->canvas = new CanvasPanel(this->scrolled_panel, wxID_ANY, this);
246  scroll_hbox->Add(this->canvas, wxSizerFlags(1).Centre());
247  scroll_vbox->Add(scroll_hbox, wxSizerFlags(1).Centre());
248  this->scrolled_panel->SetSizer(scroll_vbox);
249 
250  auto panel_grid = new wxFlexGridSizer(/* rows */ 2, /* cols */ 2, 0, 0);
251  panel_grid->AddGrowableCol(1);
252  panel_grid->AddGrowableRow(1);
253 
254  auto game_controls_vbox = new wxBoxSizer(wxVERTICAL);
255  this->game_controls_box = game_controls_vbox;
256 
257  this->show_current_turn_btn = new wxButton();
258  // Controls can be created in the disabled state in:
259  // GTK+MSW since v3.1.3: <https://github.com/wxWidgets/wxWidgets/pull/1060>
260  // OSX since v3.1.6: <https://github.com/wxWidgets/wxWidgets/pull/2509>
261 #if ((defined(__WXGTK__) || defined(__WXMSW__)) && wxCHECK_VERSION(3, 1, 3)) || \
262  (defined(__WXOSX__) && wxCHECK_VERSION(3, 1, 6))
264 #endif
265  this->show_current_turn_btn->Create(this, wxID_ANY, "Back to the game");
268  game_controls_vbox->Add(this->show_current_turn_btn, wxSizerFlags().Expand());
269 
270  this->exit_game_btn = new wxButton(this, wxID_ANY, "Close the game");
272  this->exit_game_btn->Hide();
273  game_controls_vbox->Add(this->exit_game_btn, wxSizerFlags().Expand());
274 
275  panel_grid->Add(game_controls_vbox, wxSizerFlags().Bottom().Expand().Border(wxALL & ~wxBOTTOM));
276 
277  int max_points = 0;
278  for (int y = 0; y < game->board_height; y++) {
279  for (int x = 0; x < game->board_width; x++) {
280  Coords coords = { x, y };
281  max_points += get_tile_fish(get_tile(game, coords));
282  }
283  }
284 
285  auto players_box = new wxBoxSizer(wxHORIZONTAL);
286  this->player_info_boxes.reserve(game->players_count);
287  for (int i = 0; i < game->players_count; i++) {
288  auto player_box = new PlayerInfoBox(this, wxID_ANY, max_points);
289  int border_dir = (i > 0 ? wxLEFT : 0) | (i + 1 < game->players_count ? wxRIGHT : 0);
290  players_box->Add(player_box->GetContainingSizer(), wxSizerFlags().Border(border_dir));
291  this->player_info_boxes.push_back(player_box);
292  }
293  panel_grid->Add(players_box, wxSizerFlags().Centre().Border(wxALL & ~wxBOTTOM));
294 
297  panel_grid->Add(this->log_list, wxSizerFlags(1).Expand().Border());
298 
299  panel_grid->Add(this->scrolled_panel, wxSizerFlags(1).Expand().Border());
300 
301  auto panel_vbox = new wxBoxSizer(wxVERTICAL);
302  panel_vbox->Add(panel_grid, wxSizerFlags(1).Expand().Border());
303  this->SetSizer(panel_vbox);
304 
305  this->frame->menu_close_game->Enable(true);
306 
307  this->update_player_info_boxes();
308  this->update_game_log();
309  this->canvas->SetFocus();
310 }
311 
313  this->SendDestroyEvent();
314  this->set_controller(nullptr);
315  this->stop_bot_progress();
316 }
317 
319  this->frame->Layout();
320  this->scrolled_panel->GetSizer()->SetSizeHints(this->scrolled_panel);
321  this->frame->GetSizer()->SetSizeHints(this->frame);
322 }
323 
325  Game* game = this->game.get();
327  this->update_game_log();
329 }
330 
332  Game* game = this->game.get();
334  if (game_check_player_index(game, game->current_player_index)) {
335  type = this->player_types.at(game->current_player_index);
336  }
337  if (game->phase == GAME_PHASE_END) {
338  return new GameEndedController(this);
339  } else if (game->phase == GAME_PHASE_PLACEMENT && type == PLAYER_NORMAL) {
340  return new PlayerPlacementController(this);
341  } else if (game->phase == GAME_PHASE_PLACEMENT && type == PLAYER_BOT) {
342  return new BotPlacementController(this);
343  } else if (game->phase == GAME_PHASE_MOVEMENT && type == PLAYER_NORMAL) {
344  return new PlayerMovementController(this);
345  } else if (game->phase == GAME_PHASE_MOVEMENT && type == PLAYER_BOT) {
346  return new BotMovementController(this);
347  } else {
348  wxFAIL_MSG("No appropriate controller for the current game state");
349  return nullptr;
350  }
351 }
352 
354  if (this->controller != nullptr) {
355  this->controller->on_deactivated(next_controller);
356  delete this->controller;
357  }
358  this->controller = next_controller;
359  if (next_controller != nullptr) {
360  next_controller->on_activated();
361  }
362 }
363 
365  // The progress_container is shown by the timer.
366  if (!this->progress_timer.IsRunning()) {
367  this->progress_timer.Start(50);
368  }
369 #ifndef __WXOSX__
370  if (!this->busy_cursor_changer) {
371  this->busy_cursor_changer.reset(new wxBusyCursor());
372  }
373 #endif
374 }
375 
377  this->frame->progress_container->Hide();
378  this->progress_timer.Stop();
379 #ifndef __WXOSX__
380  this->busy_cursor_changer.reset(nullptr);
381 #endif
382 }
383 
385  if (auto list_entry = dynamic_cast<GameLogListBoxEntry*>(event.GetClientObject())) {
386  this->set_controller(new LogEntryViewerController(this, list_entry->index));
387  }
388 }
389 
391  this->log_list->SetSelection(-1); // works more reliably than DeselectAll
393  Game* game = this->game.get();
396 }
397 
400 }
401 
403  size_t old_count = this->displayed_log_entries;
404  size_t new_count = this->game->log_length;
405  for (size_t i = old_count; i < new_count; i++) {
406  this->displayed_log_entries += 1;
407  wxString description = this->describe_game_log_entry(i);
408  if (description.IsEmpty()) continue;
409  int item_index = this->log_list->Append(description, new GameLogListBoxEntry(i));
410  this->log_list->EnsureVisible(item_index);
411  }
412 }
413 
415  Game* game = this->game.get();
416  const GameLogEntry* entry = game_get_log_entry(game, index);
417  if (entry->type == GAME_LOG_ENTRY_PHASE_CHANGE) {
418  auto entry_data = &entry->data.phase_change;
419  if (entry_data->new_phase == GAME_PHASE_SETUP_DONE) {
420  if (entry_data->old_phase == GAME_PHASE_SETUP) {
421  return "Start of the game";
422  }
423  } else if (entry_data->new_phase == GAME_PHASE_PLACEMENT) {
424  return "Placement phase";
425  } else if (entry_data->new_phase == GAME_PHASE_MOVEMENT) {
426  return "Movement phase";
427  } else if (entry_data->new_phase == GAME_PHASE_END) {
428  return "End of the game";
429  }
430  } else if (entry->type == GAME_LOG_ENTRY_PLACEMENT) {
431  auto entry_data = &entry->data.placement;
432  Coords target = entry_data->target;
433  return wxString::Format("@ (%d, %d)", target.x + 1, target.y + 1);
434  } else if (entry->type == GAME_LOG_ENTRY_MOVEMENT) {
435  auto entry_data = &entry->data.movement;
436  Coords penguin = entry_data->penguin, target = entry_data->target;
437  return wxString::Format(
438  "(%d, %d) -> (%d, %d)", penguin.x + 1, penguin.y + 1, target.x + 1, target.y + 1
439  );
440  }
441  return "";
442 }
443 
445  std::unique_ptr<GameEndDialog> dialog(
446  new GameEndDialog(this, wxID_ANY, this->game.get(), this->player_names)
447  );
448  dialog->ShowModal();
449 }
450 
452  Game* game = this->game.get();
453  for (int i = 0; i < game->players_count; i++) {
454  this->player_info_boxes.at(i)->update_data(game, i, this->player_names.at(i));
455  }
456 }
short get_tile(const Game *game, Coords coords)
Returns the value of the tile at coords. Fails if coords are outside the bounds.
Definition: board.h:108
void generate_board_random(Game *game, Rng *rng)
Generates the board by setting every tile purely randomly. The resulting board will look sort of like...
Definition: board.c:26
void generate_board_island(Game *game, Rng *rng)
Generates the board which looks sort of like a big icy island.
Definition: board.c:37
void setup_board(Game *game, int width, int height)
Sets Game::board_width and Game::board_height and allocates Game::board_grid and Game::tile_attribute...
Definition: board.c:12
Functions for working with the game board (and the specifics of its encoding)
#define get_tile_fish(tile)
Definition: board.h:27
void init_bot_parameters(BotParameters *self)
Initializes all fields of the given BotParameters to default values.
Definition: bot.c:31
The bot algorithm.
BaseGamePanel(GameFrame *parent, wxWindowID id)
Definition: game.cc:163
GameFrame * frame
Definition: game.hh:42
virtual void update_layout()
Definition: game.cc:166
Responsible for drawing the board and painting the UI overlays.
Definition: canvas.hh:17
virtual void on_deactivated(GameController *next_controller)
Definition: controllers.cc:42
virtual void on_activated()
Definition: controllers.cc:26
void set_panel(BaseGamePanel *panel)
Definition: game.cc:123
GameFrame(wxWindow *parent, wxWindowID id)
Definition: game.cc:42
virtual ~GameFrame()
Definition: game.cc:119
wxMenuItem * menu_close_game
Definition: game.hh:116
wxWindow * progress_container
Definition: game.hh:112
void clear_status_bar()
Definition: game.cc:132
wxMenuItem * menu_about
Definition: game.hh:118
wxMenuItem * menu_new_game
Definition: game.hh:115
wxGauge * progress_bar
Definition: game.hh:113
BaseGamePanel * current_panel
Definition: game.hh:110
void close_game()
Definition: game.cc:155
wxMenuItem * menu_exit
Definition: game.hh:117
void start_new_game()
Definition: game.cc:138
std::unique_ptr< wxBusyCursor > busy_cursor_changer
Definition: game.hh:90
virtual ~GamePanel()
Definition: game.cc:312
wxSizer * game_controls_box
Definition: game.hh:81
wxString describe_game_log_entry(size_t index) const
Definition: game.cc:414
void update_game_state()
Definition: game.cc:324
GamePanel(GameFrame *parent, wxWindowID id, NewGameDialog *dialog)
Definition: game.cc:208
void show_game_results()
Definition: game.cc:444
CanvasPanel * canvas
Definition: game.hh:76
wxButton * show_current_turn_btn
Definition: game.hh:82
void on_show_current_turn_clicked(wxCommandEvent &event)
Definition: game.cc:390
size_t displayed_log_entries
Definition: game.hh:86
wxVector< PlayerInfoBox * > player_info_boxes
Definition: game.hh:79
wxVector< PlayerType > player_types
Definition: game.hh:72
std::shared_ptr< BotParameters > bot_params
Definition: game.hh:70
GameController * controller
Definition: game.hh:74
wxScrolledWindow * scrolled_panel
Definition: game.hh:77
void set_controller(GameController *next_controller)
Definition: game.cc:353
std::unique_ptr< Game, decltype(&game_free)> game
Definition: game.hh:69
void start_bot_progress()
Definition: game.cc:364
wxButton * exit_game_btn
Definition: game.hh:83
void on_exit_game_clicked(wxCommandEvent &event)
Definition: game.cc:398
void update_game_log()
Definition: game.cc:402
wxVector< wxString > player_names
Definition: game.hh:71
GameController * get_controller_for_current_turn()
Definition: game.cc:331
void update_player_info_boxes()
Definition: game.cc:451
wxTimer progress_timer
Definition: game.hh:88
void stop_bot_progress()
Definition: game.cc:376
void on_game_log_select(wxCommandEvent &event)
Definition: game.cc:384
wxListBox * log_list
Definition: game.hh:85
virtual void update_layout() override
Definition: game.cc:318
GameStartPanel(GameFrame *parent, wxWindowID id)
Definition: game.cc:171
wxString get_player_name(size_t index) const
int get_board_width() const
int get_penguins_per_player() const
BoardGenType get_board_gen_type() const
int get_board_height() const
PlayerType get_player_type(size_t index) const
size_t get_number_of_players() const
void SetName(const wxString &name)
void SetIcon(const wxIcon &icon)
void SetVersion(const wxString &version, const wxString &longVersion=wxString())
bool Create(wxWindow *parent, wxWindowID id, const wxString &label=wxEmptyString, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxValidator &validator=wxDefaultValidator, const wxString &name=wxButtonNameStr)
wxClientData * GetClientObject() const
void Bind(const EventTag &eventType, Functor functor, int id=wxID_ANY, int lastId=wxID_ANY, wxObject *userData=NULL)
void CallAfter(void(T::*method)(T1,...), T1 x1,...)
virtual void SetStatusText(const wxString &text, int number=0)
void Centre(int direction=wxBOTH)
virtual void SetStatusWidths(int n, const int *widths_field)
virtual void SetMenuBar(wxMenuBar *menuBar)
virtual wxStatusBar * GetStatusBar() const
virtual wxStatusBar * CreateStatusBar(int number=1, long style=wxSTB_DEFAULT_STYLE, wxWindowID id=0, const wxString &name=wxStatusBarNameStr)
virtual void Pulse()
int Append(const wxString &item)
virtual void EnsureVisible(int n)
virtual void SetSelection(int n)
virtual void Enable(bool enable=true)
int GetId() const
void SetScrollRate(int xstep, int ystep)
wxSizerFlags & Border(int direction, int borderinpixels)
wxSizerFlags & Centre()
void SetSizeHints(wxWindow *window)
bool IsEmpty() const
wxCStrData c_str() const
static wxString Format(const wxString &format,...)
virtual void Stop()
bool IsRunning() const
virtual bool Start(int milliseconds=-1, bool oneShot=wxTIMER_CONTINUOUS)
virtual void SetIcons(const wxIconBundle &icons)
virtual bool Layout()
wxSizer * GetSizer() const
void SetSize(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)
void SetInitialSize(const wxSize &size=wxDefaultSize)
bool Disable()
bool Close(bool force=false)
void Centre(int direction=wxBOTH)
virtual void SetFocus()
virtual bool Destroy()
void SendDestroyEvent()
bool Hide()
virtual bool Show(bool show=true)
virtual void Update()
void SetSizer(wxSizer *sizer, bool deleteOld=true)
wxVERTICAL
wxHORIZONTAL
wxALL
wxBOTTOM
wxRIGHT
wxTOP
wxLEFT
wxID_NEW
wxID_ANY
wxID_CLOSE
wxID_EXIT
wxID_ABOUT
wxID_OK
void game_set_penguins_per_player(Game *self, int value)
Sets Game::penguins_per_player (the value mustn't be negative) and allocates Player::penguins lists o...
Definition: game.c:248
const GameLogEntry * game_get_log_entry(const Game *self, size_t idx)
Returns a pointer to the entry at the given index. Note that the returned pointer is const because th...
Definition: game.c:173
void game_begin_setup(Game *self)
Switches to the GAME_PHASE_SETUP phase, can only be called in GAME_PHASE_NONE. Should be called right...
Definition: game.c:209
void game_advance_state(Game *self)
The all-in-one phase switcher that progresses of the game.
Definition: game.c:329
void game_end_setup(Game *self)
Verifies that all fields have been initialized and configured and switches the phase from GAME_PHASE_...
Definition: game.c:224
void game_rewind_state_to_log_entry(Game *self, size_t target_entry)
Successively undoes or redoes log entries in order to reset the game state to the entry at the given ...
Definition: game.c:368
void game_set_player_name(Game *self, int idx, const char *name)
Sets the Player::name of a player at the given index. Only available in the GAME_PHASE_SETUP phase.
Definition: game.c:287
Game * game_new(void)
Constructs a Game. Allocates memory for storing the struct itself, setting all fields to default valu...
Definition: game.c:15
bool game_check_player_index(const Game *self, int idx)
Checks if idx is within the bounds of Game::players.
Definition: game.h:387
void game_set_players_count(Game *self, int count)
Sets Game::players_count (the value mustn't be negative) and allocates the Game::players list....
Definition: game.c:264
The core of the unified game logic library, contains the Game struct.
@ GAME_PHASE_PLACEMENT
Set by placement_begin.
Definition: game.h:59
@ GAME_PHASE_MOVEMENT
Set by movement_begin.
Definition: game.h:60
@ GAME_PHASE_SETUP
Set by game_begin_setup.
Definition: game.h:57
@ GAME_PHASE_SETUP_DONE
Set by game_end_setup, placement_end, movement_end.
Definition: game.h:58
@ GAME_PHASE_END
Set by game_end.
Definition: game.h:61
@ GAME_LOG_ENTRY_PHASE_CHANGE
See GameLogPhaseChange.
Definition: game.h:88
@ GAME_LOG_ENTRY_PLACEMENT
See GameLogPlacement.
Definition: game.h:90
@ GAME_LOG_ENTRY_MOVEMENT
See GameLogMovement.
Definition: game.h:91
@ BOARD_GEN_ISLAND
Definition: game_state.hh:7
@ BOARD_GEN_RANDOM
Definition: game_state.hh:6
@ BOARD_GEN_MAX
Definition: game_state.hh:8
PlayerType
Definition: game_state.hh:11
@ PLAYER_NORMAL
Definition: game_state.hh:12
@ PLAYER_BOT
Definition: game_state.hh:13
@ PLAYER_TYPE_MAX
Definition: game_state.hh:14
#define wxGA_HORIZONTAL
#define wxGA_SMOOTH
const wxSize wxDefaultSize
const wxPoint wxDefaultPosition
wxScrolled< wxPanel > wxScrolledWindow
wxAppDerivedClass & wxGetApp()
#define wxASSERT(condition)
#define wxFAIL_MSG(message)
void wxAboutBox(const wxAboutDialogInfo &info, wxWindow *parent=NULL)
wxEventType wxEVT_BUTTON
wxEventType wxEVT_LISTBOX
wxEventType wxEVT_MENU
wxEventType wxEVT_SIZE
bool wxPersistentRegisterAndRestore(T *obj, const wxString &name=wxString())
An implementation of Rng for C++ using the standard functions from <random>.
Various parameters for the bot algorithm.
Definition: bot.h:44
A pair of 2D coordinates, used for addressing the Game::board_grid.
Definition: utils.h:15
int x
Definition: utils.h:16
int y
Definition: utils.h:17
An entry in the Game::log_buffer, implemented as a tagged union.
Definition: game.h:156
union GameLogEntry::GameLogEntryData data
GameLogEntryType type
Definition: game.h:157
The central struct of the application, holds the game data and settings.
Definition: game.h:237
int current_player_index
A negative value means that there is no current player selected. Use game_set_current_player for sett...
Definition: game.h:256
int players_count
Use game_set_players_count for setting this.
Definition: game.h:251
wxEventType wxEVT_TIMER
GameLogMovement movement
Definition: game.h:162
GameLogPlacement placement
Definition: game.h:161
GameLogPhaseChange phase_change
Definition: game.h:159
int wxWindowID