[gnome-sudoku] Add validity and uniqueness check to manually created puzzles
- From: Parin Porecha <parinporecha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-sudoku] Add validity and uniqueness check to manually created puzzles
- Date: Tue, 21 Apr 2015 17:20:07 +0000 (UTC)
commit c5ce94ea6485740bc9e8b9a9c669cf789042822c
Author: Parin Porecha <parinporecha gmail com>
Date: Tue Apr 21 22:45:49 2015 +0530
Add validity and uniqueness check to manually created puzzles
Also bump required QQwing version to 1.3.4
configure.ac | 2 +-
lib/qqwing-wrapper.cpp | 14 ++++++++++++++
lib/qqwing-wrapper.h | 1 +
lib/qqwing.vapi | 1 +
lib/sudoku-board.vala | 5 +++++
src/gnome-sudoku.vala | 42 +++++++++++++++++++++++++++++++++++++++---
6 files changed, 61 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9b9f308..7661522 100644
--- a/configure.ac
+++ b/configure.ac
@@ -27,7 +27,7 @@ dnl ###########################################################################
GLIB_REQUIRED=2.40.0
GTK_REQUIRED=3.15.0
-QQWING_REQUIRED=1.2.0
+QQWING_REQUIRED=1.3.4
PKG_CHECK_MODULES(GNOME_SUDOKU, [
glib-2.0 >= $GLIB_REQUIRED
diff --git a/lib/qqwing-wrapper.cpp b/lib/qqwing-wrapper.cpp
index c1a453f..99c4562 100644
--- a/lib/qqwing-wrapper.cpp
+++ b/lib/qqwing-wrapper.cpp
@@ -64,6 +64,20 @@ int* qqwing_generate_puzzle(int difficulty)
}
/*
+ * Count the number of solutions of a puzzle
+ * but return 2 if there are multiple.
+ * Returns 0 if the puzzle is not valid.
+ */
+int qqwing_count_solutions_limited(int* puzzle)
+{
+ SudokuBoard board;
+ if (!board.setPuzzle(puzzle))
+ return 0;
+
+ return board.countSolutionsLimited();
+}
+
+/*
* Print the stats gathered while solving the puzzle given as input.
*/
void qqwing_print_stats(int* puzzle)
diff --git a/lib/qqwing-wrapper.h b/lib/qqwing-wrapper.h
index 345ab2c..4a4bfa0 100644
--- a/lib/qqwing-wrapper.h
+++ b/lib/qqwing-wrapper.h
@@ -27,6 +27,7 @@
G_BEGIN_DECLS
int *qqwing_generate_puzzle(int difficulty);
+int qqwing_count_solutions_limited(int *puzzle);
void qqwing_print_stats(int *puzzle);
char *qqwing_get_version(void);
diff --git a/lib/qqwing.vapi b/lib/qqwing.vapi
index 6b2f5d6..bea1f73 100644
--- a/lib/qqwing.vapi
+++ b/lib/qqwing.vapi
@@ -23,6 +23,7 @@
namespace QQwing {
[CCode (array_length=false)]
int[] generate_puzzle (int difficulty);
+ int count_solutions_limited ([CCode (array_length = false)] int[] puzzle);
void print_stats ([CCode (array_length = false)] int[] puzzle);
string get_version ();
}
diff --git a/lib/sudoku-board.vala b/lib/sudoku-board.vala
index 4507ac8..fbc206f 100644
--- a/lib/sudoku-board.vala
+++ b/lib/sudoku-board.vala
@@ -392,6 +392,11 @@ public class SudokuBoard : Object
fixed--;
}
+ public int count_solutions_limited ()
+ {
+ return QQwing.count_solutions_limited ((int[]) cells);
+ }
+
public Set<Coord?> get_occurances(Gee.List<Coord?> coords, int val)
{
Set<Coord?> occurances = new HashSet<Coord?>((HashDataFunc<Coord>) Coord.hash,
(EqualDataFunc<Coord>) Coord.equal);
diff --git a/src/gnome-sudoku.vala b/src/gnome-sudoku.vala
index 1ec9ed8..4a31d0e 100644
--- a/src/gnome-sudoku.vala
+++ b/src/gnome-sudoku.vala
@@ -293,9 +293,38 @@ public class Sudoku : Gtk.Application
private void play_custom_game_cb ()
{
- current_game_mode = GameMode.PLAY;
- game.stop_clock ();
- start_game (game.board);
+ int solutions = game.board.count_solutions_limited ();
+ if (solutions == 1)
+ {
+ start_custom_game (game.board);
+ }
+ else if (solutions == 0)
+ {
+ // Error dialog shown when starting a custom game that is not valid.
+ var error_str = "%s\n%s".printf(_("The puzzle you have entered is not a valid Sudoku."),
_("Please enter a valid puzzle."));
+ var dialog = new MessageDialog (window, DialogFlags.MODAL, MessageType.ERROR, ButtonsType.OK,
error_str);
+
+ dialog.run ();
+ dialog.destroy ();
+ }
+ else
+ {
+ // Warning dialog shown when starting a custom game that has multiple solutions.
+ var warning_str = "%s\n%s".printf(_("The puzzle you have entered has multiple solutions."),
_("Valid Sudoku puzzles have exactly one solution."));
+ var dialog = new MessageDialog (window, DialogFlags.MODAL, MessageType.WARNING,
ButtonsType.NONE, warning_str);
+ dialog.add_button (_("_Back"), Gtk.ResponseType.REJECT);
+ dialog.add_button (_("Play _Anyway"), Gtk.ResponseType.ACCEPT);
+
+ dialog.response.connect ((response_id) => {
+ if (response_id == Gtk.ResponseType.ACCEPT)
+ {
+ start_custom_game (game.board);
+ }
+ dialog.destroy ();
+ });
+
+ dialog.show ();
+ }
}
private void toggle_pause_cb ()
@@ -330,6 +359,13 @@ public class Sudoku : Gtk.Application
play_pause_label.label = _("_Resume");
}
+ private void start_custom_game (SudokuBoard board)
+ {
+ current_game_mode = GameMode.PLAY;
+ game.stop_clock ();
+ start_game (board);
+ }
+
private void start_game (SudokuBoard board)
{
if (view != null)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]