From fa5be295a50b53568d5501e06926d5c5851412fc Mon Sep 17 00:00:00 2001 From: pommicket Date: Wed, 13 Aug 2025 14:26:27 -0400 Subject: Integrate Kibitzer with macondo --- quacker/macondo.cpp | 9 +++++++- quacker/macondo.h | 2 ++ quacker/macondobackend.cpp | 53 +++++++++++++++++++++++++++++++++++----------- quacker/macondobackend.h | 10 +++------ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/quacker/macondo.cpp b/quacker/macondo.cpp index 3b941e1..04e6b70 100644 --- a/quacker/macondo.cpp +++ b/quacker/macondo.cpp @@ -34,7 +34,7 @@ void Macondo::simulate() { stop(); clearMoves(); MacondoSimulateOptions options; - m_backend->simulate(options); + m_backend->simulate(options, m_movesFromKibitzer); } void Macondo::gameChanged(Quackle::Game *game) { @@ -56,3 +56,10 @@ void Macondo::gotSimMoves(const Quackle::MoveList &moves) { m_moves = moves; m_anyUpdates = true; } + +void Macondo::positionChanged(const Quackle::GamePosition *position) { + if (!m_backend->isRunning()) { + // perhaps new moves were generated + m_movesFromKibitzer = position->moves(); + } +} diff --git a/quacker/macondo.h b/quacker/macondo.h index f34117e..57f6acc 100644 --- a/quacker/macondo.h +++ b/quacker/macondo.h @@ -29,6 +29,7 @@ public: public slots: void simulate(); virtual void gameChanged(Quackle::Game *game); + virtual void positionChanged(const Quackle::GamePosition *position); private slots: void gotSimMoves(const Quackle::MoveList &moves); private: @@ -36,6 +37,7 @@ private: Quackle::Game *m_game; MacondoBackend *m_backend; Quackle::MoveList m_moves; + Quackle::MoveList m_movesFromKibitzer; int m_viewingPlyNumber = 0; bool m_anyUpdates = false; std::unique_ptr initOptions; diff --git a/quacker/macondobackend.cpp b/quacker/macondobackend.cpp index b74fcea..80a3f63 100644 --- a/quacker/macondobackend.cpp +++ b/quacker/macondobackend.cpp @@ -64,9 +64,10 @@ MacondoBackend::MacondoBackend(Quackle::Game *game, const MacondoInitOptions &op m_updateTimer->start(); } -void MacondoBackend::simulate(const MacondoSimulateOptions &) { +void MacondoBackend::simulate(const MacondoSimulateOptions &options, const Quackle::MoveList &moves) { if (m_process) return; printf("running macondo %s\n", m_execPath.c_str()); + m_movesToLoad = moves; m_process = new QProcess(this); QStringList args; m_process->start(m_execPath.c_str(), args); @@ -234,8 +235,35 @@ void MacondoBackend::processStarted() { case Command::None: throw "process started with no command"; case Command::Simulate: - m_process->write("gen\nsim\n"); - m_runningSimulation = true; + { + std::stringstream commands; + // add generated moves to Macondo + for (const Quackle::Move &move: m_movesToLoad) { + commands << "add "; + switch (move.action) { + case Quackle::Move::Action::Pass: + commands << "pass"; + break; + case Quackle::Move::Action::Exchange: + commands << "exch "; + commands << QUACKLE_ALPHABET_PARAMETERS->userVisible(move.tiles()); + break; + case Quackle::Move::Action::Place: + case Quackle::Move::Action::PlaceError: + commands << move.positionString(); + commands << " "; + commands << QUACKLE_ALPHABET_PARAMETERS->userVisible(move.prettyTiles()); + break; + default: + // ignore non-plays + break; + } + commands << "\n"; + } + commands << "sim\n"; + m_process->write(commands.str().c_str()); + m_runningSimulation = true; + } break; case Command::Solve: // TODO @@ -270,12 +298,14 @@ void MacondoBackend::loadGCG() { } void MacondoBackend::killProcess() { - // This will give an annoying "destroyed while process running" message, - // but there's no way of avoiding it while keeping this method synchronous. - // (Destroying the process while it's running does what we want anyways, - // i.e., kills it) - delete m_process; - m_process = nullptr; + if (m_process) { + m_process->kill(); + // this is really unnecessary but prevents a + // "process destroyed while running" warning message + m_process->waitForFinished(100); + delete m_process; + m_process = nullptr; + } } void MacondoBackend::processFinished(int, QProcess::ExitStatus) { @@ -290,9 +320,8 @@ void MacondoBackend::removeTempGCG() { } MacondoBackend::~MacondoBackend() { - if (m_process) { - m_process->kill(); - } + killProcess(); + removeTempGCG(); } diff --git a/quacker/macondobackend.h b/quacker/macondobackend.h index 6e5b8af..7d3c8da 100644 --- a/quacker/macondobackend.h +++ b/quacker/macondobackend.h @@ -2,12 +2,7 @@ #define MACONDO_BACKEND_H #include - -namespace Quackle { - class Game; - class Move; - class MoveList; -} +#include "game.h" class QTimer; @@ -25,7 +20,7 @@ class MacondoBackend: public QObject { Q_OBJECT public: MacondoBackend(Quackle::Game *game, const MacondoInitOptions &); - void simulate(const MacondoSimulateOptions &); + void simulate(const MacondoSimulateOptions &options, const Quackle::MoveList &moves); ~MacondoBackend(); std::string getSimResults(); inline bool isRunning() const { return m_command != Command::None; } @@ -55,6 +50,7 @@ private: Quackle::Game *m_game; QByteArray m_processOutput; Command m_command = Command::None; + Quackle::MoveList m_movesToLoad; }; #endif -- cgit v1.2.3