-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
101 changed files
with
2,961 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/FillSingleCage.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
import org.piepmeyer.gauguin.creation.cage.GridCageType | ||
import org.piepmeyer.gauguin.grid.Grid | ||
|
||
class FillSingleCage { | ||
fun fillCells(grid: Grid): Int { | ||
val cagesToBeFilled = grid.cages.filter { it.cageType == GridCageType.SINGLE && !it.getCell(0).isUserValueSet } | ||
|
||
var filledCells = 0 | ||
|
||
cagesToBeFilled.forEach { | ||
grid.setUserValueAndRemovePossibles(it.getCell(0), it.result) | ||
|
||
filledCells++ | ||
} | ||
|
||
return filledCells | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/GridLine.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
import org.piepmeyer.gauguin.grid.Grid | ||
import org.piepmeyer.gauguin.grid.GridCage | ||
import org.piepmeyer.gauguin.grid.GridCell | ||
|
||
data class GridLine( | ||
private val grid: Grid, | ||
val type: GridLineType, | ||
val lineNumber: Int, | ||
) { | ||
fun contains(cell: GridCell): Boolean = | ||
when (type) { | ||
GridLineType.COLUMN -> cell.column == lineNumber | ||
GridLineType.ROW -> cell.row == lineNumber | ||
} | ||
|
||
fun cells(): List<GridCell> = grid.cells.filter { contains(it) } | ||
|
||
fun cages(): Set<GridCage> = | ||
grid.cells | ||
.filter { contains(it) } | ||
.map { it.cage!! } | ||
.toSet() | ||
|
||
override fun toString(): String = "GridLine type=$type, lineNumber=$lineNumber" | ||
} |
6 changes: 6 additions & 0 deletions
6
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/GridLineType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
enum class GridLineType { | ||
COLUMN, | ||
ROW, | ||
} |
79 changes: 79 additions & 0 deletions
79
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/GridLines.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
import org.piepmeyer.gauguin.grid.Grid | ||
|
||
class GridLines( | ||
private val grid: Grid, | ||
) { | ||
fun allLines(): Set<GridLine> { | ||
val lines = mutableSetOf<GridLine>() | ||
|
||
for (column in 0..<grid.gridSize.width) { | ||
lines += GridLine(grid, GridLineType.COLUMN, column) | ||
} | ||
|
||
for (row in 0..<grid.gridSize.height) { | ||
lines += GridLine(grid, GridLineType.ROW, row) | ||
} | ||
|
||
return lines | ||
} | ||
|
||
fun linesWithEachPossibleValue(): Set<GridLine> { | ||
val lines = mutableSetOf<GridLine>() | ||
|
||
if (grid.gridSize.height == grid.gridSize.largestSide()) { | ||
for (column in 0..<grid.gridSize.width) { | ||
lines += GridLine(grid, GridLineType.COLUMN, column) | ||
} | ||
} | ||
|
||
if (grid.gridSize.width == grid.gridSize.largestSide()) { | ||
for (row in 0..<grid.gridSize.height) { | ||
lines += GridLine(grid, GridLineType.ROW, row) | ||
} | ||
} | ||
|
||
return lines | ||
} | ||
|
||
fun adjacentlinesWithEachPossibleValue(numberOfLines: Int): Set<Set<GridLine>> { | ||
val lines = mutableSetOf<Set<GridLine>>() | ||
|
||
if (grid.gridSize.height == grid.gridSize.largestSide()) { | ||
for (column in 0..<grid.gridSize.width - numberOfLines + 1) { | ||
lines += | ||
(column..<column + numberOfLines).map { GridLine(grid, GridLineType.COLUMN, it) }.toSet() | ||
} | ||
} | ||
|
||
if (grid.gridSize.width == grid.gridSize.largestSide()) { | ||
for (row in 0..<grid.gridSize.height - numberOfLines + 1) { | ||
lines += | ||
setOf( | ||
(row..<row + numberOfLines).map { GridLine(grid, GridLineType.ROW, it) }.toSet(), | ||
) | ||
} | ||
} | ||
|
||
return lines.toSet() | ||
} | ||
|
||
fun adjacentlines(numberOfLines: Int): Set<Set<GridLine>> { | ||
val lines = mutableSetOf<Set<GridLine>>() | ||
|
||
for (column in 0..<grid.gridSize.width - numberOfLines + 1) { | ||
lines += | ||
(column..<column + numberOfLines).map { GridLine(grid, GridLineType.COLUMN, it) }.toSet() | ||
} | ||
|
||
for (row in 0..<grid.gridSize.height - numberOfLines + 1) { | ||
lines += | ||
setOf( | ||
(row..<row + numberOfLines).map { GridLine(grid, GridLineType.ROW, it) }.toSet(), | ||
) | ||
} | ||
|
||
return lines.toSet() | ||
} | ||
} |
68 changes: 68 additions & 0 deletions
68
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/HumanSolver.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
import io.github.oshai.kotlinlogging.KotlinLogging | ||
import org.piepmeyer.gauguin.grid.Grid | ||
import org.piepmeyer.gauguin.grid.GridCell | ||
|
||
private val logger = KotlinLogging.logger {} | ||
|
||
class HumanSolver( | ||
private val grid: Grid, | ||
private val validate: Boolean = false, | ||
) { | ||
private val humanSolverStrategy = | ||
HumanSolverStrategies.entries | ||
|
||
private val cache = PossiblesCache(grid) | ||
|
||
fun solveAndCalculateDifficulty(): HumanSolverResult { | ||
var progress: HumanSolverStep | ||
var success = true | ||
var difficulty = FillSingleCage().fillCells(grid) * 1 | ||
|
||
cache.initialize() | ||
|
||
do { | ||
cache.validateEntries() | ||
progress = doProgress() | ||
|
||
if (progress.success) { | ||
difficulty += progress.difficulty | ||
} else if (!grid.isSolved()) { | ||
success = false | ||
|
||
logger.info { "Sad about grid:\n$grid" } | ||
} | ||
} while (progress.success && !grid.isSolved()) | ||
|
||
return HumanSolverResult(success, difficulty) | ||
} | ||
|
||
private fun doProgress(): HumanSolverStep { | ||
humanSolverStrategy.forEach { | ||
val progress = it.solver.fillCells(grid, cache) | ||
|
||
if (progress) { | ||
logger.info { "Added ${it.difficulty} from ${it.solver::class.simpleName}" } | ||
|
||
if (validate && | ||
(grid.numberOfMistakes() != 0 || grid.cells.any { !it.isUserValueSet && it.possibles.isEmpty() }) | ||
) { | ||
logger.error { "Last step introduced errors." } | ||
throw IllegalStateException("Found a grid with wrong values.") | ||
} | ||
|
||
return HumanSolverStep(true, it.difficulty) | ||
} | ||
} | ||
|
||
return HumanSolverStep(false, 0) | ||
} | ||
|
||
fun prepareGrid() { | ||
grid.cells.forEach { | ||
it.possibles = grid.variant.possibleDigits | ||
it.userValue = GridCell.NO_VALUE_SET | ||
} | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/HumanSolverResult.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
data class HumanSolverResult( | ||
val success: Boolean, | ||
val difficulty: Int, | ||
) |
6 changes: 6 additions & 0 deletions
6
gauguin-core/src/main/kotlin/org/piepmeyer/gauguin/difficulty/human/HumanSolverStep.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package org.piepmeyer.gauguin.difficulty.human | ||
|
||
data class HumanSolverStep( | ||
val success: Boolean, | ||
val difficulty: Int, | ||
) |
Oops, something went wrong.