Moved Cell to its own file.
authorEevee <eevee@nyarumaa.(none)>
Wed, 7 Jan 2009 13:49:40 +0000 (08:49 -0500)
committerEevee <eevee@nyarumaa.(none)>
Wed, 7 Jan 2009 13:49:40 +0000 (08:49 -0500)
Also added columns/boxes accessors for Grid.

pseudoku/grid/__init__.py
pseudoku/grid/cell.py [new file with mode: 0644]

index 3bf854b..9ba0158 100644 (file)
@@ -3,8 +3,8 @@ from __future__ import division
 from math import sqrt
 from operator import attrgetter
 import re
-from weakref import ref
 
+from cell import Cell
 from constraints import Constraint, Row, Column, Box
 
 symbols = [str(x + 1) for x in range(9)] + [chr(x + 97) for x in xrange(26)]
@@ -19,85 +19,6 @@ class GridIntegrityError(Exception):
     """
     pass
 
-class Cell(object):
-    """Represents a single cell/value within a sudoku grid."""
-
-    ### Accessors
-
-    def _get_solved(self):
-        """True iff this cell has been solved."""
-        return len(self._values) == 1
-    solved = property(_get_solved)
-
-    def _get_value(self):
-        """Returns this cell's value, if it has one known."""
-        if self.solved:
-            return self._values[0]
-        return None
-    value = property(_get_value)
-
-    grid = property(lambda self: self._grid())
-    constraints = property(attrgetter('_constraints'))
-
-    def __init__(self, grid, row, column):
-        self._grid = ref(grid)
-        self._row = row
-        self._col = column
-        self._values = range(self.grid.size)
-        self._constraints = []
-        self._normalized = False
-
-    def add_constraint(self, constraint):
-        self._constraints.append(constraint)
-
-    def set(self, value, normalize=True):
-        """Sets the value of this cell.  If `normalize` is True or omitted, the
-        grid will be updated accordingly.
-        """
-        self._values = [value]
-        if normalize:
-            self._normalized = False
-            self.normalize()
-
-
-
-    def normalize(self):
-        """Checks to see if this cell has only one possible value left.  If
-        so, sets that as its value and eliminates it from every related cell.
-        This method is exhaustive; that repeated calls should have no effect.
-        """
-
-        if self._normalized:
-            # Already done
-            return
-
-        # Set this now just in case of infinite looping
-        self._normalized = True
-
-        if not self.solved:
-            # Don't know the value yet
-            return
-
-        # Elimination time
-        for constraint in self.constraints:
-            for cell in constraint.cells:
-                if cell == self:
-                    continue
-                cell.eliminate(self.value)
-
-
-    def eliminate(self, value):
-        """Eliminates the given value as a possibility for this cell."""
-        if value in self._values:
-            self._values.remove(value)
-
-            if len(self._values) == 0:
-                # XXX give me a real exception here
-                raise Exception
-
-            self._normalized = False
-            self.normalize()
-
 
 class Grid(object):
     """Represents a Sudoku grid."""
@@ -153,6 +74,9 @@ class Grid(object):
         return filter(condition, self._constraints)
 
     rows = property(lambda self: self.get_constraints(Row))
+    columns = property(lambda self: self.get_constraints(Column))
+    boxes = property(lambda self: self.get_constraints(Box))
+
     box_height = property(attrgetter('_box_height'))
     box_width = property(attrgetter('_box_width'))
     size = property(attrgetter('_size'))
diff --git a/pseudoku/grid/cell.py b/pseudoku/grid/cell.py
new file mode 100644 (file)
index 0000000..0262130
--- /dev/null
@@ -0,0 +1,81 @@
+from operator import attrgetter
+from weakref import ref
+
+class Cell(object):
+    """Represents a single cell/value within a sudoku grid."""
+
+    ### Accessors
+
+    def _get_solved(self):
+        """True iff this cell has been solved."""
+        return len(self._values) == 1
+    solved = property(_get_solved)
+
+    def _get_value(self):
+        """Returns this cell's value, if it has one known."""
+        if self.solved:
+            return self._values[0]
+        return None
+    value = property(_get_value)
+
+    grid = property(lambda self: self._grid())
+    constraints = property(attrgetter('_constraints'))
+
+    def __init__(self, grid, row, column):
+        self._grid = ref(grid)
+        self._row = row
+        self._col = column
+        self._values = range(self.grid.size)
+        self._constraints = []
+        self._normalized = False
+
+    def add_constraint(self, constraint):
+        self._constraints.append(constraint)
+
+    def set(self, value, normalize=True):
+        """Sets the value of this cell.  If `normalize` is True or omitted, the
+        grid will be updated accordingly.
+        """
+        self._values = [value]
+        if normalize:
+            self._normalized = False
+            self.normalize()
+
+
+
+    def normalize(self):
+        """Checks to see if this cell has only one possible value left.  If
+        so, sets that as its value and eliminates it from every related cell.
+        This method is exhaustive; that repeated calls should have no effect.
+        """
+
+        if self._normalized:
+            # Already done
+            return
+
+        # Set this now just in case of infinite looping
+        self._normalized = True
+
+        if not self.solved:
+            # Don't know the value yet
+            return
+
+        # Elimination time
+        for constraint in self.constraints:
+            for cell in constraint.cells:
+                if cell == self:
+                    continue
+                cell.eliminate(self.value)
+
+
+    def eliminate(self, value):
+        """Eliminates the given value as a possibility for this cell."""
+        if value in self._values:
+            self._values.remove(value)
+
+            if len(self._values) == 0:
+                # XXX give me a real exception here
+                raise Exception
+
+            self._normalized = False
+            self.normalize()