summaryrefslogtreecommitdiff
path: root/quacker
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-08-08 19:06:56 -0400
committerpommicket <pommicket@gmail.com>2025-08-08 19:06:56 -0400
commiteb4ac13af80fdde8d4e869d9d1fb404e29a158dc (patch)
tree96dad459bde457d381b22e8c7ae23ed24725e64a /quacker
parent4c9d6ed3024d7869c427a7f6bd2f4f61feba027d (diff)
more move extraction; not working yet
Diffstat (limited to 'quacker')
-rw-r--r--quacker/macondo.cpp8
-rw-r--r--quacker/macondo.h3
-rw-r--r--quacker/macondobackend.cpp70
-rw-r--r--quacker/macondobackend.h3
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<Quackle::Move> &)), this, SLOT(gotSimMoves(const std::vector<Quackle::Move> &)));
}
void Macondo::simulate() {
MacondoBackend::SimulateOptions options;
m_backend->simulate(options);
}
+
+void Macondo::gotSimMoves(const std::vector<Quackle::Move> &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<Quackle::Move> &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 <QTextStream>
#include <random>
+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<Quackle::Move> extractSimMoves(QByteArray &processOutput) {
+ std::vector<Quackle::Move> 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<Quackle::Move> 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<Quackle::Move> &moves);
protected slots:
void processStarted();
void processFinished(int, QProcess::ExitStatus);