Pseudo code for the solve and _solver methods: ---------------------------------------------- Make sure that your resolve_singletons method is also checking for "bad" squares! A "bad" square is a square that has no valid value. Once you find such square, you return False immediately. Otherwise, after filling all singletons (recursively), you return True. The Pseudo Algorithm: --------------------- def solve(self): self.solutions = [] # This is where you save all the solutions clone = Sudoku(str(self)) # Take a copy of your self self._solver(clone) # and send it to the _solver method def _solver(self, clone): if number of solutions >= self.max_solutions: return if resolve_singletons (in clone) fails: return if clone is solved: add it to self.solutions return else if clone is not valid: return Find the square with the minimal number of possible valid values for each valid value n you can place in this square: Create a new Sudoku puzzle in which n is placed in that square Send the new puzzle to the _solver method (recursion)