clone

fifteen puzzle games for the terminal, with daily puzzles, weekly ladders and xp, built on bubble tea

main
puzzletea / games / takuzuplus / grid.go
grid.go 2.4K
1package takuzuplus23import (4 "strings"56 "github.com/FelineStateMachine/puzzletea/games/takuzu"7)89const (10 emptyCell = takuzu.EmptyCell11 zeroCell = takuzu.ZeroCell12 oneCell = takuzu.OneCell1314 relationNone rune = '.'15 relationSame rune = '='16 relationDiff rune = 'x'17)1819type grid [][]rune2021type relations struct {22 horizontal [][]rune23 vertical [][]rune24}2526func newGridFromState(s string) grid {27 rows := strings.Split(string(s), "\n")28 g := make(grid, len(rows))29 for i, row := range rows {30 g[i] = []rune(row)31 }32 return g33}3435func (g grid) String() string {36 rows := make([]string, len(g))37 for i, row := range g {38 rows[i] = string(row)39 }40 return strings.Join(rows, "\n")41}4243func (g grid) clone() grid {44 clone := make(grid, len(g))45 for y, row := range g {46 clone[y] = make([]rune, len(row))47 copy(clone[y], row)48 }49 return clone50}5152func newRelations(size int) relations {53 r := relations{54 horizontal: make([][]rune, size),55 vertical: make([][]rune, max(size-1, 0)),56 }57 for y := range size {58 r.horizontal[y] = make([]rune, max(size-1, 0))59 for x := range r.horizontal[y] {60 r.horizontal[y][x] = relationNone61 }62 }63 for y := range size - 1 {64 r.vertical[y] = make([]rune, size)65 for x := range r.vertical[y] {66 r.vertical[y][x] = relationNone67 }68 }69 return r70}7172func (r relations) clone() relations {73 clone := newRelations(len(r.horizontal))74 for y := range r.horizontal {75 copy(clone.horizontal[y], r.horizontal[y])76 }77 for y := range r.vertical {78 copy(clone.vertical[y], r.vertical[y])79 }80 return clone81}8283func serializeRuneRows(rows [][]rune) string {84 var b strings.Builder85 for y, row := range rows {86 b.WriteString(string(row))87 if y < len(rows)-1 {88 b.WriteByte('\n')89 }90 }91 return b.String()92}9394func deserializeRuneRows(s string, rows, cols int) [][]rune {95 if rows <= 0 {96 return [][]rune{}97 }9899 parsed := strings.Split(s, "\n")100 out := make([][]rune, rows)101 for y := range rows {102 out[y] = make([]rune, cols)103 for x := range cols {104 out[y][x] = relationNone105 }106 if y >= len(parsed) {107 continue108 }109 runes := []rune(parsed[y])110 for x := 0; x < cols && x < len(runes); x++ {111 out[y][x] = runes[x]112 }113 }114 return out115}116117func countRelations(r relations) int {118 total := 0119 for _, row := range r.horizontal {120 for _, value := range row {121 if value != relationNone {122 total++123 }124 }125 }126 for _, row := range r.vertical {127 for _, value := range row {128 if value != relationNone {129 total++130 }131 }132 }133 return total134}