diff --git a/domain/src/main/kotlin/ch/dissem/yaep/domain/generator.kt b/domain/src/main/kotlin/ch/dissem/yaep/domain/generator.kt index ba7b6ef..e690791 100644 --- a/domain/src/main/kotlin/ch/dissem/yaep/domain/generator.kt +++ b/domain/src/main/kotlin/ch/dissem/yaep/domain/generator.kt @@ -1,6 +1,8 @@ package ch.dissem.yaep.domain -import ch.dissem.yaep.domain.PuzzleSolution.* +import ch.dissem.yaep.domain.PuzzleSolution.MULTIPLE_SOLUTIONS +import ch.dissem.yaep.domain.PuzzleSolution.NO_SOLUTION +import ch.dissem.yaep.domain.PuzzleSolution.SOLVABLE import kotlin.random.Random fun generateGame(size: Int = 6): Game { @@ -68,24 +70,33 @@ internal fun solve( if (grid.cells.all { it.selection != null }) return SOLVABLE // If there are still cells with multiple items, pick one and try each item in turn, then go back to step 2. - for (i in 0 until grid.size) { - for (j in 0 until grid.size) { - val cell = grid[i][j] - if (cell.selection == null) { - val options = cell.options.toList() - for (option in options) { - cell.selection = option - if (solve(grid, clues) == SOLVABLE) { - return SOLVABLE - } - } - cell.selection = null - cell.options.addAll(options) - } + return if ( + grid.cells + .filter { it.selection == null } + .any { it.countSolutions(grid, clues) == 1 } + ) { + SOLVABLE + } else { + MULTIPLE_SOLUTIONS + } +} + +internal fun > GameCell.countSolutions( + grid: Grid, + clues: Collection +): Int { + val options = options.toList() + var solvableCount = 0 + for (option in options) { + selection = option + if (solve(grid, clues) == SOLVABLE) { + solvableCount++ } } - // This shouldn't happen, as we don't check if there are more solutions once we find one - return MULTIPLE_SOLUTIONS + selection = null + this.options.addAll(options) + + return solvableCount } internal enum class PuzzleSolution {