Fix game generator

This commit is contained in:
2025-05-17 21:23:01 +02:00
parent 6d9e50fb88
commit 935115ca65
2 changed files with 10 additions and 32 deletions

View File

@@ -1,6 +1,8 @@
package ch.dissem.yaep.domain 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 import kotlin.random.Random
fun generateGame(size: Int = 6): Game { fun generateGame(size: Int = 6): Game {
@@ -36,8 +38,9 @@ fun generateGame(size: Int = 6): Game {
// If there is exactly one solution, update clues and reset index. // If there is exactly one solution, update clues and reset index.
clues = temp clues = temp
i = 0 i = 0
} else {
i++
} }
i++
} }
return Game(grid.toGrid(), clues) return Game(grid.toGrid(), clues)

View File

@@ -1,29 +1,20 @@
package ch.dissem.yaep.domain package ch.dissem.yaep.domain
import ch.dissem.yaep.domain.PuzzleSolution.SOLVABLE import ch.dissem.yaep.domain.PuzzleSolution.SOLVABLE
import ch.tutteli.atrium.api.fluent.en_GB.toBeEmpty
import ch.tutteli.atrium.api.fluent.en_GB.toEqual import ch.tutteli.atrium.api.fluent.en_GB.toEqual
import ch.tutteli.atrium.api.verbs.expect import ch.tutteli.atrium.api.verbs.expect
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlin.io.path.Path
import kotlin.io.path.createDirectories
import kotlin.io.path.createFile
import kotlin.io.path.isDirectory
import kotlin.io.path.notExists
import kotlin.io.path.writeText
import kotlin.test.Test import kotlin.test.Test
import kotlin.time.Clock
import kotlin.time.ExperimentalTime import kotlin.time.ExperimentalTime
class GameSolverTest { class GameSolverTest {
private val log = KotlinLogging.logger {}
@Test @Test
@OptIn(ExperimentalTime::class) @OptIn(ExperimentalTime::class)
fun `find problematic clues`() { fun `ensure there are no unnecessary clues`() {
var game: Game var game: Game
var neighbours: List<NeighbourClue<*, *>> var neighbours: List<NeighbourClue<*, *>>
var i = 0 repeat(100) {
do {
game = generateGame() game = generateGame()
val triplets = game.horizontalClues.filterIsInstance<TripletClue<*, *, *>>() val triplets = game.horizontalClues.filterIsInstance<TripletClue<*, *, *>>()
neighbours = game.horizontalClues.filterIsInstance<NeighbourClue<*, *>>() neighbours = game.horizontalClues.filterIsInstance<NeighbourClue<*, *>>()
@@ -32,25 +23,9 @@ class GameSolverTest {
t.contains(n.a) && t.contains(n.b) t.contains(n.a) && t.contains(n.b)
} }
} }
i++ expect(neighbours).toBeEmpty()
log.info { "Found ${neighbours.size} neighbours after $i tries: $neighbours" } expect(game.solve()).toEqual(SOLVABLE)
} while (neighbours.isEmpty())
val dirName = """${System.getProperty("user.home")}/.yaep"""
val dir = Path(dirName)
if (dir.notExists()) {
dir.createDirectories()
} else if (!dir.isDirectory()) {
log.error { "Yaep data directory already exists and is not a directory: $dir" }
log.info { "Game: $game" }
} else {
val fileName = "$dirName/problematic-${Clock.System.now()}.yaep"
Path(fileName)
.createFile()
.writeText(game.toString())
log.info { "Saved game to $fileName" }
} }
} }
fun TripletClue<*, *, *>.contains(item: Item<*>): Boolean { fun TripletClue<*, *, *>.contains(item: Item<*>): Boolean {