First, it looks like there are two kinds of cells.
Known calls; those with a fixed value, no choices.
Unknown cells; those with a set of candidate values that reduces down to a single final value.
Second, there are several groups of cells.
Horizontal rows and Vertical columns which must have one cell of each value. That constraint is used to remove values from various cells in the row or column.
3x3 blocks which must have one cell of each value. That constraint is used to remove values from various cells in the block.
Finally, there's the overall grid. This has several complementary views.
It's 81 cells.
The cells are also collected into a 3x3 grid of 3x3 blocks.
The cells are also collected into 9 columns.
The cells are also collected into 9 rows.
And you have a solver strategy object.
Each Unknown cell it set to having set( range(1,10) )
as the candidate values.
For each row, column and 3x3 block (27 different collections):
a. For each cell:
- If it has definite value (Known cells and Unknown cells implement this differently): remove that value from all other cells in this grouping.
The above must be iterated until no changes are found.
At this point, you either have it solved (all cells report a definite value), or, you have some cells with multiple values. Now you have to engage in a sophisticated back-tracking solver to find a combination of the remaining values that "works".