From d68aeacdd9cb632879de345a77de80d53baf4d04 Mon Sep 17 00:00:00 2001 From: jacksona Date: Wed, 3 Jul 2019 09:31:41 -0700 Subject: [PATCH 1/2] add handicap support to the ast tree parser. --- cc/gtp_client.cc | 7 +++++-- cc/sgf.cc | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/cc/gtp_client.cc b/cc/gtp_client.cc index 6f06a7b61..d0f469dfa 100644 --- a/cc/gtp_client.cc +++ b/cc/gtp_client.cc @@ -179,11 +179,14 @@ void GtpClient::Ponder() { GtpClient::Response GtpClient::ReplaySgf( const std::vector>& trees) { + if (!trees.empty()) { + // the SGF parser takes care of transforming an sgf into moves that the + // engine is able to understand, so all we do here is just play them in. for (const auto& move : trees[0]->ExtractMainLine()) { if (!player_->PlayMove(move.c)) { - MG_LOG(ERROR) << "couldn't play move " << move.c; - return Response::Error("cannot load file"); + MG_LOG(ERROR) << "Couldn't play move " << move.c; + return Response::Error("Cannot load file"); } } } diff --git a/cc/sgf.cc b/cc/sgf.cc index d873b192a..2d4b7d995 100644 --- a/cc/sgf.cc +++ b/cc/sgf.cc @@ -210,6 +210,7 @@ bool GetTreeImpl(const Ast::Tree& tree, std::vector>* dst) { const auto* src = &tree; const Ast::Property* prop; + const Ast::Property* stones; // Extract all the nodes out of this tree. for (const auto& node : src->nodes) { @@ -219,6 +220,44 @@ bool GetTreeImpl(const Ast::Tree& tree, move.color = Color::kBlack; } else if ((prop = node.FindProperty("W")) != nullptr) { move.color = Color::kWhite; + } else if ((prop = node.FindProperty("HA")) != nullptr) { + int handicap; + bool valid_handicap = absl::SimpleAtoi(prop->values[0], &handicap); + if (!valid_handicap) { + MG_LOG(ERROR) << "Invalid handicap property: " << prop->values[0]; + break; + } + + if ((handicap <= 1) || (handicap > 9)) { + MG_LOG(ERROR) << "Invalid handicap value:" << handicap; + return false; + } + stones = node.FindProperty("AB"); + if (stones == nullptr) { + MG_LOG(ERROR) << "Handicap stones not specified."; + return false; + } + + for (const auto& h_location : stones->values) { + Move m; + m.color = Color::kBlack; + m.c = Coord::FromSgf(h_location, true); + if (m.c == Coord::kInvalid) { + MG_LOG(ERROR) << "Can't parse node " << node.ToString() << ": \"" + << h_location << "\" isn't a valid SGF coord for a handicap stone"; + return false; + } + std::string comment; + dst->push_back(absl::make_unique(m, std::move(comment))); + dst = &(dst->back()->children); + if (h_location != stones->values.back()) { + m.color = Color::kWhite; + m.c = Coord::kPass; + dst->push_back(absl::make_unique(m, std::move(comment))); + dst = &(dst->back()->children); + } + } + continue; } else { continue; } From 8582d5ce488c5f846a0f5c7fec25d89293f776aa Mon Sep 17 00:00:00 2001 From: jacksona Date: Wed, 3 Jul 2019 12:05:30 -0700 Subject: [PATCH 2/2] remove unused comment variable --- cc/sgf.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cc/sgf.cc b/cc/sgf.cc index 2d4b7d995..85df11b5e 100644 --- a/cc/sgf.cc +++ b/cc/sgf.cc @@ -247,13 +247,12 @@ bool GetTreeImpl(const Ast::Tree& tree, << h_location << "\" isn't a valid SGF coord for a handicap stone"; return false; } - std::string comment; - dst->push_back(absl::make_unique(m, std::move(comment))); + dst->push_back(absl::make_unique(m, "")); dst = &(dst->back()->children); if (h_location != stones->values.back()) { m.color = Color::kWhite; m.c = Coord::kPass; - dst->push_back(absl::make_unique(m, std::move(comment))); + dst->push_back(absl::make_unique(m, "")); dst = &(dst->back()->children); } }