102 lines
2.6 KiB
Kotlin
102 lines
2.6 KiB
Kotlin
package domain
|
|
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.mutableStateOf
|
|
import androidx.compose.runtime.setValue
|
|
import kotlin.math.abs
|
|
|
|
sealed class Clue {
|
|
abstract fun isRuleViolated(grid: Grid): Boolean
|
|
var isActive: Boolean by mutableStateOf(true)
|
|
}
|
|
|
|
sealed class HorizontalClue : Clue()
|
|
|
|
class NeighbourClue<C : ItemClass<C>>(val a: Item<C>, val b: Item<C>) : HorizontalClue() {
|
|
private val aType = a.itemType
|
|
private val bType = b.itemType
|
|
|
|
override fun isRuleViolated(grid: Grid): Boolean {
|
|
val ia = grid.indexOf(aType)
|
|
val ib = grid.indexOf(bType)
|
|
|
|
if (ia == -1 || ib == -1) return false
|
|
|
|
return abs(ia - ib) != 1
|
|
}
|
|
}
|
|
|
|
class OrderClue<C : ItemClass<C>>(val left: Item<C>, val right: Item<C>) : HorizontalClue() {
|
|
private val leftType = left.itemType
|
|
private val rightType = right.itemType
|
|
|
|
override fun isRuleViolated(grid: Grid): Boolean {
|
|
val il = grid.indexOf(leftType)
|
|
val ir = grid.indexOf(rightType)
|
|
|
|
if (il == -1 || ir == -1) return false
|
|
|
|
return ir <= il
|
|
}
|
|
}
|
|
|
|
class TripletClue<C : ItemClass<C>>(val a: Item<C>, val b: Item<C>, val c: Item<C>) :
|
|
HorizontalClue() {
|
|
private val aType = a.itemType
|
|
private val bType = b.itemType
|
|
private val cType = c.itemType
|
|
|
|
private fun isNeighbourRuleViolated(ix: Int, iy: Int): Boolean {
|
|
if (ix == -1 || iy == -1) return false
|
|
return abs(ix - iy) != 1
|
|
}
|
|
|
|
override fun isRuleViolated(grid: Grid): Boolean {
|
|
val ia = grid.indexOf(aType)
|
|
val ib = grid.indexOf(bType)
|
|
val ic = grid.indexOf(cType)
|
|
|
|
if (ia == -1 && ic == -1) {
|
|
return false
|
|
}
|
|
|
|
if (ia != -1 && ic != -1) {
|
|
if (ia + 2 == ic || ia == ic + 2) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
if (isNeighbourRuleViolated(ia, ib) || isNeighbourRuleViolated(ib, ic)) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
}
|
|
|
|
class SameRowClue<C : ItemClass<C>>(val a: Item<C>, val b: Item<C>) : Clue() {
|
|
private val aType = a.itemType
|
|
private val bType = b.itemType
|
|
|
|
override fun isRuleViolated(grid: Grid): Boolean {
|
|
val ia = grid.indexOf(aType)
|
|
val ib = grid.indexOf(bType)
|
|
|
|
if (ia == -1 || ib == -1) return false
|
|
|
|
return ia != ib
|
|
}
|
|
}
|
|
|
|
class PositionClue<C : ItemClass<C>>(val item: Item<C>, val index: Int) : Clue() {
|
|
private val aType = item.itemType
|
|
|
|
override fun isRuleViolated(grid: Grid): Boolean {
|
|
val ia = grid.indexOf(aType)
|
|
|
|
if (ia == -1) return false
|
|
|
|
return ia != index
|
|
}
|
|
}
|