Skip to content

Commit

Permalink
#35, towards #29, go bowls and lids etc wip
Browse files Browse the repository at this point in the history
  • Loading branch information
popojan committed Dec 3, 2021
1 parent 0ca9073 commit b25206c
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 170 deletions.
5 changes: 0 additions & 5 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion data/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"path": "./engine/katago",
"command": "katago",
"parameters": "gtp -model ./engine/katago/models/g170-b20c256x2-s4384473088-d968438914.bin.gz -config ./engine/katago/default_gtp.cfg",
"enabled": 0,
"enabled": 1,
"kibitz": 1,
"messages": [
{
"regex": "^:\\s+T.*--\\s*([A-Z0-9]+)",
Expand Down
2 changes: 1 addition & 1 deletion data/gui/goban.rml
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@
<div class="grp">
<div class="hr">Game</div>
<div class="cmd" id="cmdPass" onmouseup="play pass">Pass</div>
<div class="cmd" onmouseup="play once">Play once</div>
<div class="hr">Move</div>
<div class="cmd" onmouseup="play once">Kibitz move</div>
<div class="cmd" onmouseup="undo move">Undo</div>
</div>
</div>
Expand Down
328 changes: 216 additions & 112 deletions data/shaders/fragment.glsl

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/Board.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Move {

public:

enum Special { INVALID, INTERRUPT, NORMAL, PASS, UNDO, RESIGN };
enum Special { INVALID, INTERRUPT, NORMAL, PASS, UNDO, RESIGN, KIBITZED};

Move(): spec(INVALID), col(Color::EMPTY) {}

Expand All @@ -93,7 +93,7 @@ class Move {
: spec(NORMAL), pos(pos), col(col)
{ }

operator bool() const { return spec != INVALID && spec != INTERRUPT; }
operator bool() const { return spec != INVALID && spec != INTERRUPT && spec != KIBITZED; }
operator Position() const { return pos; }
operator Color() const { return col; }

Expand Down Expand Up @@ -221,6 +221,10 @@ class Board
void setRandomStoneRotation() {
randomStoneRotation = 3.1415f * udist(generator);
}

double getRandomStoneRotation() {
return 3.1415f * udist(generator);
}
private:

inline int ord(const Position& p) const {
Expand Down
8 changes: 7 additions & 1 deletion src/ElementGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ void ElementGame::OnUpdate()
}


std::string cmd(isOver ? "New" : !isRunning ? "Play" : "Pass");
std::string cmd(isOver ? "Clear" : !isRunning ? "Start" : "Pass");
model.state.cmd = cmd;
if (view.state.cmd != model.state.cmd) {
Rocket::Core::Element* cmdPass = context->GetDocument("game_window")->GetElementById("cmdPass");
Expand Down Expand Up @@ -217,6 +217,12 @@ void ElementGame::OnUpdate()
view.state.capturedWhite = model.state.capturedWhite;
view.state.reason = model.state.reason;
}
if(view.state.reservoirBlack != model.state.reservoirBlack
|| view.state.reservoirWhite != model.state.reservoirWhite) {
view.state.reservoirBlack = model.state.reservoirBlack;
view.state.reservoirWhite = model.state.reservoirWhite;
requestRepaint();
}
if (view.state.handicap != model.state.handicap) {
Rocket::Core::Element* hand = context->GetDocument("game_window")->GetElementById("lblHandicap");
if (hand != NULL) {
Expand Down
2 changes: 2 additions & 0 deletions src/GameState.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class GameState {
std::string black;
std::string white;
int capturedBlack, capturedWhite;
int reservoirBlack, reservoirWhite;
float komi;
int handicap;
float result;
Expand All @@ -24,6 +25,7 @@ class GameState {
Message msg;

GameState(): colorToMove(Color::BLACK), black(""), white(""), capturedBlack(0), capturedWhite(0),
reservoirBlack(32), reservoirWhite(32),
komi(0.5f), handicap(0), result(0.0f), cmd("xxx"), msg(PAUSED),
reason(NOREASON), adata(), metricsReady(false), showTerritory(false), showOverlay(false),
holdsStone(false), dirty(true)
Expand Down
50 changes: 46 additions & 4 deletions src/GameThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

GameThread::GameThread(GobanModel &m) :
model(m), thread(nullptr), interruptRequested(false), hasThreadRunning(false),
playerToMove(0), human(0), sgf(0), coach(0), numPlayers(0), activePlayer({0, 0})
playerToMove(0), human(0), sgf(0), coach(0), kibitz(0), numPlayers(0), activePlayer({0, 0})
{

}
Expand Down Expand Up @@ -41,6 +41,14 @@ Engine* GameThread::currentCoach() {
}
return 0;
}

Engine* GameThread::currentKibitz() {
for(auto eit = engines.begin(); eit != engines.end(); ++eit) {
if((*eit)->hasRole(Player::KIBITZ)) return *eit;
}
return 0;
}

Player* GameThread::currentPlayer() {
int roleToMove = model.state.colorToMove == Color::BLACK ? Player::BLACK : Player::WHITE;
for(auto pit = players.begin(); pit != players.end(); ++pit) {
Expand Down Expand Up @@ -222,11 +230,13 @@ void GameThread::gameLoop() {
interruptRequested = false;
while (model && !interruptRequested) {
Engine* coach = currentCoach();
Engine* kibitz = currentKibitz();
Player* player = currentPlayer();
std::unique_lock<std::mutex> lock(playerMutex, std::defer_lock);
bool locked = false;
if(coach && player && !interruptRequested) {
bool success = false;
bool kibitzed = false;
bool doubleUndo = false;
playerToMove = player;
if(!player->isTypeOf(Player::HUMAN)){
Expand All @@ -237,6 +247,10 @@ void GameThread::gameLoop() {
player->suggestMove(Move(Move::INVALID, model.state.colorToMove));
//blocking wait for move
Move move = player->genmove(model.state.colorToMove);
if(move == Move::KIBITZED) {
move = kibitz->genmove(model.state.colorToMove);
kibitzed = true;
}
spdlog::debug("MOVE to {}, valid = {}", move.toString(), move);
playerToMove = 0;
if(player->isTypeOf(Player::HUMAN)){
Expand All @@ -262,6 +276,7 @@ void GameThread::gameLoop() {
else if (move) {
// coach plays
success = player == coach
|| (kibitzed && kibitz == coach)
|| move == Move::RESIGN
|| coach->play(move);
}
Expand All @@ -270,7 +285,7 @@ void GameThread::gameLoop() {
if (!(move == Move::RESIGN)) {
for (auto pit = players.begin(); pit != players.end(); ++pit) {
Player *p = *pit;
if (p != reinterpret_cast<Player *>(coach) && p != player) {
if (p != reinterpret_cast<Player *>(coach) && p != player && (!kibitzed || p != kibitz)) {
spdlog::debug("DEBUG play iter");
if (move == Move::UNDO) {
undo(p, doubleUndo);
Expand Down Expand Up @@ -328,10 +343,17 @@ void GameThread::playLocalMove(const Move& move) {
if(playerToMove) playerToMove->suggestMove(move);
}

void GameThread::playKibitzMove() {
std::unique_lock<std::mutex> lock(playerMutex);
Move kibitzed(Move::KIBITZED, model.state.colorToMove);
if(playerToMove) playerToMove->suggestMove(kibitzed);
}

void GameThread::loadEngines(const std::shared_ptr<Configuration> config) {
auto bots = config->data.find("bots");
if(bots != config->data.end()) {
bool hasCoach(false);
bool hasKibitz(false);
for(auto it = bots->begin(); it != bots->end(); ++it) {
auto enabled = it->value("enabled", 1);
if(enabled) {
Expand All @@ -340,6 +362,7 @@ void GameThread::loadEngines(const std::shared_ptr<Configuration> config) {
auto command = it->value("command", "");
auto parameters = it->value("parameters", "");
auto main = it->value("main", 0);
auto kibitz = it->value("kibitz", 0);
auto messages = it->value("messages", nlohmann::json::array());

int role = Player::SPECTATOR;
Expand Down Expand Up @@ -367,13 +390,32 @@ void GameThread::loadEngines(const std::shared_ptr<Configuration> config) {
players[coach]->getName());
}
}

if (kibitz) {
if(!hasKibitz) {
role |= Player::KIBITZ;
hasKibitz = true;
kibitz = id;
spdlog::info("Setting [{}] engine as trusted kibitz.",
players[id]->getName());
} else {
spdlog::warn("Ignoring kibitz flag for [{}] engine, kibitz has already been set to [{}].",
players[id]->getName(),
players[coach]->getName());
}
}
setRole(id, role, true);
}
}
}
if(!hasKibitz) {
kibitz = coach;
spdlog::info("No kibitz set. Defaulting to [{}] coach engine.",
players[kibitz]->getName());
players[coach]->setRole(players[coach]->getRole() | Player::KIBITZ);
}
}
sgf = -1; //addPlayer(new SgfPlayer("SGF Record", "./problems/alphago-2016/3/13/Tictactoe.sgf"));

sgf = -1;

human = addPlayer(new LocalHumanPlayer("Human"));

Expand Down
4 changes: 3 additions & 1 deletion src/GameThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class GameThread
size_t addPlayer(Player* player);

Engine* currentCoach();
Engine* currentKibitz();

Player* currentPlayer();

Expand All @@ -52,6 +53,7 @@ class GameThread
bool humanToMove();

void playLocalMove(const Move& move);
void playKibitzMove();

void loadEngines(const std::shared_ptr<Configuration> config);

Expand Down Expand Up @@ -82,7 +84,7 @@ class GameThread
std::mutex mutex2;
volatile bool interruptRequested, hasThreadRunning;
Player* playerToMove;
std::size_t human, sgf, coach;
std::size_t human, sgf, coach, kibitz;
std::size_t numPlayers;
std::array<std::size_t, 2> activePlayer;
std::mutex playerMutex;
Expand Down
8 changes: 8 additions & 0 deletions src/GobanControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ void GobanControl::mouseClick(int button, int state, int x, int y) {
}
else {
model.state.holdsStone = true;
if(model.state.colorToMove == Color::BLACK)
model.state.reservoirBlack -= 1;
else
model.state.reservoirWhite -= 1;
view.requestRepaint(GobanView::UPDATE_STONES);
}
}
Expand Down Expand Up @@ -102,6 +106,10 @@ bool GobanControl::command(const std::string& cmd) {
view.toggleOverlay();
view.requestRepaint();
}
else if (cmd == "play once") {
engine.playKibitzMove();
view.requestRepaint();
}
else if (cmd == "play pass") {
bool playNow = !firstGame;
if (model.isGameOver()) {
Expand Down
Loading

0 comments on commit b25206c

Please sign in to comment.