summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--quacker/macondo.cpp45
-rw-r--r--quacker/macondo.h8
-rw-r--r--quacker/macondobackend.cpp25
-rw-r--r--quacker/macondobackend.h4
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