penguins  1.0.0
bot_thread.cc
Go to the documentation of this file.
1 #include "gui/bot_thread.hh"
2 #include "bot.h"
3 #include "gui/controllers.hh"
4 #include "movement.h"
5 #include "placement.h"
6 #include "utils.h"
7 #include <wx/debug.h>
8 #include <wx/thread.h>
9 
11  wxMutexLocker lock(this->mutex);
12  while (!this->exited) {
13  wxCondError code WX_ATTRIBUTE_UNUSED = this->condvar.Wait();
14  wxASSERT(code == wxCOND_NO_ERROR);
15  }
16 }
17 
19  wxMutexLocker lock(this->mutex);
20  wxASSERT(!this->exited);
21  this->exited = true;
22  this->condvar.Broadcast();
23 }
24 
26 : wxThread(wxTHREAD_DETACHED), controller(controller), bot_params(controller->bot_params) {
27  this->game.reset(game_clone(controller->game));
28  this->bot_state.reset(bot_state_new(this->bot_params.get(), this->game.get(), &this->rng));
29  this->cancelled_ptr = &this->bot_state->cancelled;
30 }
31 
33  this->cancelled_ptr = nullptr;
34 }
35 
37  *this->cancelled_ptr = true;
38 }
39 
41  // The thread is unregistered in the OnExit method instead of the destructor
42  // so as to not accidentally use a half-destroyed object. And also because
43  // joinable threads don't destruct themselves automatically.
44  this->controller->unregister_bot_thread(this);
45  this->shared->notify_exit();
46 }
47 
49  this->SetName("bot-placement");
50  Coords target;
51  bool ok = bot_compute_placement(this->bot_state.get(), &target);
52  bool cancelled = this->bot_state->cancelled;
53  auto controller = this->controller;
54  auto shared = this->shared;
55  controller->CallAfter([=]() -> void {
56  shared->wait_for_exit();
57  if (!cancelled && ok) place_penguin(controller->game, target);
59  });
60  return 0;
61 }
62 
64  this->SetName("bot-movement");
65  Coords penguin, target;
66  bool ok = bot_compute_move(this->bot_state.get(), &penguin, &target);
67  bool cancelled = this->bot_state->cancelled;
68  auto controller = this->controller;
69  auto shared = this->shared;
70  controller->CallAfter([=]() -> void {
71  shared->wait_for_exit();
72  if (!cancelled && ok) move_penguin(controller->game, penguin, target);
74  });
75  return 0;
76 }
bool bot_compute_placement(BotState *self, Coords *out_target)
Computes the best placement for the current player given the current game state.
Definition: bot.c:143
BotState * bot_state_new(const BotParameters *params, Game *game, Rng *rng)
Constructs a BotState (similarly game_new).
Definition: bot.c:42
bool bot_compute_move(BotState *self, Coords *out_penguin, Coords *out_target)
Computes the best move for the current player given the current game state.
Definition: bot.c:295
The bot algorithm.
virtual ExitCode Entry() override
Definition: bot_thread.cc:63
virtual ExitCode Entry() override
Definition: bot_thread.cc:48
void wait_for_exit()
Definition: bot_thread.cc:10
void notify_exit()
Definition: bot_thread.cc:18
wxCondition condvar
Definition: bot_thread.hh:26
bool SetName(const wxString &WXUNUSED(name))
Definition: bot_thread.hh:44
BotTurnController * controller
Definition: bot_thread.hh:49
virtual void OnExit() override
Definition: bot_thread.cc:40
std::shared_ptr< BotParameters > bot_params
Definition: bot_thread.hh:51
std::unique_ptr< BotState, decltype(&bot_state_free)> bot_state
Definition: bot_thread.hh:52
void cancel()
Definition: bot_thread.cc:36
std::shared_ptr< BotThreadShared > shared
Definition: bot_thread.hh:37
std::unique_ptr< Game, decltype(&game_free)> game
Definition: bot_thread.hh:50
volatile bool * cancelled_ptr
Definition: bot_thread.hh:54
BotThread(BotTurnController *controller)
Definition: bot_thread.cc:25
virtual ~BotThread()
Definition: bot_thread.cc:32
void unregister_bot_thread(BotThread *thread)
Definition: controllers.cc:134
void on_bot_thread_done_work(bool cancelled)
Definition: controllers.cc:93
wxCondError Wait()
wxCondError Broadcast()
void CallAfter(void(T::*method)(T1,...), T1 x1,...)
void * ExitCode
Game * game_clone(const Game *other)
Creates a (deep) copy of another Game.
Definition: game.c:36
#define wxASSERT(condition)
wxTHREAD_DETACHED
wxCondError
wxCOND_NO_ERROR
void move_penguin(Game *game, Coords start, Coords target)
Creates a GameLogMovement entry. The requested move must be valid.
Definition: movement.c:118
Movement phase functions.
void place_penguin(Game *game, Coords target)
Creates a GameLogPlacement entry. The requested placement must be valid.
Definition: placement.c:93
Placement phase functions.
A pair of 2D coordinates, used for addressing the Game::board_grid.
Definition: utils.h:15