diff --git a/src/main/java/hse/java/practice/task1/Edge.java b/src/main/java/hse/java/practice/task1/Edge.java index d95ba56b..fe54ca93 100644 --- a/src/main/java/hse/java/practice/task1/Edge.java +++ b/src/main/java/hse/java/practice/task1/Edge.java @@ -31,6 +31,65 @@ public void setParts(CubeColor[][] parts) { this.parts = parts; } + private void swap(int r1, int c1, int r2, int c2) { + CubeColor temp = parts[r2][c2]; + parts[r2][c2] = parts[r1][c1]; + parts[r1][c1] = temp; + } + + private void transpose() { + for (int i = 0; i < 3; i++) { + for (int j = i + 1; j < 3; j++) { + swap(i, j, j, i); + } + } + } + + private void swapHorizontally() { + for (int i = 0; i < 3; i++) { + swap(0, i, 2, i); + } + } + + private void swapVertically() { + for (int i = 0; i < 3; i++) { + swap(i, 0, i, 2); + } + } + + public void rotate(RotateDirection direction) { + transpose(); + if (direction == RotateDirection.CLOCKWISE) { + swapHorizontally(); + } else { + swapVertically(); + } + } + + public CubeColor[] getRow(int i) { + return parts[i].clone(); + } + + public CubeColor[] getColumn(int i) { + CubeColor[] result = new CubeColor[3]; + for (int j = 0; j < 3; j++) { + result[j] = parts[j][i]; + } + return result; + } + + public void setRow(int i, CubeColor[] newRow) { + for (int j = 0; j < 3; j++) { + parts[i][j] = newRow[j]; + } + } + + public void setColumn(int i, CubeColor[] newColumn) { + for (int j = 0; j < 3; j++) { + parts[j][i] = newColumn[j]; + } + } + @Override public String toString() { return Arrays.deepToString(parts); diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index d986f9f0..98f0e771 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -2,23 +2,11 @@ import java.util.Arrays; -/** - * Необходимо реализовать интерфейс Cube - * При повороте передней грани, меняются верх низ право и лево - */ public class RubiksCube implements Cube { private static final int EDGES_COUNT = 6; - private final Edge[] edges = new Edge[EDGES_COUNT]; - /** - * Создать валидный собранный кубик - * грани разместить по ордеру в енуме цветов - * грань 0 -> цвет 0 - * грань 1 -> цвет 1 - * ... - */ public RubiksCube() { CubeColor[] colors = CubeColor.values(); for (int i = 0; i < 6; i++) { @@ -26,34 +14,160 @@ public RubiksCube() { } } - @Override - public void up(RotateDirection direction) { - + private static void reverse(CubeColor[] arr) { + for (int i = 0; i < arr.length / 2; i++) { + CubeColor temp = arr[i]; + arr[i] = arr[arr.length - 1 - i]; + arr[arr.length - 1 - i] = temp; + } } @Override - public void down(RotateDirection direction) { - + public void front(RotateDirection direction) { + edges[EdgePosition.FRONT.ordinal()].rotate(direction); + + CubeColor[] upRow = edges[EdgePosition.UP.ordinal()].getRow(2); + CubeColor[] rightColumn = edges[EdgePosition.RIGHT.ordinal()].getColumn(0); + CubeColor[] downRow = edges[EdgePosition.DOWN.ordinal()].getRow(0); + CubeColor[] leftColumn = edges[EdgePosition.LEFT.ordinal()].getColumn(2); + + if (direction == RotateDirection.CLOCKWISE) { + reverse(leftColumn); + edges[EdgePosition.UP.ordinal()].setRow(2, leftColumn); + edges[EdgePosition.RIGHT.ordinal()].setColumn(0, upRow); + reverse(rightColumn); + edges[EdgePosition.DOWN.ordinal()].setRow(0, rightColumn); + edges[EdgePosition.LEFT.ordinal()].setColumn(2, downRow); + } else { + edges[EdgePosition.UP.ordinal()].setRow(2, rightColumn); + reverse(downRow); + edges[EdgePosition.RIGHT.ordinal()].setColumn(0, downRow); + edges[EdgePosition.DOWN.ordinal()].setRow(0, leftColumn); + reverse(upRow); + edges[EdgePosition.LEFT.ordinal()].setColumn(2, upRow); + } } @Override - public void left(RotateDirection direction) { - + public void back(RotateDirection direction) { + edges[EdgePosition.BACK.ordinal()].rotate(direction); + + CubeColor[] upRow = edges[EdgePosition.UP.ordinal()].getRow(0); + CubeColor[] rightColumn = edges[EdgePosition.RIGHT.ordinal()].getColumn(2); + CubeColor[] downRow = edges[EdgePosition.DOWN.ordinal()].getRow(2); + CubeColor[] leftColumn = edges[EdgePosition.LEFT.ordinal()].getColumn(0); + + if (direction == RotateDirection.CLOCKWISE) { + reverse(rightColumn); + edges[EdgePosition.UP.ordinal()].setRow(0, rightColumn); + edges[EdgePosition.RIGHT.ordinal()].setColumn(2, downRow); + reverse(leftColumn); + edges[EdgePosition.DOWN.ordinal()].setRow(2, leftColumn); + edges[EdgePosition.LEFT.ordinal()].setColumn(0, upRow); + } else { + edges[EdgePosition.UP.ordinal()].setRow(0, leftColumn); + reverse(upRow); + edges[EdgePosition.RIGHT.ordinal()].setColumn(2, upRow); + edges[EdgePosition.DOWN.ordinal()].setRow(2, rightColumn); + reverse(downRow); + edges[EdgePosition.LEFT.ordinal()].setColumn(0, downRow); + } } @Override - public void right(RotateDirection direction) { - + public void up(RotateDirection direction) { + edges[EdgePosition.UP.ordinal()].rotate(direction); + + CubeColor[] frontRow = edges[EdgePosition.FRONT.ordinal()].getRow(0); + CubeColor[] rightRow = edges[EdgePosition.RIGHT.ordinal()].getRow(0); + CubeColor[] backRow = edges[EdgePosition.BACK.ordinal()].getRow(0); + CubeColor[] leftRow = edges[EdgePosition.LEFT.ordinal()].getRow(0); + + if (direction == RotateDirection.CLOCKWISE) { + edges[EdgePosition.FRONT.ordinal()].setRow(0, rightRow); + edges[EdgePosition.RIGHT.ordinal()].setRow(0, backRow); + edges[EdgePosition.BACK.ordinal()].setRow(0, leftRow); + edges[EdgePosition.LEFT.ordinal()].setRow(0, frontRow); + } else { + edges[EdgePosition.FRONT.ordinal()].setRow(0, leftRow); + edges[EdgePosition.RIGHT.ordinal()].setRow(0, frontRow); + edges[EdgePosition.BACK.ordinal()].setRow(0, rightRow); + edges[EdgePosition.LEFT.ordinal()].setRow(0, backRow); + } } @Override - public void front(RotateDirection direction) { - + public void down(RotateDirection direction) { + edges[EdgePosition.DOWN.ordinal()].rotate(direction); + + CubeColor[] frontRow = edges[EdgePosition.FRONT.ordinal()].getRow(2); + CubeColor[] rightRow = edges[EdgePosition.RIGHT.ordinal()].getRow(2); + CubeColor[] backRow = edges[EdgePosition.BACK.ordinal()].getRow(2); + CubeColor[] leftRow = edges[EdgePosition.LEFT.ordinal()].getRow(2); + + if (direction == RotateDirection.CLOCKWISE) { + edges[EdgePosition.FRONT.ordinal()].setRow(2, leftRow); + edges[EdgePosition.RIGHT.ordinal()].setRow(2, frontRow); + edges[EdgePosition.BACK.ordinal()].setRow(2, rightRow); + edges[EdgePosition.LEFT.ordinal()].setRow(2, backRow); + } else { + edges[EdgePosition.FRONT.ordinal()].setRow(2, rightRow); + edges[EdgePosition.RIGHT.ordinal()].setRow(2, backRow); + edges[EdgePosition.BACK.ordinal()].setRow(2, leftRow); + edges[EdgePosition.LEFT.ordinal()].setRow(2, frontRow); + } } @Override - public void back(RotateDirection direction) { + public void left(RotateDirection direction) { + edges[EdgePosition.LEFT.ordinal()].rotate(direction); + + CubeColor[] upColumn = edges[EdgePosition.UP.ordinal()].getColumn(0); + CubeColor[] frontColumn = edges[EdgePosition.FRONT.ordinal()].getColumn(0); + CubeColor[] downColumn = edges[EdgePosition.DOWN.ordinal()].getColumn(0); + CubeColor[] backColumn = edges[EdgePosition.BACK.ordinal()].getColumn(2); + + if (direction == RotateDirection.CLOCKWISE) { + reverse(backColumn); + edges[EdgePosition.UP.ordinal()].setColumn(0, backColumn); + edges[EdgePosition.FRONT.ordinal()].setColumn(0, upColumn); + edges[EdgePosition.DOWN.ordinal()].setColumn(0, frontColumn); + reverse(downColumn); + edges[EdgePosition.BACK.ordinal()].setColumn(2, downColumn); + } else { + edges[EdgePosition.UP.ordinal()].setColumn(0, frontColumn); + edges[EdgePosition.FRONT.ordinal()].setColumn(0, downColumn); + reverse(backColumn); + edges[EdgePosition.DOWN.ordinal()].setColumn(0, backColumn); + reverse(upColumn); + edges[EdgePosition.BACK.ordinal()].setColumn(2, upColumn); + } + } + @Override + public void right(RotateDirection direction) { + edges[EdgePosition.RIGHT.ordinal()].rotate(direction); + + CubeColor[] upColumn = edges[EdgePosition.UP.ordinal()].getColumn(2); + CubeColor[] frontColumn = edges[EdgePosition.FRONT.ordinal()].getColumn(2); + CubeColor[] downColumn = edges[EdgePosition.DOWN.ordinal()].getColumn(2); + CubeColor[] backColumn = edges[EdgePosition.BACK.ordinal()].getColumn(0); + + if (direction == RotateDirection.CLOCKWISE) { + edges[EdgePosition.UP.ordinal()].setColumn(2, frontColumn); + edges[EdgePosition.FRONT.ordinal()].setColumn(2, downColumn); + reverse(backColumn); + edges[EdgePosition.DOWN.ordinal()].setColumn(2, backColumn); + reverse(upColumn); + edges[EdgePosition.BACK.ordinal()].setColumn(0, upColumn); + } else { + reverse(backColumn); + edges[EdgePosition.UP.ordinal()].setColumn(2, backColumn); + edges[EdgePosition.FRONT.ordinal()].setColumn(2, upColumn); + edges[EdgePosition.DOWN.ordinal()].setColumn(2, frontColumn); + reverse(downColumn); + edges[EdgePosition.BACK.ordinal()].setColumn(0, downColumn); + } } public Edge[] getEdges() {