diff options
author | pommicket <pommicket@gmail.com> | 2025-08-22 09:57:10 -0400 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2025-08-22 09:57:10 -0400 |
commit | 4956c4f2f7605dc7332b0e51e77a25fe88caef69 (patch) | |
tree | d62fc3982e0eef21d28c089a6ee5b95bbb132b25 /quacker | |
parent | 15fb752e8502f0b5c7e5f579dd3ff0eb8baabf3b (diff) |
Macondo max plies options
Diffstat (limited to 'quacker')
-rw-r--r-- | quacker/macondo.cpp | 45 | ||||
-rw-r--r-- | quacker/macondo.h | 8 | ||||
-rw-r--r-- | quacker/macondobackend.cpp | 25 | ||||
-rw-r--r-- | quacker/macondobackend.h | 4 |
4 files changed, 64 insertions, 18 deletions
diff --git a/quacker/macondo.cpp b/quacker/macondo.cpp index f732b32..83a197a 100644 --- a/quacker/macondo.cpp +++ b/quacker/macondo.cpp @@ -1,14 +1,13 @@ /* TODO: -- detect Macondo crashing? -- configurable max plies -- other peg/endgame options +- more peg/endgame options */ #include "macondo.h" #include "macondobackend.h" #include <QCheckBox> +#include <QCoreApplication> #include <QFileDialog> #include <QGridLayout> #include <QGroupBox> @@ -18,9 +17,19 @@ TODO: #include <QOperatingSystemVersion> #include <QPushButton> #include <QSettings> +#include <QSpinBox> #include "customqsettings.h" +// Convenience wrapper around an hbox containing a label and another widget. +class LabelLayout: public QHBoxLayout { +public: + LabelLayout(const QString &label, QWidget *widget): QHBoxLayout() { + addWidget(new QLabel(label)); + addWidget(widget); + } +}; + Macondo::Macondo(Quackle::Game *game) : View() { CustomQSettings settings; m_game = game; @@ -28,7 +37,8 @@ Macondo::Macondo(Quackle::Game *game) : View() { boldFont.setWeight(QFont::Bold); m_useMacondo = new QCheckBox(tr("Use Macondo for 'Simulate'")); m_useMacondo->setChecked(settings.value("macondo/useForSimulate", false).toBool()); - std::string execPath = settings.value("macondo/execPath", "").toString().toStdString(); + QString defaultExecPath = QCoreApplication::applicationDirPath() + "/macondo/macondo"; + std::string execPath = settings.value("macondo/execPath", defaultExecPath).toString().toStdString(); m_initOptions = std::make_unique<MacondoInitOptions>(execPath); m_backend = new MacondoBackend(game, *m_initOptions); connectBackendSignals(); @@ -40,22 +50,37 @@ Macondo::Macondo(Quackle::Game *game) : View() { connect(m_execPath, SIGNAL(editingFinished()), this, SLOT(execPathChanged())); m_solve = new QPushButton(tr("Solve")); m_solve->setDisabled(true); + + QHBoxLayout *execPathLayout = new QHBoxLayout; + execPathLayout->addWidget(execPathLabel); + execPathLayout->addWidget(m_execPath); + execPathLayout->addWidget(selectExecButton); + QGroupBox *pegBox = new QGroupBox(tr("Pre-endgame options")); QVBoxLayout *pegLayout = new QVBoxLayout; m_generatedMovesOnly = new QCheckBox(tr("Generated moves only")); m_generatedMovesOnly->setToolTip("Only analyze the moves that have been generated in the 'Choices' box."); m_generatedMovesOnly->setChecked(settings.value("macondo/generatedMovesOnly", false).toBool()); + m_preEndgameMaxPlies = new QSpinBox; + m_preEndgameMaxPlies->setRange(1, 100); + m_preEndgameMaxPlies->setValue(settings.value("macondo/preEndgameMaxPlies", 4).toInt()); pegLayout->addWidget(m_generatedMovesOnly); + pegLayout->addLayout(new LabelLayout(tr("Endgame plies"), m_preEndgameMaxPlies)); pegBox->setLayout(pegLayout); - QHBoxLayout *execPathLayout = new QHBoxLayout; - execPathLayout->addWidget(execPathLabel); - execPathLayout->addWidget(m_execPath); - execPathLayout->addWidget(selectExecButton); + + QGroupBox *endgameBox = new QGroupBox(tr("Endgame options")); + QVBoxLayout *endgameLayout = new QVBoxLayout; + endgameBox->setLayout(endgameLayout); + m_endgameMaxPlies = new QSpinBox; + m_endgameMaxPlies->setRange(1, 100); + m_endgameMaxPlies->setValue(settings.value("macondo/endgameMaxPlies", 15).toInt()); + endgameLayout->addLayout(new LabelLayout(tr("Plies"), m_endgameMaxPlies)); QVBoxLayout *layout = new QVBoxLayout(this); layout->setAlignment(Qt::AlignTop); layout->addLayout(execPathLayout); layout->addWidget(m_useMacondo); layout->addWidget(pegBox); + layout->addWidget(endgameBox); layout->addWidget(m_solve); connect(m_solve, SIGNAL(clicked()), this, SLOT(solve())); } @@ -64,6 +89,8 @@ Macondo::~Macondo() { CustomQSettings settings; settings.setValue("macondo/useForSimulate", m_useMacondo->isChecked()); settings.setValue("macondo/generatedMovesOnly", m_generatedMovesOnly->isChecked()); + settings.setValue("macondo/endgameMaxPlies", m_endgameMaxPlies->value()); + settings.setValue("macondo/preEndgameMaxPlies", m_preEndgameMaxPlies->value()); delete m_backend; } @@ -135,6 +162,7 @@ void Macondo::solve() { } else { if (m_tilesUnseen > 7) { MacondoPreEndgameOptions options; + options.endgamePlies = m_preEndgameMaxPlies->value(); if (m_generatedMovesOnly->isChecked()) { if (m_movesFromKibitzer.empty()) { QMessageBox::critical(this, @@ -148,6 +176,7 @@ void Macondo::solve() { m_backend->solvePreEndgame(options); } else { MacondoEndgameOptions options; + options.maxPlies = m_endgameMaxPlies->value(); m_backend->solveEndgame(options); } m_isSolving = true; diff --git a/quacker/macondo.h b/quacker/macondo.h index 9c85987..86d8b59 100644 --- a/quacker/macondo.h +++ b/quacker/macondo.h @@ -7,6 +7,7 @@ class QCheckBox; class QPushButton; class QLineEdit; +class QSpinBox; class MacondoBackend; struct MacondoInitOptions; class MoveBox; @@ -46,9 +47,14 @@ private: void connectBackendSignals(); bool checkExecPath(); void updateSolveButton(); + // == options == QCheckBox *m_useMacondo; - QCheckBox *m_generatedMovesOnly; QLineEdit *m_execPath; + // == endgame options == + QSpinBox *m_endgameMaxPlies; + // == pre-endgame options === + QCheckBox *m_generatedMovesOnly; + QSpinBox *m_preEndgameMaxPlies; QPushButton *m_solve; Quackle::Game *m_game; MacondoBackend *m_backend; diff --git a/quacker/macondobackend.cpp b/quacker/macondobackend.cpp index d123b95..fa3c334 100644 --- a/quacker/macondobackend.cpp +++ b/quacker/macondobackend.cpp @@ -118,16 +118,17 @@ bool MacondoBackend::simulate(const MacondoSimulateOptions &options, const Quack return true; } -void MacondoBackend::solveEndgame(const MacondoEndgameOptions &) { +void MacondoBackend::solveEndgame(const MacondoEndgameOptions &options) { + m_endgameOptions = options; startProcess(); m_command = Command::SolveEndgame; } void MacondoBackend::solvePreEndgame(const MacondoPreEndgameOptions &options) { - startProcess(); - m_command = Command::SolvePreEndgame; m_preEndgamePlaysToAnalyze = 0; m_preEndgameOptions = options; + startProcess(); + m_command = Command::SolvePreEndgame; } static bool parseInt(const string &s, int &value, size_t *len) { @@ -473,12 +474,11 @@ void MacondoBackend::timer() { i += preEndgameProgressMarker.length(); m_processStderr = QByteArray(m_processStderr.constData() + i, m_processStderr.size() - i); string numPlaysStr(m_processStderr.constData(), std::min(32, m_processStderr.size())); - int numPlays = 0; - parseInt(numPlaysStr, numPlays, nullptr); - std::stringstream message; - message << "Analyzed " << numPlays << "/" << m_preEndgamePlaysToAnalyze << " plays" << dots; - emit statusMessage(QString::fromStdString(message.str())); + parseInt(numPlaysStr, m_preEndgamePlaysAnalyzed, nullptr); } + std::stringstream message; + message << "Analyzed " << m_preEndgamePlaysAnalyzed << "/" << m_preEndgamePlaysToAnalyze << " plays" << dots; + emit statusMessage(QString::fromStdString(message.str())); } else { // no progress yet emit statusMessage(QString("Solving pre-endgame") + dots); @@ -584,6 +584,7 @@ void MacondoBackend::processStarted() { command << "-only-solve \"" << moveStr << "\" "; } } + command << "-endgameplies " << m_preEndgameOptions.endgamePlies << " "; command << "-disable-id true "; command << "-early-cutoff true "; command << "\n"; @@ -591,7 +592,13 @@ void MacondoBackend::processStarted() { } break; case Command::SolveEndgame: - m_process->write("endgame -plies 20\n"); + { + std::stringstream command; + command << "endgame "; + command << "-plies " << m_endgameOptions.maxPlies << " "; + command << "\n"; + m_process->write(command.str().c_str()); + } break; } } diff --git a/quacker/macondobackend.h b/quacker/macondobackend.h index c8bcfdf..8af328f 100644 --- a/quacker/macondobackend.h +++ b/quacker/macondobackend.h @@ -17,10 +17,12 @@ struct MacondoSimulateOptions { }; struct MacondoEndgameOptions { inline MacondoEndgameOptions() {} + int maxPlies = 15; }; struct MacondoPreEndgameOptions { // if empty, we'll get Macondo to analyze all possible moves Quackle::MoveList movesToAnalyze; + int endgamePlies = 4; inline MacondoPreEndgameOptions() {} }; @@ -64,6 +66,7 @@ private: QTimer *m_updateTimer = nullptr; int m_solveStatusDots = 3; int m_preEndgamePlaysToAnalyze = 0; + int m_preEndgamePlaysAnalyzed = 0; // is simulation being run right now? (i.e. has process been started & game been loaded?) bool m_runningSimulation = false; Quackle::Game *m_game; @@ -72,6 +75,7 @@ private: Command m_command = Command::None; Quackle::MoveList m_movesToLoad; MacondoPreEndgameOptions m_preEndgameOptions; + MacondoEndgameOptions m_endgameOptions; }; #endif |