From eb4ac13af80fdde8d4e869d9d1fb404e29a158dc Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 8 Aug 2025 19:06:56 -0400 Subject: more move extraction; not working yet --- quacker/macondo.cpp | 8 ++++++ quacker/macondo.h | 3 ++ quacker/macondobackend.cpp | 70 ++++++++++++++++++++++++++++++++++++---------- quacker/macondobackend.h | 3 ++ 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/quacker/macondo.cpp b/quacker/macondo.cpp index cb65110..8c53beb 100644 --- a/quacker/macondo.cpp +++ b/quacker/macondo.cpp @@ -17,9 +17,17 @@ Macondo::Macondo(Quackle::Game *game) : QWidget() { MacondoBackend::InitOptions initOptions(execPath); m_backend = new MacondoBackend(game, initOptions); connect(m_simulateButton, SIGNAL(clicked()), this, SLOT(simulate())); + connect(m_backend, SIGNAL(gotSimMoves(const std::vector &)), this, SLOT(gotSimMoves(const std::vector &))); } void Macondo::simulate() { MacondoBackend::SimulateOptions options; m_backend->simulate(options); } + +void Macondo::gotSimMoves(const std::vector &moves) { + printf("got %zu moves\n",moves.size()); + for (const Quackle::Move &move: moves) { + std::cout << move << std::endl; + } +} diff --git a/quacker/macondo.h b/quacker/macondo.h index d8b2eb1..82505d5 100644 --- a/quacker/macondo.h +++ b/quacker/macondo.h @@ -7,6 +7,7 @@ class QPushButton; class QTimer; namespace Quackle { class Game; + class Move; } class MacondoBackend; @@ -16,6 +17,8 @@ public: Macondo(Quackle::Game *); public slots: void simulate(); +private slots: + void gotSimMoves(const std::vector &moves); private: enum class Command { None, diff --git a/quacker/macondobackend.cpp b/quacker/macondobackend.cpp index 83fddad..26bf0cd 100644 --- a/quacker/macondobackend.cpp +++ b/quacker/macondobackend.cpp @@ -1,3 +1,4 @@ +#include "datamanager.h" #include "macondobackend.h" #include "quackleio/gcgio.h" #include "game.h" @@ -8,6 +9,8 @@ #include #include +using std::string; + static int getPlyNumber(const Quackle::GamePosition &position) { int playerIndex = 0, numPlayers = position.players().size(); for (const Quackle::Player &player: position.players()) { @@ -44,6 +47,56 @@ void MacondoBackend::simulate(const SimulateOptions &) { m_command = Command::Simulate; } +static string trimLeft(const string &s) { + int i; + for (i = 0; strchr(" \t\r\n", s[i]); i++); + return s.substr(i); +} + +static Quackle::Move extractSimMove(const string &s) { + string play = trimLeft(s); + if (play.find("(exch ") == 0) { + // exchange + } else if (strchr("123456789ABCDEFGHIJKLMNO", play[0])) { + // normal play + size_t space = play.find(" "); + if (space == string::npos) + throw "no space after placement"; + string placement = play.substr(0, space); + play = trimLeft(play.substr(space)); + space = play.find(" "); + if (space == string::npos) + throw "no space after move description"; + string description = play.substr(0, space); + Quackle::Move move = Quackle::Move::createPlaceMove(placement, "A"); + move.setPrettyTiles(QUACKLE_ALPHABET_PARAMETERS->encode(description.c_str())); + return move; + } + throw "bad syntax"; +} + +static std::vector extractSimMoves(QByteArray &processOutput) { + std::vector moves; + QByteArray playsStartIdentifier("Play Leave Score Win% Equity"); + QByteArray playsEndIdentifier("Iterations:"); + int start = processOutput.indexOf(playsStartIdentifier) + playsStartIdentifier.length(); + if (start < 0) return moves; + int end = processOutput.indexOf(playsEndIdentifier, start); + if (end < 0) return moves; + string plays(processOutput.constData() + start, end - start); + processOutput.remove(0, end); + plays = trimLeft(plays); + for (size_t i = 0, next; (next = plays.find("\n", i)) != string::npos; i = next + 1) { + string play = plays.substr(i, next - i); + try { + moves.push_back(extractSimMove(play)); + } catch (const char *s) { + fprintf(stderr, "WARNING: unrecognized play: %s (%s)\n", play.c_str(), s); + } + } + return moves; +} + void MacondoBackend::timer() { if (m_process) { QByteArray data = m_process->readAllStandardError(); @@ -60,20 +113,9 @@ void MacondoBackend::timer() { m_process->write("sim show\n"); } { - QByteArray playsStartIdentifier("Play Leave Score Win% Equity"); - QByteArray playsEndIdentifier("Iterations:"); - int start = m_processOutput.indexOf(playsStartIdentifier) + playsStartIdentifier.length(); - if (start < 0) return; - // trim whitespace before plays - while (start < m_processOutput.length() - && strchr(" \r\n", m_processOutput[start])) { - start++; - } - int end = m_processOutput.indexOf(playsEndIdentifier, start); - if (end < 0) return; - std::string plays(m_processOutput.constData() + start, end - start); - m_processOutput.remove(0, end); - printf("%s\n",plays.c_str()); + std::vector moves = extractSimMoves(m_processOutput); + if (!moves.empty()) + emit gotSimMoves(moves); } break; case Command::Solve: diff --git a/quacker/macondobackend.h b/quacker/macondobackend.h index c8e07fa..188533a 100644 --- a/quacker/macondobackend.h +++ b/quacker/macondobackend.h @@ -5,6 +5,7 @@ namespace Quackle { class Game; + class Move; } class QTimer; @@ -25,6 +26,8 @@ public: void simulate(const SimulateOptions &); ~MacondoBackend(); std::string getSimResults(); +signals: + void gotSimMoves(const std::vector &moves); protected slots: void processStarted(); void processFinished(int, QProcess::ExitStatus); -- cgit v1.2.3