[gnome-games/sudoku-vala] Handle incorrect inputs, Gdk keybind to detect key



commit d7445597d129e303bfc0656acc363c7923eb61aa
Author: PioneerAxon <arth svnit gmail com>
Date:   Mon Mar 19 01:42:23 2012 +0530

    Handle incorrect inputs, Gdk keybind to detect key
    
    SudokuBoard now handles wrong inputs by saving status bit saying broken or not. On update or remove, it automatically updates status and possible flags.
    key_press_event now uses Gdk.keyval_name to detect the value of key, instead of default uint number.
    added key_map_kaypad to map keys to keypad.
    Minor bugfix in Hint function, for range of random number generator.
    Minor bugfix in apply_stack, removed multiple insert on value = 0.

 gnome-sudoku/src/sudoku-game.vala      |   72 +++++++++++++++++++++-----------
 gnome-sudoku/src/sudoku-generator.vala |    2 +-
 gnome-sudoku/src/sudoku-view.vala      |   53 +++++++++++++++++------
 3 files changed, 88 insertions(+), 39 deletions(-)
---
diff --git a/gnome-sudoku/src/sudoku-game.vala b/gnome-sudoku/src/sudoku-game.vala
index 0dfd0f7..26fb416 100644
--- a/gnome-sudoku/src/sudoku-game.vala
+++ b/gnome-sudoku/src/sudoku-game.vala
@@ -9,6 +9,7 @@ public class SudokuBoard
     private bool[,,] possible_in_block;         /* if specific value is possible in specific block */
     private int block_row;                      /* size of sub-part ( block ) in board */
     private int block_col;                      /* size of sub-part ( block ) in board */
+    public bool broken;                        /* true if forced inserted */
 
     public signal void value_changed (int row, int col, int old_value, int new_value);
     public signal void value_changing (int row, int col, int old_value, int new_value);
@@ -51,7 +52,7 @@ public class SudokuBoard
         possible_in_row = new bool[_row, _col];
         possible_in_col = new bool[_col, _row];
         possible_in_block = new bool[block_row, block_col, block_row * block_col];
-
+        broken = false;
         for (var l1 = 0; l1 < _row; l1++)
         {
             for (var l2 = 0; l2 < _col; l2++)
@@ -103,17 +104,50 @@ public class SudokuBoard
         return count;
     }
 
+    public bool update_possibles ()
+    {
+        bool ret = false;
+        for (var l1 = 0; l1 < _row; l1++)
+        {
+            for (var l2 = 0; l2 < _col; l2++)
+            {
+                possible_in_row [l1, l2] = true;
+                possible_in_col [l2, l1] = true;
+            }
+        }
+        for (var l1 = 0; l1 < block_row; l1++)
+        {
+            for (var l2 = 0; l2 < block_col; l2++)
+            {
+                for (var l3 = 0; l3 < max_val; l3++)
+                    possible_in_block [l1, l2, l3] = true;
+            }
+        }
+        for (var l1 = 0; l1 < _row; l1++)
+        {
+            for (var l2 = 0; l2 < _col; l2++)
+            {
+                int val = cells [l1, l2];
+                if (val-- == 0)
+                    continue;
+                ret |= (possible_in_row [l1, val] == false || possible_in_col [l2, val] == false || possible_in_block [l1 / block_col, l2 / block_row, val] == false);
+                possible_in_row [l1, val] = false;
+                possible_in_col [l2, val] = false;
+                possible_in_block [l1 / block_col, l2 / block_row, val] = false;
+            }
+        }
+        return ret;
+    }
+
     /* This function should only be used by SudokuSolver to stop call to SudokuViewer. */
     public void silent_insert (int row, int col, int val, bool is_fixed = false)
     {
         /* This should not happen when coded properly ;) */
         if (cells[row, col] != 0)
-            return;
-
+            silent_remove (row, col);
         /* This should not happen when coded properly ;) */
         if (!is_possible (row, col, val))
-             return;
-
+             broken = true;
         cells[row, col] = val;
         this.is_fixed[row, col] = is_fixed;
         val--;
@@ -126,10 +160,7 @@ public class SudokuBoard
     public void insert (int row, int col, int val, bool is_fixed = false)
     {
         var old_val = cells[row, col];
-
         value_changing (row, col, old_val, val);
-        if (cells [row, col] != 0)
-            silent_remove (row, col);
         silent_insert (row, col, val, is_fixed);
         value_changed (row, col, old_val, val);
     }
@@ -140,11 +171,9 @@ public class SudokuBoard
         /* This should not happen when coded properly ;) */
         if (is_fixed[row, col])
             return;
-
         /* Empty cell, Just pretend everything is okay... */
         if (cells[row, col] == 0)
             return;
-
         int val = cells[row, col];
         val--;
         cells[row, col] = 0;
@@ -152,18 +181,12 @@ public class SudokuBoard
         possible_in_col[col, val] = true;
         possible_in_block[row / block_col, col / block_row, val] = true;
         _filled--;
+        if (broken)
+            broken = update_possibles ();
     }
 
     public void remove (int row, int col)
     {
-        /* This should not happen when coded properly ;) */
-        if (is_fixed[row, col])
-            return;
-
-        /* Empty cell, Just pretend everything is okay... */
-        if (cells[row, col] == 0)
-            return;
-
         int old_val = cells[row, col];
         value_changing (row, col, old_val, 0);
         silent_remove (row, col);
@@ -244,7 +267,6 @@ public class SudokuGame
         var total_pos = new int [board.row, board.col];
         var min = board.max_val + 1;
         var count = 0;
-
         for (var l1 = 0; l1 < board.row; l1++)
         {
             for (var l2 = 0; l2 < board.col; l2++)
@@ -256,13 +278,14 @@ public class SudokuGame
                     count = 0;
                 }
                 if (total_pos [l1, l2] == min)
+                {
                     count++;
+                }
             }
         }
         if (count == 0)
             return;
