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>(val a: Item, val b: Item) : 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>(val left: Item, val right: Item) : 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>(val a: Item, val b: Item, val c: Item) : 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>(val a: Item, val b: Item) : 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>(val item: Item, 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 } }