summaryrefslogtreecommitdiff
path: root/core/src/commonMain/kotlin/coffee/liz/rookery/algs/AlgSets.kt
blob: 2309d97c5110ecb3b4c69ce5c3bdaba81225b1f6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package coffee.liz.rookery.algs

import coffee.liz.rookery.puzzle.Notation
import coffee.liz.rookery.puzzle.NxnCube

/** One case of an algorithm set, with the algorithms people use for it (the first is the usual one). */
data class AlgCase(val set: String, val name: String, val group: String, val probability: Int, val algs: List<String>) {
    val id: String get() = "$set:$name"

    /**
     * The cube showing this case, last layer up, as you would hold it before doing [alg]: a solved
     * cube with the algorithm undone. An algorithm with a net rotation (say it starts with `x`)
     * leaves the centres somewhere else, so colours are renamed after whichever centre they sit on.
     */
    fun state(alg: String = algs.first()): NxnCube {
        val c = NxnCube(3).apply(Notation.invert(clean(alg)))
        val rename = IntArray(6)
        for (f in 0 until 6) rename[c.stickers[f * 9 + 4]] = f
        for (i in c.stickers.indices) c.stickers[i] = rename[c.stickers[i]]
        return c
    }

    /** Moves that set this case up from a solved cube. */
    fun setup(alg: String = algs.first()): String = Notation.invert(clean(alg))

    companion object {
        fun clean(alg: String) = alg.replace("(", " ").replace(")", " ").trim().replace(Regex("\\s+"), " ")
    }
}

enum class AlgStatus { NEW, LEARNING, KNOWN }

object AlgSets {
    val names: List<String> get() = ALG_DATA.keys.toList()
    fun cases(set: String): List<AlgCase> = ALG_DATA[set].orEmpty()
    fun find(id: String): AlgCase? = cases(id.substringBefore(':')).firstOrNull { it.id == id }

    /**
     * The last layer seen from above, as 5x5 cells of colour indices (-1 = empty corner): the U face
     * in the middle and the top row of each side around it, front at the bottom.
     */
    fun plan(c: NxnCube): Array<IntArray> {
        val s = c.stickers
        val g = Array(5) { IntArray(5) { -1 } }
        for (r in 0 until 3) for (k in 0 until 3) g[r + 1][k + 1] = s[r * 3 + k]              // U
        for (k in 0 until 3) {
            g[4][k + 1] = s[2 * 9 + k]            // F, left to right
            g[0][k + 1] = s[5 * 9 + (2 - k)]      // B, seen from above
            g[k + 1][4] = s[1 * 9 + (2 - k)]      // R, back to front
            g[k + 1][0] = s[4 * 9 + k]            // L, back to front
        }
        return g
    }
}