from __future__ import division
-from weakref import proxy
+from weakref import ref
-class CellGroup(object):
- """Represents any group of cells in a grid."""
+class CellConstraint(object):
+ """Represents any group of cells in a grid that cannot repeat a digit."""
### Accessors
- cells = []
+ # NOTE: _cells is a list of refs; _grid is a ref
+ # XXX document this
+ cells = property(lambda self: [ x() for x in self._cells ])
+ grid = property(lambda self: self._grid())
### Methods
- # XXX inherited __init__
+ # XXX inherited __init__ to init _grid/_cells
def find_value(self, value):
"""Returns the cells that can be a specific value."""
return possible_cells
def resolve_uniques(self):
- for value in xrange(self._grid._size):
+ for value in xrange(self.grid._size):
# XXX cache values that are taken care of
possible_cells = self.find_value(value)
target_cell.set(value)
-class Box(CellGroup):
+class Box(CellConstraint):
def _get_box_row(self):
- return self._pos // self._grid._box_width
+ return self._pos // self.grid._box_width
box_row = property(_get_box_row)
def _get_box_column(self):
- return self._pos % self._grid._box_height
+ return self._pos % self.grid._box_height
box_column = property(_get_box_column)
- def _get_cells(self):
- # XXX generator + docstring
- cells = []
- for row in xrange(self._grid._box_height):
- for col in xrange(self._grid._box_width):
- cell_row = row + self.box_row * self._grid._box_height
- cell_col = col + self.box_column * self._grid._box_width
- cells.append(self._grid.cell(cell_row, cell_col))
- return cells
- cells = property(_get_cells)
-
def __init__(self, grid, position):
- self._grid = proxy(grid)
+ self._grid = ref(grid)
self._pos = position
+ self._cells = []
+ for row in xrange(self.grid._box_height):
+ for col in xrange(self.grid._box_width):
+ cell_row = row + self.box_row * self.grid._box_height
+ cell_col = col + self.box_column * self.grid._box_width
+ self._cells.append(ref(self.grid.cell(cell_row, cell_col)))
-class Row(CellGroup):
- def _get_cells(self):
- # XXX generator + docstring
- cells = []
- for col in xrange(self._grid._size):
- cells.append(self._grid.cell(self._pos, col))
- return cells
- cells = property(_get_cells)
+class Row(CellConstraint):
def __init__(self, grid, position):
- self._grid = proxy(grid)
+ self._grid = ref(grid)
self._pos = position
+ self._cells = []
+ for col in xrange(self.grid._size):
+ self._cells.append(ref(self.grid.cell(self._pos, col)))
-class Column(CellGroup):
- def _get_cells(self):
- # XXX generator + docstring
- cells = []
- for row in xrange(self._grid._size):
- cells.append(self._grid.cell(row, self._pos))
- return cells
- cells = property(_get_cells)
-
+class Column(CellConstraint):
def __init__(self, grid, position):
- self._grid = proxy(grid)
+ self._grid = ref(grid)
self._pos = position
+
+ self._cells = []
+ for row in xrange(self.grid._size):
+ self._cells.append(ref(self.grid.cell(row, self._pos)))
+
+class Diagonal(CellConstraint):
+ def __init__(self, grid, direction='down', offset=0):
+ self._grid = ref(grid)
+ self._direction = direction
+ self._offset = offset
+
+ if direction == 'down':
+ coords = {'row': 0, 'column': 0}
+ increment = 1
+ elif direction == 'up':
+ coords = {'row': 0, 'column': grid.size - 1}
+ increment = -1
+ else:
+ raise Exception # XXX
+
+ # XXX
+ if offset != 0:
+ raise NotImplementedError
+
+ self._cells = []
+ for i in xrange(self.grid.size):
+ self._cells.append(ref(self.grid.cell(coords['row'], coords['column'])))
+ coords['row'] += 1
+ coords['column'] += increment