summaryrefslogtreecommitdiff
path: root/quacker
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-08-21 15:12:03 -0400
committerpommicket <pommicket@gmail.com>2025-08-21 15:12:03 -0400
commitf7bba783ccf693ccb92c870562931ef3377852f0 (patch)
tree826dddad51b29e1ed7d475f21ecc1f0fe5bd8ea6 /quacker
parent4702e6bb96ed5f943039956224b8a5e28d862c75 (diff)
"Generated moves only" checkbox
Diffstat (limited to 'quacker')
-rw-r--r--quacker/macondo.cpp14
-rw-r--r--quacker/macondobackend.cpp60
-rw-r--r--quacker/macondobackend.h3
-rw-r--r--quacker/movebox.cpp8
-rw-r--r--quacker/quacker.cpp3
5 files changed, 61 insertions, 27 deletions
diff --git a/quacker/macondo.cpp b/quacker/macondo.cpp
index 3b301c4..d43395b 100644
--- a/quacker/macondo.cpp
+++ b/quacker/macondo.cpp
@@ -17,6 +17,7 @@ TODO:
#include <QCheckBox>
#include <QLabel>
#include <QGroupBox>
+#include <QMessageBox>
Macondo::Macondo(Quackle::Game *game) : View() {
m_game = game;
@@ -40,8 +41,8 @@ Macondo::Macondo(Quackle::Game *game) : View() {
pegBox->setLayout(pegLayout);
layout->setAlignment(Qt::AlignTop);
layout->addWidget(m_useMacondo, 0, 0);
- layout->addWidget(m_solve, 1, 0);
- layout->addWidget(pegBox, 2, 0);
+ layout->addWidget(pegBox, 1, 0);
+ layout->addWidget(m_solve, 2, 0);
connect(m_solve, SIGNAL(clicked()), this, SLOT(solve()));
}
@@ -73,14 +74,21 @@ void Macondo::solve() {
if (wasSolving) {
emit stoppedSolver();
} else {
- emit runningSolver();
if (m_tilesUnseen > 7) {
MacondoPreEndgameOptions options;
+ if (m_generatedMovesOnly->isChecked()) {
+ if (m_movesFromKibitzer.empty()) {
+ QMessageBox::critical(this, tr("Can't run pre-endgame solver"), tr("Please generate moves to analyze or uncheck 'Generated moves only'"));
+ return;
+ }
+ options.movesToAnalyze = m_movesFromKibitzer;
+ }
m_backend->solvePreEndgame(options);
} else {
MacondoEndgameOptions options;
m_backend->solveEndgame(options);
}
+ emit runningSolver();
m_isSolving = true;
}
updateSolveButton();
diff --git a/quacker/macondobackend.cpp b/quacker/macondobackend.cpp
index 20d54ba..0a4e945 100644
--- a/quacker/macondobackend.cpp
+++ b/quacker/macondobackend.cpp
@@ -120,10 +120,11 @@ void MacondoBackend::solveEndgame(const MacondoEndgameOptions &) {
m_command = Command::SolveEndgame;
}
-void MacondoBackend::solvePreEndgame(const MacondoPreEndgameOptions &) {
+void MacondoBackend::solvePreEndgame(const MacondoPreEndgameOptions &options) {
startProcess();
m_command = Command::SolvePreEndgame;
m_preEndgamePlaysToAnalyze = 0;
+ m_preEndgameOptions = options;
}
static bool parseInt(const string &s, int &value, size_t *len) {
@@ -413,6 +414,7 @@ void MacondoBackend::timer() {
data = m_process->readAllStandardOutput();
anyNewOutput |= data.size() != 0;
m_processOutput.append(data);
+ //printf("%.*s",data.size(), data.constData());
fflush(stdout);
}
const char *dots = updateDots(anyNewOutput);
@@ -531,6 +533,21 @@ void MacondoBackend::timer() {
}
}
+static string moveToString(const Quackle::Move &move) {
+ switch (move.action) {
+ case Quackle::Move::Action::Pass:
+ return "pass";
+ case Quackle::Move::Action::Exchange:
+ return std::string("exch ") + QUACKLE_ALPHABET_PARAMETERS->userVisible(move.tiles());
+ case Quackle::Move::Action::Place:
+ case Quackle::Move::Action::PlaceError:
+ return move.positionString() + " " + QUACKLE_ALPHABET_PARAMETERS->userVisible(move.tiles());
+ default:
+ // blind exchanges, etc.
+ return "";
+ }
+}
+
void MacondoBackend::processStarted() {
loadGCG();
switch (m_command) {
@@ -541,26 +558,12 @@ void MacondoBackend::processStarted() {
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;
+ string moveStr = moveToString(move);
+ if (!moveStr.empty()) {
+ commands << "add ";
+ commands << moveStr;
+ commands << "\n";
}
- commands << "\n";
}
commands << "sim\n";
@@ -569,7 +572,20 @@ void MacondoBackend::processStarted() {
}
break;
case Command::SolvePreEndgame:
- m_process->write("peg -disable-id true -early-cutoff true\n");
+ {
+ std::stringstream command;
+ command << "peg ";
+ for (const Quackle::Move &move: m_preEndgameOptions.movesToAnalyze) {
+ string moveStr = moveToString(move);
+ if (!moveStr.empty()) {
+ command << "-only-solve \"" << moveStr << "\" ";
+ }
+ }
+ command << "-disable-id true ";
+ command << "-early-cutoff true ";
+ command << "\n";
+ m_process->write(command.str().c_str());
+ }
break;
case Command::SolveEndgame:
m_process->write("endgame -plies 20\n");
@@ -615,7 +631,7 @@ void MacondoBackend::killProcess() {
m_process->kill();
// this is really unnecessary but prevents a
// "process destroyed while running" warning message
- m_process->waitForFinished(100);
+ m_process->waitForFinished(200);
delete m_process;
m_process = nullptr;
}
diff --git a/quacker/macondobackend.h b/quacker/macondobackend.h
index 3feb80d..dfc4fc9 100644
--- a/quacker/macondobackend.h
+++ b/quacker/macondobackend.h
@@ -19,6 +19,8 @@ struct MacondoEndgameOptions {
inline MacondoEndgameOptions() {}
};
struct MacondoPreEndgameOptions {
+ // if empty, we'll get Macondo to analyze all possible moves
+ Quackle::MoveList movesToAnalyze;
inline MacondoPreEndgameOptions() {}
};
@@ -66,6 +68,7 @@ private:
QByteArray m_processStderr;
Command m_command = Command::None;
Quackle::MoveList m_movesToLoad;
+ MacondoPreEndgameOptions m_preEndgameOptions;
};
#endif
diff --git a/quacker/movebox.cpp b/quacker/movebox.cpp
index 5ca9572..813fd91 100644
--- a/quacker/movebox.cpp
+++ b/quacker/movebox.cpp
@@ -175,8 +175,12 @@ void MoveBox::setMoves(const Quackle::MoveList &moves, const Quackle::Move &sele
{
if (mapIt.key() == *it)
{
- mapIt.value()->setText(WinPercentageColumn, formatWinPercentage((*it).win));
- mapIt.value()->setText(EquityColumn, formatValuation((*it).equity));
+ QTreeWidgetItem *item = mapIt.value();
+ item->setText(WinPercentageColumn, formatWinPercentage((*it).win));
+ item->setText(EquityColumn, formatValuation((*it).equity));
+ for (int column = 0; column < m_treeWidget->columnCount(); column++) {
+ item->setToolTip(column, QString::fromStdString((*it).comment));
+ }
if (resorted)
{
diff --git a/quacker/quacker.cpp b/quacker/quacker.cpp
index c15b826..cde9175 100644
--- a/quacker/quacker.cpp
+++ b/quacker/quacker.cpp
@@ -1047,6 +1047,7 @@ void TopLevel::commitTopChoice()
void TopLevel::ensureUpToDateSimulatorMoveList()
{
m_simulator->setIncludedMoves(m_game->currentPosition().moves());
+ m_macondo->clearMoves();
}
void TopLevel::simulate(bool startSimulation)
@@ -1106,6 +1107,7 @@ void TopLevel::clearSimulationResults()
return;
m_simulator->resetNumbers();
+ m_macondo->clearMoves();
updateMoveViews();
updateSimViews();
@@ -2043,6 +2045,7 @@ void TopLevel::createWidgets()
m_macondo = new Macondo(m_game);
plugIntoMatrix(m_macondo);
plugIntoPositionMatrix(m_macondo);
+ plugIntoMoveMatrix(m_macondo);
connect(m_macondo, SIGNAL(runningSolver()), this, SLOT(simulate()));
connect(m_macondo, SIGNAL(stoppedSolver()), this, SLOT(stopSimulation()));