This commit is contained in:
2026-06-08 17:48:16 +02:00
parent 4759179c56
commit 9965821560
+114 -6
View File
@@ -1,6 +1,7 @@
package rubiks_ga
import "core:fmt"
import "core:math/rand"
// first, to solve a rubik's cube can mean different things. namely, if i am given a particular
// configuration of the cube, and memorize some precomputed steps that takes me to the terminal
@@ -60,12 +61,119 @@ import "core:fmt"
// be [dynamic; 5]Instruction, but
// argh who cares, let's try something
main :: proc() {
x: [dynamic; 5]int
fmt.println(x)
for i in 0 ..< 10 {
append(&x, i)
fmt.println(x)
solution := solved_cube()
defer delete(solution)
arr := [2][4]int{{0, 1, 2, 3}, {4, 5, 6, 7}}
fmt.println(arr)
fmt.println(rotate(arr))
}
/////////////////////////////////
/// RUBIKS CUBE STATE MACHINE ///
/////////////////////////////////
Face :: enum u8 {
Right,
Left,
Up,
Down,
Front,
Back,
}
Color :: enum u8 {
Red,
Green,
White,
Blue,
Orange,
Yellow,
}
Cube :: map[Instruction]([3][3]Color)
solved_cube :: proc(allocator := context.allocator) -> (c: Cube) {
c = make(Cube)
for f in Instruction {
face_colors: [3][3]Color
for i in 0 ..< 3 {
for j in 0 ..< 3 {
switch f {
case .Right:
face_colors[i][j] = .Red
case .Left:
face_colors[i][j] = .Orange
case .Up:
face_colors[i][j] = .White
case .Down:
face_colors[i][j] = .Yellow
case .Front:
face_colors[i][j] = .Green
case .Back:
face_colors[i][j] = .Blue
}
}
}
c[f] = face_colors
}
return
}
rotate :: proc(arr: [$row][$col]$T) -> (res: [col][row]T) {
for i in 0 ..< row {
for j in 0 ..< col {
res[j][i] = arr[row - 1 - i][j]
}
}
return
}
// only fundamental instructions; pseudo-instructions only complicate the implementation
Instruction :: distinct Face
perform_instruction :: proc(c: ^Cube, instr: Face) {
switch instr {
case .Left:
c[.Left] = rotate(c[.Left])
// TODO: repair
case .Right:
c[.Right] = rotate(c[.Right])
case .Up:
c[.Up] = rotate(c[.Up])
case .Down:
c[.Down] = rotate(c[.Down])
case .Front:
c[.Front] = rotate(c[.Front])
case .Back:
c[.Back] = rotate(c[.Back])
}
}
/////////////////////////
/// GENETIC ALGORITHM ///
/////////////////////////
// god's number is 20 for normal notation, 26 for mine. give margin, choose 32 for memory layout
MAX_STEPS :: 32
POPULATION_SIZE :: 512
Chromosome :: [dynamic; MAX_STEPS]Face
Population :: [dynamic; POPULATION_SIZE]Chromosome
create_population :: proc(size: int) -> (pop: Population) {
for len(pop) < size {
chrom: Chromosome
num_steps := int(rand.norm_float64() * cap(chrom))
for len(chrom) < num_steps {
i := rand.int_max(len(Face))
append(&chrom, Face(i))
}
append(&pop, chrom)
}
return
}
// TODO: generation step
// TODO: fitness calculation