diff options
author | Nat Lasseter <nat.lasseter@exa.net.uk> | 2019-07-16 11:14:38 +0100 |
---|---|---|
committer | Nat Lasseter <nat.lasseter@exa.net.uk> | 2019-07-16 11:14:38 +0100 |
commit | ac3bf7d594a515dcd238c8e369960b89720f26c1 (patch) | |
tree | 3cb575c81b8bb91ab148e1f3e0ec66acff7f5c63 /cube |
Initial commit
Diffstat (limited to 'cube')
-rw-r--r-- | cube/cube.go | 129 | ||||
-rw-r--r-- | cube/turns.go | 190 |
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 "[97mW[0m" + case Yellow: + return "[97mY[0m" + case Red: + return "[97mR[0m" + case Orange: + return "[97mO[0m" + case Blue: + return "[97mB[0m" + case Green: + return "[97mG[0m" + } + 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) +} |