1 from operator
import attrgetter
2 from weakref
import ref
5 """Represents a single cell/value within a sudoku grid."""
10 """True iff this cell has been solved."""
11 return len(self
._values
) == 1
12 solved
= property(_get_solved
)
15 """Returns this cell's value, if it has one known."""
17 return self
._values
[0]
19 value
= property(_get_value
)
21 grid
= property(lambda self
: self
._grid())
22 constraints
= property(attrgetter('_constraints'))
24 def __init__(self
, grid
, row
, column
):
25 self
._grid
= ref(grid
)
28 self
._values
= range(self
.grid
.size
)
29 self
._constraints
= []
30 self
._normalized
= False
32 def add_constraint(self
, constraint
):
33 self
._constraints
.append(constraint
)
35 def set(self
, value
, normalize
=True):
36 """Sets the value of this cell. If `normalize` is True or omitted, the
37 grid will be updated accordingly.
39 self
._values
= [value
]
41 self
._normalized
= False
47 """Checks to see if this cell has only one possible value left. If
48 so, sets that as its value and eliminates it from every related cell.
49 This method is exhaustive; that repeated calls should have no effect.
56 # Set this now just in case of infinite looping
57 self
._normalized
= True
60 # Don't know the value yet
64 for constraint
in self
.constraints
:
65 for cell
in constraint
.cells
:
68 cell
.eliminate(self
.value
)
71 def eliminate(self
, value
):
72 """Eliminates the given value as a possibility for this cell."""
73 if value
in self
._values
:
74 self
._values
.remove(value
)
76 if len(self
._values
) == 0:
77 # XXX give me a real exception here
80 self
._normalized
= False