-
-        count = Random.int_range (0, count);
+        count = Random.int_range (1, count + 1);
         for (var l1 = 0; l1 < board.row; l1++)
         {
             for (var l2 = 0; l2 < board.col; l2++)
@@ -307,9 +330,10 @@ public class SudokuGame
         if (from.data.row >= 0 && from.data.col >= 0)
         {
             board.value_changing.disconnect (update_undo);
-            add_to_stack (ref to, from.data.row, from.data.col, board.cells [from.data.row, from.data.col] );
-            board.silent_remove (from.data.row, from.data.col);
-            board.insert (from.data.row, from.data.col, from.data.val);
+            add_to_stack (ref to, from.data.row, from.data.col, board.cells [from.data.row, from.data.col]);
+            board.remove (from.data.row, from.data.col);
+            if (from.data.val != 0)
+                board.insert (from.data.row, from.data.col, from.data.val);
             from.remove (from.data);
             board.value_changing.connect (update_undo);
         }
diff --git a/gnome-sudoku/src/sudoku-generator.vala b/gnome-sudoku/src/sudoku-generator.vala
index 69843d0..6b35bd3 100644
--- a/gnome-sudoku/src/sudoku-generator.vala
+++ b/gnome-sudoku/src/sudoku-generator.vala
@@ -28,7 +28,7 @@ public class SudokuSolver
         this.board = board;
     }
 
-    /* Check if current SudokuBoard has at lesat one solution or not */
+    /* Check if current SudokuBoard has at least one solution or not */
     public bool has_solution ()
     {
         int solutions = 0;
diff --git a/gnome-sudoku/src/sudoku-view.vala b/gnome-sudoku/src/sudoku-view.vala
index db2c6b7..c01402f 100644
--- a/gnome-sudoku/src/sudoku-view.vala
+++ b/gnome-sudoku/src/sudoku-view.vala
@@ -47,15 +47,11 @@ private class SudokuCellView : Gtk.DrawingArea
                 text = "%d".printf (value);
                 return;
             }
-            if (board.is_possible(_row, _col, value))
+            if (!board.is_possible (_row, _col, value))
             {
-                board.insert (_row, _col, value);
-            }
-            else
-            {
-                stdout.printf("TODO: Notification Invalid value.\n");
-                /* TODO: Notify user. Wrong value selected */
+                /* TODO: Notify user for inconsistant value */
             }
+            board.insert (_row, _col, value);
         }
     }
 
@@ -260,23 +256,52 @@ private class SudokuCellView : Gtk.DrawingArea
         return false;
     }
 
-    public override bool key_press_event (Gdk.EventKey event)
+    /* Key mapping function to help convert Gdk.keyval_name string to numbers */
+    private int key_map_keypad (string key_name)
     {
-        /* FIXME: Can't find vala bindings to Gdk keyvals... */
+        /* Compared with "0" to make sure, actual "0" is not misinterpreted as parse error in int.parse() */
+        if (key_name == "KP_0" || key_name == "0")
+            return 0;
+        if (key_name == "KP_1")
+            return 1;
+        if (key_name == "KP_2")
+            return 2;
+        if (key_name == "KP_3")
+            return 3;
+        if (key_name == "KP_4")
+            return 4;
+        if (key_name == "KP_5")
+            return 5;
+        if (key_name == "KP_6")
+            return 6;
+        if (key_name == "KP_7")
+            return 7;
+        if (key_name == "KP_8")
+            return 8;
+        if (key_name == "KP_9")
+            return 9;
+        return -1;
+    }
 
-        if (event.keyval >= 49 /* 1 */ && event.keyval <= 58 /* 9 */)
+    public override bool key_press_event (Gdk.EventKey event)
+    {
+        string k_name = Gdk.keyval_name (event.keyval);
+        int k_no = int.parse (k_name);
+        /* If k_no is 0, there might be some error in parsing, crosscheck with keypad values. */
+        if (k_no == 0)
+            k_no = key_map_keypad (k_name);
+        if (k_no >= 1 && k_no <= 9)
         {
-            value = (int)event.keyval - 48;
+            value = k_no;
             return true;
         }
-
-        if (event.keyval == 48 || event.keyval == 65288 /* backspace */ || event.keyval == 65535 /* delete */)
+        if (k_no == 0 || k_name == "BackSpace" || k_name == "Delete")
         {
             value = 0;
             return true;
         }
 
-        if (event.keyval == 32 /* space */ || event.keyval == 65293 /* enter */)
+        if (k_name == "space" || k_name == "Return" || k_name == "KP_Enter")
         {
             show_number_picker ();
             return true;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]