From ac3bf7d594a515dcd238c8e369960b89720f26c1 Mon Sep 17 00:00:00 2001 From: Nat Lasseter Date: Tue, 16 Jul 2019 11:14:38 +0100 Subject: Initial commit --- cube/cube.go | 129 +++++++++++++++++++++++++++++++++++++++ cube/turns.go | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 319 insertions(+) create mode 100644 cube/cube.go create mode 100644 cube/turns.go (limited to 'cube') 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) +} -- cgit v1.2.1