aboutsummaryrefslogtreecommitdiff
path: root/cube
diff options
context:
space:
mode:
authorNat Lasseter <nat.lasseter@exa.net.uk>2019-07-16 11:14:38 +0100
committerNat Lasseter <nat.lasseter@exa.net.uk>2019-07-16 11:14:38 +0100
commitac3bf7d594a515dcd238c8e369960b89720f26c1 (patch)
tree3cb575c81b8bb91ab148e1f3e0ec66acff7f5c63 /cube
Initial commit
Diffstat (limited to 'cube')
-rw-r--r--cube/cube.go129
-rw-r--r--cube/turns.go190
2 files changed, 319 insertions, 0 deletions
diff --git a/cube/cube.go b/cube/cube.go
new file mode 100644
index 0000000..f52cf8f
--- /dev/null
+++ b/cube/cube.go
@@ -0,0 +1,129 @@
+package cube
+
+import (
+ "errors"
+ "strings"
+)
+
+type colour uint8
+
+const (
+ White colour = iota
+ Yellow
+ Red
+ Orange
+ Blue
+ Green
+)
+
+func (c colour) String() string {
+ switch c {
+ case White:
+ return "W"
+ case Yellow:
+ return "Y"
+ case Red:
+ return "R"
+ case Orange:
+ return "O"
+ case Blue:
+ return "B"
+ case Green:
+ return "G"
+ }
+ return ""
+}
+
+type row []colour
+
+func (r row) String() (s string) {
+ for i := range r {
+ s += r[i].String()
+ }
+ return
+}
+
+type face []row
+
+func (f face) colGet(c int) (r row) {
+ r = make(row, len(f))
+ for i := 0; i < len(f); i++ {
+ r[i] = f[i][c]
+ }
+ return
+}
+
+func (f *face) colSet(c int, r row) {
+ for i := 0; i < len(*f); i++ {
+ (*f)[i][c] = r[i]
+ }
+}
+
+type Cube struct {
+ front face
+ back face
+ top face
+ bottom face
+ left face
+ right face
+}
+
+func New(size int) (*Cube, error) {
+ if size < 1 {
+ return nil, errors.New("Size must be greater than 0.")
+ }
+ var c Cube
+ c.front = make(face, size)
+ c.back = make(face, size)
+ c.top = make(face, size)
+ c.bottom = make(face, size)
+ c.left = make(face, size)
+ c.right = make(face, size)
+
+ for i := 0; i < size; i++ {
+ c.front[i] = make(row, size)
+ c.back[i] = make(row, size)
+ c.top[i] = make(row, size)
+ c.bottom[i] = make(row, size)
+ c.left[i] = make(row, size)
+ c.right[i] = make(row, size)
+
+ for j := 0; j < size; j++ {
+ c.front[i][j] = Red
+ c.back[i][j] = Orange
+ c.top[i][j] = White
+ c.bottom[i][j] = Yellow
+ c.left[i][j] = Green
+ c.right[i][j] = Blue
+ }
+ }
+
+ return &c, nil
+}
+
+func (c Cube) Size() int {
+ return len(c.front)
+}
+
+func (c Cube) String() (r string) {
+ s := strings.Repeat(" ", c.Size()+2)
+
+ for i := 0; i < c.Size(); i++ {
+ r += s + c.top[i].String() + "\n"
+ }
+ r += "\n"
+
+ for i := 0; i < c.Size(); i++ {
+ r += c.left[i].String() + " " +
+ c.front[i].String() + " " +
+ c.right[i].String() + " " +
+ c.back[i].String() + "\n"
+ }
+ r += "\n"
+
+ for i := 0; i < c.Size(); i++ {
+ r += s + c.bottom[i].String() + "\n"
+ }
+
+ return
+}
diff --git a/cube/turns.go b/cube/turns.go
new file mode 100644
index 0000000..2129f26
--- /dev/null
+++ b/cube/turns.go
@@ -0,0 +1,190 @@
+package cube
+
+func (a *row) flip() {
+ for left, right := 0, len(*a)-1; left < right; left, right = left+1, right-1 {
+ (*a)[left], (*a)[right] = (*a)[right], (*a)[left]
+ }
+}
+
+func (f *face) transpose() {
+ l := len(*f)
+ nf := make(face, l)
+
+ for i := 0; i < l; i++ {
+ nf[i] = make(row, l)
+ for j := 0; j < l; j++ {
+ nf[i][j] = (*f)[j][i]
+ }
+ }
+
+ for i := 0; i < l; i++ {
+ for j := 0; j < l; j++ {
+ (*f)[i][j] = nf[i][j]
+ }
+ }
+}
+
+func (f *face) clockwise() {
+ f.transpose()
+
+ for i := 0; i < len(*f); i++ {
+ (*f)[i].flip()
+ }
+}
+
+func (f *face) _clockwise() {
+ for i := 0; i < len(*f); i++ {
+ (*f)[i].flip()
+ }
+
+ f.transpose()
+}
+
+func (c *Cube) Y(layer int) {
+ _layer := c.Size() - layer - 1
+
+ if layer == 0 {
+ c.top.clockwise()
+ } else if _layer == 0 {
+ c.bottom._clockwise()
+ }
+
+ temp := c.front[layer]
+ c.front[layer] = c.right[layer]
+ c.right[layer] = c.back[layer]
+ c.back[layer] = c.left[layer]
+ c.left[layer] = temp
+}
+
+func (c *Cube) Y_(layer int) {
+ _layer := c.Size() - layer - 1
+
+ if layer == 0 {
+ c.top._clockwise()
+ } else if _layer == 0 {
+ c.bottom.clockwise()
+ }
+
+ temp := c.front[layer]
+ c.front[layer] = c.left[layer]
+ c.left[layer] = c.back[layer]
+ c.back[layer] = c.right[layer]
+ c.right[layer] = temp
+}
+
+func (c *Cube) U() {
+ c.Y(0)
+}
+func (c *Cube) U_() {
+ c.Y_(0)
+}
+
+func (c *Cube) D() {
+ c.Y_(c.Size() - 1)
+}
+func (c *Cube) D_() {
+ c.Y(c.Size() - 1)
+}
+
+func (c *Cube) Z(layer int) {
+ _layer := c.Size() - layer - 1
+
+ if layer == 0 {
+ c.front.clockwise()
+ } else if _layer == 0 {
+ c.back._clockwise()
+ }
+
+ temp := c.top[_layer]
+ c.top[_layer] = c.left.colGet(_layer)
+ c.top[_layer].flip()
+ c.left.colSet(_layer, c.bottom[layer])
+ c.bottom[layer] = c.right.colGet(layer)
+ c.bottom[layer].flip()
+ c.right.colSet(layer, temp)
+}
+
+func (c *Cube) Z_(layer int) {
+ _layer := c.Size() - layer - 1
+
+ if layer == 0 {
+ c.front._clockwise()
+ } else if _layer == 0 {
+ c.back.clockwise()
+ }
+
+ temp := c.top[_layer]
+ c.top[_layer] = c.right.colGet(layer)
+ c.bottom[layer].flip()
+ c.right.colSet(layer, c.bottom[layer])
+ c.bottom[layer] = c.left.colGet(layer)
+ temp.flip()
+ c.left.colSet(_layer, temp)
+}
+
+func (c *Cube) F() {
+ c.Z(0)
+}
+func (c *Cube) F_() {
+ c.Z_(0)
+}
+
+func (c *Cube) B() {
+ c.Z_(c.Size() - 1)
+}
+func (c *Cube) B_() {
+ c.Z(c.Size() - 1)
+}
+
+func (c *Cube) X(layer int) {
+ _layer := c.Size() - layer - 1
+
+ if layer == 0 {
+ c.right.clockwise()
+ } else if _layer == 0 {
+ c.left._clockwise()
+ }
+
+ temp := c.top.colGet(_layer)
+ temp.flip()
+ c.top.colSet(_layer, c.front.colGet(_layer))
+ c.front.colSet(_layer, c.bottom.colGet(_layer))
+ t := c.back.colGet(layer)
+ t.flip()
+ c.bottom.colSet(_layer, t)
+ c.back.colSet(layer, temp)
+}
+
+func (c *Cube) X_(layer int) {
+ _layer := c.Size() - layer - 1
+
+ if layer == 0 {
+ c.right._clockwise()
+ } else if _layer == 0 {
+ c.left.clockwise()
+ }
+
+ temp := c.top.colGet(_layer)
+ t := c.back.colGet(layer)
+ t.flip()
+ c.top.colSet(_layer, t)
+ t = c.bottom.colGet(_layer)
+ t.flip()
+ c.back.colSet(layer, t)
+ c.bottom.colSet(_layer, c.front.colGet(_layer))
+ c.front.colSet(_layer, temp)
+}
+
+func (c *Cube) R() {
+ c.X(0)
+}
+func (c *Cube) R_() {
+ c.X_(0)
+}
+
+func (c *Cube) L() {
+ c.X_(c.Size() - 1)
+}
+func (c *Cube) L_() {
+ c.X(c.Size() - 1)
+}