X-Git-Url: http://git.veekun.com/pseudoku.git/blobdiff_plain/8a045b780490790e8d69f929562a8d4befaf6283..1ebfc79f097b15fd37d3441344148a77c541ae08:/pseudoku/grid/constraints.py diff --git a/pseudoku/grid/constraints.py b/pseudoku/grid/constraints.py index 91f8287..e1ea667 100644 --- a/pseudoku/grid/constraints.py +++ b/pseudoku/grid/constraints.py @@ -7,6 +7,11 @@ class Constraint(object): ### Accessors + # True iff a constraint consists of a straight line of cells. Used to + # quickly skip over pairs of constraints that cannot possibly have more + # than one cell in common. + is_linear = False + # NOTE: _cells is a list of refs; _grid is a ref # XXX document this cells = property(lambda self: [ x() for x in self._cells ]) @@ -28,7 +33,15 @@ class Constraint(object): return possible_cells def resolve_uniques(self): - for value in xrange(self.grid._size): + """Searches for values that can only appear in one cell, and sets them + appropriately. + + Returns the number of cell changes. + """ + + cell_changes = 0 + + for value in xrange(self.grid.size): # XXX cache values that are taken care of possible_cells = self.find_value(value) @@ -43,16 +56,18 @@ class Constraint(object): continue # Only cell in the group that can be value - target_cell.set(value) + cell_changes += target_cell.set(value) + + return cell_changes class Box(Constraint): 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 __init__(self, grid, position): @@ -60,32 +75,38 @@ class Box(Constraint): 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 + 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(Constraint): + is_linear = True + def __init__(self, grid, position): self._grid = ref(grid) self._pos = position self._cells = [] - for col in xrange(self.grid._size): + for col in xrange(self.grid.size): self._cells.append(ref(self.grid.cell(self._pos, col))) class Column(Constraint): + is_linear = True + def __init__(self, grid, position): self._grid = ref(grid) self._pos = position self._cells = [] - for row in xrange(self.grid._size): + for row in xrange(self.grid.size): self._cells.append(ref(self.grid.cell(row, self._pos))) class Diagonal(Constraint): + is_linear = True + def __init__(self, grid, direction='down', offset=0): self._grid = ref(grid) self._direction = direction