diff options
author | pommicket <pommicket@gmail.com> | 2025-08-21 15:12:03 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-08-21 15:12:03 -0400 |
commit | f7bba783ccf693ccb92c870562931ef3377852f0 (patch) | |
tree | 826dddad51b29e1ed7d475f21ecc1f0fe5bd8ea6 | |
parent | 4702e6bb96ed5f943039956224b8a5e28d862c75 (diff) |
"Generated moves only" checkbox
-rw-r--r-- | quacker/macondo.cpp | 14 | ||||
-rw-r--r-- | quacker/macondobackend.cpp | 60 | ||||
-rw-r--r-- | quacker/macondobackend.h | 3 | ||||
-rw-r--r-- | quacker/movebox.cpp | 8 | ||||
-rw-r--r-- | quacker/quacker.cpp | 3 |
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())); |