[gnome-games/applygsoc2009: 50/76] Fix impossible hints
- From: Pablo Castellano <pablog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games/applygsoc2009: 50/76] Fix impossible hints
- Date: Mon, 6 Sep 2010 02:51:25 +0000 (UTC)
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]