From 625dc584bed28259ed4db1665b99c8d6f4261033 Mon Sep 17 00:00:00 2001 From: Eevee Date: Wed, 7 Jan 2009 08:49:40 -0500 Subject: [PATCH] Moved Cell to its own file. Also added columns/boxes accessors for Grid. --- pseudoku/grid/__init__.py | 84 +++-------------------------------------------- pseudoku/grid/cell.py | 81 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 80 deletions(-) create mode 100644 pseudoku/grid/cell.py diff --git a/pseudoku/grid/__init__.py b/pseudoku/grid/__init__.py index 3bf854b..9ba0158 100644 --- a/pseudoku/grid/__init__.py +++ b/pseudoku/grid/__init__.py @@ -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 index 0000000..0262130 --- /dev/null +++ b/pseudoku/grid/cell.py @@ -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() -- 2.7.4