private bool SolveHelper(Board board) { // Create Reducers OtherRowsAreBlockedReducer otherRowsAreBlockedReducer = new OtherRowsAreBlockedReducer(board); OtherColumnsAreBlockedReducer otherColumnsAreBlockedReducer = new OtherColumnsAreBlockedReducer(board); EqualOptionsInRowReducer equalOptionsInRowReducer = new EqualOptionsInRowReducer(board); EqualOptionsInColumnReducer equalOptionsInColumnReducer = new EqualOptionsInColumnReducer(board); EqualOptionsInQuadReducer equalOptionsInQuadReducer = new EqualOptionsInQuadReducer(board); // Create Solvers OnlyCandidateInCellSolver onlyCandidateInCellSolver = new OnlyCandidateInCellSolver(board); OnlyOptionInRowSolver onlyOptionInRowSolver = new OnlyOptionInRowSolver(board); OnlyOptionInColumnSolver onlyOptionInColumnSolver = new OnlyOptionInColumnSolver(board); OnlyOptionInQuadSolver onlyOptionInQuadSolver = new OnlyOptionInQuadSolver(board); while (true) { iterations++; bool repeatLoop = false; // Limit insertion candidates repeatLoop = repeatLoop || otherRowsAreBlockedReducer.Run(); repeatLoop = repeatLoop || otherColumnsAreBlockedReducer.Run(); repeatLoop = repeatLoop || equalOptionsInRowReducer.Run(); repeatLoop = repeatLoop || equalOptionsInColumnReducer.Run(); repeatLoop = repeatLoop || equalOptionsInQuadReducer.Run(); // Fill cells repeatLoop = repeatLoop || onlyCandidateInCellSolver.Run(); repeatLoop = repeatLoop || onlyOptionInRowSolver.Run(); repeatLoop = repeatLoop || onlyOptionInColumnSolver.Run(); repeatLoop = repeatLoop || onlyOptionInQuadSolver.Run(); if (repeatLoop) { continue; } if (board.UnknownValues() == 0) { return(true); } else if (board.BacktrackLevel < maxBacktrackLevel) { foreach (Cell cell in board.AllCells()) { foreach (int candidate in cell.Candidates) { Board newBoard = new Board(board); Cell assumedCell = new Cell(cell); assumedCell.Number = candidate; newBoard.ReplaceCell(assumedCell); if (SolveHelper(newBoard)) { assumedCells.Add(assumedCell); foreach (Cell solvedCell in newBoard.AllCells()) { board.ReplaceCell(solvedCell); } return(true); } } } } return(false); } }