[gnome-games/applygsoc2009: 50/76] Fix impossible hints



commit f49248e325d86dc079973565b81884ff648c45fb
Author: Pablo Castellano <pablog src gnome org>
Date:   Wed Sep 1 04:06:59 2010 +0200

    Fix impossible hints

 gnome-sudoku/src/lib/main.py       |   10 ++---
 gnome-sudoku/src/lib/model.py      |   86 +++++++++++++-----------------------
 gnome-sudoku/src/lib/number_box.py |   16 ++-----
 3 files changed, 39 insertions(+), 73 deletions(-)
---
diff --git a/gnome-sudoku/src/lib/main.py b/gnome-sudoku/src/lib/main.py
index 0a7af43..46ffccb 100644
--- a/gnome-sudoku/src/lib/main.py
+++ b/gnome-sudoku/src/lib/main.py
@@ -376,10 +376,11 @@ class UI (gconf_wrapper.GConfWrapper):
         sublabel += "\n"
         sublabel += ngettext("You got %(n)s hint.", "You got %(n)s hints.", self.gsd.hints) % {'n':self.gsd.hints}
         sublabel += "\n"
-        if self.gsd.impossible_hints:
+        impossible_hints = self._main_model.get_impossible_hints()
+        if impossible_hints:
             sublabel += ngettext("You had %(n)s impossibility pointed out.",
                                  "You had %(n)s impossibilities pointed out.",
-                                 self.gsd.impossible_hints) % {'n':self.gsd.impossible_hints}
+                                 impossible_hints) % {'n': impossible_hints}
             sublabel += "\n"
         self.start_dancer()
         dialog_extras.show_message(_("You win!"), label = _("You win!"),
@@ -535,10 +536,7 @@ class UI (gconf_wrapper.GConfWrapper):
         self._notes_model.toggle_auto_hint(action.get_active())
 
     def impossible_implication_cb (self, action):
-        if action.get_active():
-            self.gsd.display_impossible_implications()
-        else:
-            self.gsd.hide_impossible_implications()
+        self._main_model.toggle_impossible_implications(True)
 
     def setup_tracker_interface (self):
         self.tracker_ui = tracker_box.TrackerBox(self)
diff --git a/gnome-sudoku/src/lib/model.py b/gnome-sudoku/src/lib/model.py
index 65de735..115e789 100644
--- a/gnome-sudoku/src/lib/model.py
+++ b/gnome-sudoku/src/lib/model.py
@@ -88,8 +88,7 @@ class SudokuModel:
         self.hints = 0
         self.autofill_count = 0
         self.show_impossible_implications = False
-        self.impossible_hints = 0
-        self.impossibilities = []
+        self.impossibilities = set()
         self.__trackers_tracking__ = {}
         self.group_size = group_size
 
@@ -108,7 +107,8 @@ class SudokuModel:
     def _signal_observers(self, values):
         for observer in self._observers:
             observer.update(values)
-
+        self._check_for_completeness()
+        
     def animate_hint (self):
         if self.hint_animate_count % 2 == 0:
             color = (1.0, 0.0, 0.0)
@@ -250,9 +250,9 @@ class SudokuModel:
         result = [NumberBoxModel(x, y, value=value, conflict=flag)]
         result.extend(old_conflicts)
         result.extend(new_conflicts)
-
+        result.extend(self._update_impossible_implications(x, y))
+        
         self._signal_observers(result)
-        self._check_for_completeness()
 
     def get_virgin_value(self, x, y):
         return self._virgin_grid[9 * y + x]
@@ -340,59 +340,35 @@ class SudokuModel:
         if self.always_show_hints:
             self.update_all_hints()
 
-    def _mark_impossible_implications (self, x, y, check_conflicts = True):
-        '''Mark cells with X if they have no possible values
+    def toggle_impossible_implications(self, show):
+        self.show_impossible_implications = show
+        if not show:
+            self._clean_impossible_implications()
 
-        The hint this method provides can be turned on and off from the
-        menu Tools->'Warn about unfillable squares' option.
+    def _clean_impossible_implications(self):
+        for (x, y) in self.impossibilities:
+            self.set_value(x, y, 0)
 
-        The check_conflicts parameter is for internal use only.  It is used as
-        a one level recursion on conflicts that the original target is involved
-        with.
+    def _update_impossible_implications(self, x, y):
+        if not self.show_impossible_implications:
+            return []
+
+        changes = []
+        new_imposs = set(self.grid.find_impossible_implications(x, y))
+
+        for coord in new_imposs - self.impossibilities:
+            # -1 means impossible
+            changes.append(NumberBoxModel(coord[0], coord[1], value=-1))
+        for coord in self.impossibilities - new_imposs:
+            # remove the 'X' mark
+            changes.append(NumberBoxModel(coord[0], coord[1], value=0))
+
+        self.impossibilities = new_imposs
+        return changes
+
+    def get_impossible_hints(self):
+        return len(self.impossibilities)
 
-        Impossibilities are tracked regardless of the user's option setting.
-        This was done to allow the user to toggle the option mid-game and still
-        behave properly.  Conditional X-marking of cells happens in the
-        __set_impossible() function.
-        '''
-        # Make sure we have a grid to work with
-        if not self.grid:
-            return
-        # Flag whether or not we need to update hints
-        grid_modified = False
-        # Find any new impossible cells based on calling cell
-        implications = self.grid.find_impossible_implications(x, y)
-        if implications:
-            for imp_cell in implications:
-                grid_modified = self.__set_impossible(imp_cell, True)
-                # Add them to the list if they aren't there already...
-                if not imp_cell in self.impossibilities:
-                    self.impossibilities.append(imp_cell)
-                    # But don't score it unless the option is on
-                    if self.show_impossible_implications:
-                        self.impossible_hints += 1
-        # Reset the list of impossible cells ignoring the called cell. Use a
-        # copy to iterate over, so items can be removed while looping.
-        if self.impossibilities:
-            for imp_cell in self.impossibilities[:]:
-                if imp_cell == (x, y):
-                    continue
-                if self.grid.possible_values(*imp_cell):
-                    self.impossibilities.remove(imp_cell)
-                    grid_modified = self.__set_impossible(imp_cell, False)
-                else:
-                    grid_modified = self.__set_impossible(imp_cell, True)
-        # If any conflicts have been cleared or created, mark any impossible
-        # cells they may have caused or removed
-        if check_conflicts:
-            for xx, yy in self.grid.cleared_conflicts:
-                self.mark_impossible_implications(xx, yy, False)
-            if self.grid.conflicts.has_key((x, y)):
-                for xx, yy in self.grid.conflicts[(x, y)]:
-                    self.mark_impossible_implications(xx, yy, False)
-        # Update the hints if we need to
-        if grid_modified and self.always_show_hints:
-            self.update_all_hints()
 
     def delete_by_tracker (self):
         '''Delete all cells tracked by the current tracker
diff --git a/gnome-sudoku/src/lib/number_box.py b/gnome-sudoku/src/lib/number_box.py
index f9ea537..9d73b02 100644
--- a/gnome-sudoku/src/lib/number_box.py
+++ b/gnome-sudoku/src/lib/number_box.py
@@ -88,7 +88,7 @@ class _NumberBox (gtk.Widget):
     npicker = None
     draw_boxes = False
 
-    def __init__ (self, upper=9, value=''):
+    def __init__ (self, upper=9, value=0):
         gtk.Widget.__init__(self)
         self.upper = upper
         self.parent_win = None
@@ -700,8 +700,10 @@ class _NumberBox (gtk.Widget):
         self.value = v
         if 0 < v <= self.upper:
             self.set_text(str(v))
+        elif v == 0:
+			self.set_text('')
         else:
-            self.set_text('')
+            self.set_text("X")
         self.queue_draw()
 
     def get_value (self):
@@ -763,16 +765,6 @@ class SudokuNumberBox (_NumberBox):
             self.set_font(self.normal_font)
         self.queue_draw()
 
-    def set_impossible (self, val):
-        if val:
-            if not self.get_text():
-                self.set_text('X')
-                self.set_text_color(self.error_color)
-        elif self.get_text() == 'X':
-            self.set_text('')
-            self.set_text_color(self.normal_color)
-        self.queue_draw()
-
 
 if __name__ == '__main__':
     window = gtk.Window()



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