summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2013-07-12 13:45:53 +0000
committerStijn Buys <ingar@osirion.org>2013-07-12 13:45:53 +0000
commit1ee4d49f99e7925b9ac19aadc944007bd4320389 (patch)
tree5491f9d071edb09f1991e942511392fff0faa53d
parenta613c9476b4a6f2aa4c9eaf3a2f0dd131594f373 (diff)
Removes sidebar buttons,
adds current filename to the window title, adds a Move -> Guess option to the menu bar, adds messageboxes to the Step, Guess and Validate actions.
-rw-r--r--src/mainwindow.cc54
-rw-r--r--src/mainwindow.h12
-rw-r--r--src/solverwindow.cc165
-rw-r--r--src/solverwindow.h32
-rw-r--r--src/sudokuwidget.cc36
-rw-r--r--src/sudokuwidget.h2
6 files changed, 216 insertions, 85 deletions
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index b929aaa..4f252d3 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -27,17 +27,17 @@ void MainWindow::initActions()
action_load = new QAction(tr("&Load..."), this);
action_load->setShortcuts(QKeySequence::Open);
action_load->setStatusTip(tr("Load a previously saved game"));
- connect(action_load, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(load()));
+ connect(action_load, SIGNAL(triggered()), this, SLOT(doLoad()));
// Game -> Save
action_save = new QAction(tr("&Save"), this);
action_load->setStatusTip(tr("Save the current game"));
- //TODO
+ connect(action_save, SIGNAL(triggered()), this, SLOT(doSave()));
// Game -> Save As
action_saveas = new QAction(tr("Save &As..."), this);
action_load->setStatusTip(tr("Save the current game to a new file"));
- connect(action_saveas, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(saveas()));
+ connect(action_saveas, SIGNAL(triggered()), this, SLOT(doSaveAs()));
// Game -> Revert
action_revert = new QAction(tr("&Revert"), this);
@@ -60,6 +60,11 @@ void MainWindow::initActions()
action_step->setStatusTip(tr("Solve a single cell"));
connect(action_step, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(step()));
+ // Move -> Step
+ action_guess = new QAction(tr("Guess"), this);
+ action_guess->setStatusTip(tr("Solve a single cell with guessing"));
+ connect(action_guess, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(guess()));
+
// Move -> Solve
action_solve = new QAction(tr("Solve rules"), this);
action_solve->setStatusTip(tr("Solve sudoku rules"));
@@ -69,6 +74,11 @@ void MainWindow::initActions()
action_search = new QAction(tr("Find solution"), this);
action_search->setStatusTip(tr("Find a solution"));
connect(action_search, SIGNAL(triggered()), mainwindow_solverwindow, SLOT(search()));
+
+ // Move -> Validate
+ action_validate = new QAction(tr("Validate"), this);
+ action_validate ->setStatusTip(tr("Validate the sudoku"));
+ connect(action_validate, SIGNAL(triggered()), this, SLOT(doValidate()));
}
void MainWindow::initMenus()
@@ -77,7 +87,7 @@ void MainWindow::initMenus()
mainwindow_gamemenu->addAction(action_new);
mainwindow_gamemenu->addAction(action_load);
mainwindow_gamemenu->addSeparator();
- //mainwindow_gamemenu->addAction(action_save);
+ mainwindow_gamemenu->addAction(action_save);
mainwindow_gamemenu->addAction(action_saveas);
mainwindow_gamemenu->addAction(action_revert);
mainwindow_gamemenu->addSeparator();
@@ -86,7 +96,43 @@ void MainWindow::initMenus()
mainwindow_movemenu = menuBar()->addMenu(tr("&Move"));
//mainwindow_movemenu->addAction(action_hint);
mainwindow_movemenu->addAction(action_step);
+ mainwindow_movemenu->addAction(action_guess);
+ mainwindow_movemenu->addSeparator();
mainwindow_movemenu->addAction(action_solve);
mainwindow_movemenu->addAction(action_search);
+ mainwindow_movemenu->addSeparator();
+ mainwindow_movemenu->addAction(action_validate);
+}
+
+void MainWindow::updateTitle()
+{
+ if (mainwindow_solverwindow->filename().isEmpty()) {
+ setWindowTitle("Sudoku");
+ } else {
+ setWindowTitle(mainwindow_solverwindow->filename() + " - Sudoku");
+ }
+}
+
+void MainWindow::doSave()
+{
+ mainwindow_solverwindow->save();
+ updateTitle();
}
+void MainWindow::doSaveAs()
+{
+ mainwindow_solverwindow->saveas();
+ updateTitle();
+}
+
+void MainWindow::doLoad()
+{
+ mainwindow_solverwindow->load();
+ updateTitle();
+}
+
+void MainWindow::doValidate()
+{
+ mainwindow_solverwindow->validate();
+}
+ \ No newline at end of file
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 2467f25..13283fe 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -22,6 +22,8 @@ private:
void initMenus();
+ void updateTitle();
+
SolverWindow *mainwindow_solverwindow;
QMenu *mainwindow_gamemenu;
QMenu *mainwindow_movemenu;
@@ -37,8 +39,18 @@ private:
// Move menu actions
QAction *action_hint;
QAction *action_step;
+ QAction *action_guess;
QAction *action_solve;
QAction *action_search;
+ QAction *action_validate;
+
+private slots:
+
+ void doSave();
+ void doSaveAs();
+ void doLoad();
+
+ void doValidate();
};
diff --git a/src/solverwindow.cc b/src/solverwindow.cc
index 9947d5d..bad0791 100644
--- a/src/solverwindow.cc
+++ b/src/solverwindow.cc
@@ -14,6 +14,7 @@
* FIXME
* On windows, this results in a rather awkward directory.
* The homepath should probably be a setting.
+ * This should move to mainwindow
* */
const QString HOMEDIR(QDir::homePath() + "/.sudoku");
@@ -21,63 +22,7 @@ const QString HOMEDIR(QDir::homePath() + "/.sudoku");
SolverWindow::SolverWindow()
{
QHBoxLayout *windowlayout = new QHBoxLayout();
-
-
- // sidebar
- QVBoxLayout *sidebarlayout = new QVBoxLayout();
-
- // add stretch
- sidebarlayout->addStretch(1);
-
- // add load button
- QPushButton *loadbutton = new QPushButton(tr("Load"));
- sidebarlayout->addWidget(loadbutton);
- connect(loadbutton, SIGNAL(clicked()), this, SLOT(load()));
-
- // add save button
- QPushButton *savebutton = new QPushButton(tr("Save"));
- sidebarlayout->addWidget(savebutton);
- connect(savebutton, SIGNAL(clicked()), this, SLOT(saveas()));
-
- // add revert button
- QPushButton *revertbutton = new QPushButton(tr("Revert"));
- sidebarlayout->addWidget(revertbutton);
- connect(revertbutton, SIGNAL(clicked()), this, SLOT(revert()));
- // add validate button
- QPushButton *validatebutton = new QPushButton(tr("Validate"));
- sidebarlayout->addWidget(validatebutton);
- connect(validatebutton, SIGNAL(clicked()), this, SLOT(validate()));
-
- // add a step button
- QPushButton *stepbutton = new QPushButton(tr("Step"));
- sidebarlayout->addWidget(stepbutton);
- connect(stepbutton, SIGNAL(clicked()), this, SLOT(step()));
-
- // add stretch
- sidebarlayout->addStretch(2);
-
- // add a solve button
- QPushButton *solvebutton = new QPushButton(tr("Solve"));
- sidebarlayout->addWidget(solvebutton);
- connect(solvebutton, SIGNAL(clicked()), this, SLOT(solve()));
-
- // add a search button
- QPushButton *searchbutton = new QPushButton(tr("Search"));
- sidebarlayout->addWidget(searchbutton);
- connect(searchbutton, SIGNAL(clicked()), this, SLOT(search()));
-
- // add clear button
- QPushButton *clearbutton = new QPushButton(tr("Clear"));
- sidebarlayout->addWidget(clearbutton);
- connect(clearbutton, SIGNAL(clicked()), this, SLOT(clear()));
-
- // add stretch
- sidebarlayout->addStretch(1);
-
- // add sidebar layout
- windowlayout->addLayout(sidebarlayout);
-
// sudoku widget
solverwindow_sudokuwidget = new SudokuWidget();
windowlayout->addWidget(solverwindow_sudokuwidget, 1);
@@ -86,20 +31,17 @@ SolverWindow::SolverWindow()
setLayout(windowlayout);
// create home directory
+ // FIXME this should move to mainwindow
QDir directory;
if (!directory.exists(HOMEDIR)) {
directory.mkdir(HOMEDIR);
}
}
-void SolverWindow::load()
+void SolverWindow::loadFromFile(const QString & filename)
{
- QString filename = QFileDialog::getOpenFileName(this, tr("Open..."), HOMEDIR, "Sudoku (*.sudoku)");
- if (filename.isEmpty()) {
- return;
- }
-
QFile file(filename);
+
if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Open file"),
tr("Could not open file %1:\n%2.")
@@ -125,22 +67,14 @@ void SolverWindow::load()
file.close();
+ solverwindow_filename = filename;
+
QApplication::restoreOverrideCursor();
}
-void SolverWindow::revert()
-{
- // FIXME this should actually re-load the savegame
- solverwindow_sudokuwidget->set_values(solverwindow_revertstate);
-}
-void SolverWindow::saveas()
+void SolverWindow::saveToFile(const QString & filename)
{
- QString filename = QFileDialog::getSaveFileName(this, tr("Save as..."), HOMEDIR, "Sudoku (*.sudoku)");
- if (filename.isEmpty()) {
- return;
- }
-
QFile file(filename);
if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Save file"),
@@ -149,7 +83,7 @@ void SolverWindow::saveas()
.arg(file.errorString()));
return;
}
-
+
QApplication::setOverrideCursor(Qt::WaitCursor);
QTextStream textstream(&file);
@@ -176,8 +110,48 @@ void SolverWindow::saveas()
file.close();
+ solverwindow_filename = filename;
+
QApplication::restoreOverrideCursor();
+}
+
+void SolverWindow::load()
+{
+ QString filename = QFileDialog::getOpenFileName(this, tr("Open..."), HOMEDIR, "Sudoku (*.sudoku)");
+
+ if (!filename.isEmpty()) {
+ loadFromFile(filename);
+ }
+
+ return;
+}
+
+void SolverWindow::revert()
+{
+ if (!solverwindow_filename.isEmpty()) {
+ loadFromFile(solverwindow_filename);
+ }
+}
+
+void SolverWindow::save()
+{
+ if (solverwindow_filename.isEmpty()) {
+ saveas();
+ } else {
+ saveToFile(solverwindow_filename);
+ }
+ return;
+}
+
+void SolverWindow::saveas()
+{
+ QString filename = QFileDialog::getSaveFileName(this, tr("Save as..."), HOMEDIR, "Sudoku (*.sudoku)");
+ if (!filename.isEmpty()) {
+ solverwindow_filename = filename;
+ saveToFile(solverwindow_filename);
+ }
+
return;
}
@@ -195,7 +169,37 @@ void SolverWindow::step()
Sudoku solution(sudoku);
int solved = solution.solve_rules();
if (solved == 0) {
- qDebug() << "no solveable cells left!";
+ QMessageBox::warning(this, tr("Step"), tr("No cells to solve found"));
+ return;
+ }
+
+ // compare sudoku and solution values
+ int index_start = (int) random() % 81;
+ int index_current = index_start;
+ do {
+ int column = index_current % 9;
+ int row = (index_current - column) / 9;
+ if ((sudoku.cell(row,column).value() == 0) && (solution.cell(row,column).value() != 0)) {
+ sudoku.cell(row,column).set_value(solution.cell(row, column).value());
+ solverwindow_sudokuwidget->set_values(sudoku);
+ return;
+ }
+
+ index_current = (index_current + 1) % 81;
+
+ } while (index_current != index_start);
+
+}
+
+void SolverWindow::guess()
+{
+ Sudoku sudoku;
+ solverwindow_sudokuwidget->get_values(sudoku);
+
+ Sudoku solution(sudoku);
+ int solved = solution.solve_search();
+ if (solved == 0) {
+ QMessageBox::warning(this, tr("Guess"), tr("No cells to solve found"));
return;
}
@@ -219,6 +223,7 @@ void SolverWindow::step()
void SolverWindow::solve()
{
+ // TODO messagebox, detect invalid and solved states
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
int solved = sudoku.solve_rules();
@@ -229,6 +234,7 @@ void SolverWindow::solve()
void SolverWindow::search()
{
+ // TODO messagebox, detect invalid and solved states
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
int iterations = sudoku.solve_search();
@@ -244,7 +250,7 @@ void SolverWindow::step_constraints()
solverwindow_sudokuwidget->get_values(sudoku);
int solved = sudoku.solve_constraints();
solverwindow_sudokuwidget->set_values(sudoku);
- qDebug() << solved << " cells solved";
+ // qDebug() << solved << " cells solved";
}
void SolverWindow::step_coverage()
@@ -253,7 +259,7 @@ void SolverWindow::step_coverage()
solverwindow_sudokuwidget->get_values(sudoku);
int solved = sudoku.solve_coverage();
solverwindow_sudokuwidget->set_values(sudoku);
- qDebug() << solved << " cells solved";
+ // qDebug() << solved << " cells solved";
}
void SolverWindow::validate()
@@ -261,11 +267,10 @@ void SolverWindow::validate()
Sudoku sudoku;
solverwindow_sudokuwidget->get_values(sudoku);
if (sudoku.validate()) {
- qDebug() << "sudoku is valid";
+ QMessageBox::information(this, tr("Validate"), tr("Sudoku is valid."));
} else {
- qDebug() << "sudoku is not valid";
+ QMessageBox::warning(this, tr("Validate"), tr("Sudoku is not valid!"));
}
solverwindow_sudokuwidget->set_values(sudoku);
- qDebug() << "sudoku validated";
}
diff --git a/src/solverwindow.h b/src/solverwindow.h
index 17cb55c..4520c9e 100644
--- a/src/solverwindow.h
+++ b/src/solverwindow.h
@@ -14,23 +14,53 @@ class SolverWindow : public QWidget
public:
SolverWindow();
+
+ inline const QString & filename()
+ {
+ return solverwindow_filename;
+ }
public slots:
void load();
+ void save();
void saveas();
void revert();
+
+ /**
+ * @brief try to find a solution by using the rules only
+ * */
void solve();
+
+ /**
+ * @brief try to find a solution by guessing where required
+ * */
void search();
+
+ /**
+ * @brief try to solve a single cell by using the rules only
+ * */
void step();
+
void step_constraints();
- void step_coverage();
+ void step_coverage();
+
+ /**
+ * @brief try to solve a single cell by guessing where required
+ * */
+ void guess();
+
void clear();
+
void validate();
private:
+ void saveToFile(const QString & filename);
+ void loadFromFile(const QString & filename);
+
SudokuWidget *solverwindow_sudokuwidget;
Sudoku solverwindow_revertstate;
+ QString solverwindow_filename;
};
#endif // __INCLUDED_SUDOKUSOLVER_SOLVERWINDOW__ \ No newline at end of file
diff --git a/src/sudokuwidget.cc b/src/sudokuwidget.cc
index 23052ef..75fc3be 100644
--- a/src/sudokuwidget.cc
+++ b/src/sudokuwidget.cc
@@ -13,6 +13,42 @@ SudokuWidget::SudokuWidget()
sudokuwidget_value[row][column] = new QLineEdit(this);
sudokuwidget_value[row][column]->setFrame(false);
sudokuwidget_value[row][column]->setAlignment(Qt::AlignCenter);
+
+ connect(sudokuwidget_value[row][column], SIGNAL(textEdited(const QString &)), this, SLOT(verify(const QString &)));
+ }
+ }
+}
+
+void SudokuWidget::verify(const QString & text)
+{
+ Sudoku values;
+ for (int row = 0; row < 9; row++) {
+ for (int column = 0; column < 9 ; column++) {
+ bool ok;
+ QString str(sudokuwidget_value[row][column]->text());
+ int i = str.toInt(&ok);
+ if (ok && (i > 0) && (i <= 9)) {
+ values.cell(row, column).set_value(i);
+ } else {
+ values.cell(row, column).set_value(0);
+ }
+ }
+ }
+
+ values.validate();
+
+ for (int row = 0; row < 9; row++) {
+ for (int column = 0; column < 9 ; column++) {
+ QPalette child_palette(palette());
+ int i = values.cell(row, column).value();
+ if ( (i > 0) && (i <= 9) ) {
+ // set background color depending on the validity of the cell value
+ if (!values.cell(row, column).valid()) {
+ // FIXME colors should be configurable
+ child_palette.setColor(QPalette::Base, QColor(255, 0, 0));
+ }
+ }
+ sudokuwidget_value[row][column]->setPalette(child_palette);
}
}
}
diff --git a/src/sudokuwidget.h b/src/sudokuwidget.h
index ce1cffd..e4140a0 100644
--- a/src/sudokuwidget.h
+++ b/src/sudokuwidget.h
@@ -45,6 +45,8 @@ protected:
private:
QLineEdit * sudokuwidget_value[9][9];
+private slots:
+ void verify(const QString & text);
};
#endif // __INCLUDED_SUDOKUSOLVER_SUDOKUWIDGET__ \ No newline at end of file