From 9499db1c55e45b56ebb1a7dc5356eafa6bef817b Mon Sep 17 00:00:00 2001 From: Satlykovs Date: Fri, 6 Feb 2026 13:50:18 +0300 Subject: [PATCH 1/4] feat: Practice1 task finished --- .../hse/java/practice/task1/RubiksCube.java | 243 +++++++++++++++++- 1 file changed, 236 insertions(+), 7 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 2091b657..1b75a607 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -2,11 +2,13 @@ import java.util.Arrays; + /** * Необходимо реализовать интерфейс Cube * При повороте передней грани, меняются верх низ право и лево */ -public class RubiksCube { +public class RubiksCube implements Cube +{ private static final int EDGES_COUNT = 6; @@ -19,23 +21,250 @@ public class RubiksCube { * грань 1 -> цвет 1 * ... */ - public RubiksCube() { + public RubiksCube() + { CubeColor[] colors = CubeColor.values(); - for (int i = 0; i < 6; i++) { + for (int i = 0; i < 6; i++) + { edges[i] = new Edge(colors[i]); } } - public void front(RotateDirection direction) { + @Override + public void up(RotateDirection direction) + { + if (direction == RotateDirection.COUNTERCLOCKWISE) + { + up(RotateDirection.CLOCKWISE); + up(RotateDirection.CLOCKWISE); + up(RotateDirection.CLOCKWISE); + return; + } + + rotateFaceMatrix(EdgePosition.UP); + + CubeColor[][] front = getMatrix(EdgePosition.FRONT); + CubeColor[][] left = getMatrix(EdgePosition.LEFT); + CubeColor[][] back = getMatrix(EdgePosition.BACK); + CubeColor[][] right = getMatrix(EdgePosition.RIGHT); + + CubeColor[] tmp = new CubeColor[3]; + + for (int i = 0; i < 3; ++i) tmp[i] = front[0][i]; + + for (int i = 0; i < 3; ++i) front[0][i] = right[0][i]; + + for (int i = 0; i < 3; ++i) right[0][i] = back[0][i]; + + for (int i = 0; i < 3; ++i) back[0][i] = left[0][i]; + + for (int i = 0; i < 3; ++i) left[0][i] = tmp[i]; + } + + @Override + public void down(RotateDirection direction) + { + if (direction == RotateDirection.COUNTERCLOCKWISE) + { + down(RotateDirection.CLOCKWISE); + down(RotateDirection.CLOCKWISE); + down(RotateDirection.CLOCKWISE); + return; + } + + rotateFaceMatrix(EdgePosition.DOWN); + + CubeColor[][] front = getMatrix(EdgePosition.FRONT); + CubeColor[][] right = getMatrix(EdgePosition.RIGHT); + CubeColor[][] back = getMatrix(EdgePosition.BACK); + CubeColor[][] left = getMatrix(EdgePosition.LEFT); + + CubeColor[] tmp = new CubeColor[3]; + + for (int i = 0; i < 3; ++i) tmp[i] = front[2][i]; + + for (int i = 0; i < 3; ++i) front[2][i] = left[2][i]; + + for (int i = 0; i < 3; ++i) left[2][i] = back[2][i]; + + for (int i = 0; i < 3; ++i) back[2][i] = right[2][i]; + + for (int i = 0; i < 3; ++i) right[2][i] = tmp[i]; } - - public Edge[] getEdges() { + + @Override + public void left(RotateDirection direction) + { + if (direction == RotateDirection.COUNTERCLOCKWISE) + { + left(RotateDirection.CLOCKWISE); + left(RotateDirection.CLOCKWISE); + left(RotateDirection.CLOCKWISE); + return; + } + + rotateFaceMatrix(EdgePosition.LEFT); + + CubeColor[][] up = getMatrix(EdgePosition.UP); + CubeColor[][] front = getMatrix(EdgePosition.FRONT); + CubeColor[][] down = getMatrix(EdgePosition.DOWN); + CubeColor[][] back = getMatrix(EdgePosition.BACK); + + CubeColor[] tmp = new CubeColor[3]; + + for (int i = 0; i < 3; ++i) tmp[i] = up[i][0]; + + for (int i = 0; i < 3; i++) up[i][0] = back[2 - i][2]; + + for (int i = 0; i < 3; i++) back[i][2] = down[2 - i][0]; + + for (int i = 0; i < 3; i++) down[i][0] = front[i][0]; + + for (int i = 0; i < 3; i++) front[i][0] = tmp[i]; + + } + + @Override + public void right(RotateDirection direction) { + if (direction == RotateDirection.COUNTERCLOCKWISE) { + right(RotateDirection.CLOCKWISE); + right(RotateDirection.CLOCKWISE); + right(RotateDirection.CLOCKWISE); + return; + } + + rotateFaceMatrix(EdgePosition.RIGHT); + + + CubeColor[][] up = getMatrix(EdgePosition.UP); + CubeColor[][] back = getMatrix(EdgePosition.BACK); + CubeColor[][] down = getMatrix(EdgePosition.DOWN); + CubeColor[][] front = getMatrix(EdgePosition.FRONT); + + CubeColor[] temp = new CubeColor[3]; + + for (int i = 0; i < 3; i++) temp[i] = up[i][2]; + + for (int i = 0; i < 3; i++) up[i][2] = front[i][2]; + + for (int i = 0; i < 3; i++) front[i][2] = down[i][2]; + + for (int i = 0; i < 3; i++) down[i][2] = back[2 - i][0]; + + for (int i = 0; i < 3; i++) back[i][0] = temp[2 - i]; + } + + public void front(RotateDirection direction) + { + if (direction == RotateDirection.COUNTERCLOCKWISE) + { + front(RotateDirection.CLOCKWISE); + front(RotateDirection.CLOCKWISE); + front(RotateDirection.CLOCKWISE); + return; + } + + rotateFaceMatrix(EdgePosition.FRONT); + + CubeColor[][] up = getMatrix(EdgePosition.UP); + CubeColor[][] right = getMatrix(EdgePosition.RIGHT); + CubeColor[][] down = getMatrix(EdgePosition.DOWN); + CubeColor[][] left = getMatrix(EdgePosition.LEFT); + + + CubeColor[] tmp = new CubeColor[3]; + + for (int i = 0; i < 3; ++i) tmp[i] = up[2][i]; + + for (int i = 0; i < 3; ++i) up[2][i] = left[2 - i][2]; + + for (int i = 0; i < 3; ++i) left[i][2] = down[0][i]; + + for (int i = 0; i < 3; ++i) down[0][i] = right[2 - i][0]; + + for (int i = 0; i < 3; ++i) right[i][0] = tmp[i]; + + } + + @Override + public void back(RotateDirection direction) + { + if (direction == RotateDirection.COUNTERCLOCKWISE) + { + back(RotateDirection.CLOCKWISE); + back(RotateDirection.CLOCKWISE); + back(RotateDirection.CLOCKWISE); + return; + } + + rotateFaceMatrix(EdgePosition.BACK); + + CubeColor[][] up = getMatrix(EdgePosition.UP); + CubeColor[][] left = getMatrix(EdgePosition.LEFT); + CubeColor[][] down = getMatrix(EdgePosition.DOWN); + CubeColor[][] right = getMatrix(EdgePosition.RIGHT); + + CubeColor[] tmp = new CubeColor[3]; + + for (int i = 0; i < 3; ++i) tmp[i] = up[0][i]; + + for (int i = 0; i < 3; ++i) up[0][i] = right[i][2]; + + for (int i = 0; i < 3; ++i) right[i][2] = down[2][2 - i]; + + for (int i = 0; i < 3; ++i) down[2][i] = left[i][0]; + + for (int i = 0; i < 3; ++i) left[i][0] = tmp[2 - i]; + } + + public Edge[] getEdges() + { return edges; } @Override - public String toString() { + public String toString() + { return Arrays.toString(edges); } + + + private CubeColor[][] getMatrix(EdgePosition pos) + { + return edges[pos.ordinal()].getParts(); + } + + private void rotateFaceMatrix(EdgePosition pos) + { + CubeColor[][] matrix = getMatrix(pos); + + transpose(matrix); + reverseRows(matrix); + + } + + + private void transpose(CubeColor[][] matrix) + { + for (int i = 0; i < 3; ++i) + { + for (int j = i + 1; j < 3; j++) + { + CubeColor tmp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = tmp; + } + } + } + + private void reverseRows(CubeColor[][] matrix) + { + for (int i = 0; i < 3; i++) + { + CubeColor tmp = matrix[i][0]; + matrix[i][0] = matrix[i][2]; + matrix[i][2] = tmp; + } + } } From b00d6532e2b98410865ce9cd437264699c24a38e Mon Sep 17 00:00:00 2001 From: Satlykovs Date: Fri, 6 Feb 2026 14:29:15 +0300 Subject: [PATCH 2/4] refactor: Hold my templates --- .../hse/java/practice/task1/RubiksCube.java | 235 +++++++++--------- 1 file changed, 114 insertions(+), 121 deletions(-) diff --git a/src/main/java/hse/java/practice/task1/RubiksCube.java b/src/main/java/hse/java/practice/task1/RubiksCube.java index 1b75a607..b89cd17b 100644 --- a/src/main/java/hse/java/practice/task1/RubiksCube.java +++ b/src/main/java/hse/java/practice/task1/RubiksCube.java @@ -1,6 +1,7 @@ package hse.java.practice.task1; import java.util.Arrays; +import java.util.function.Consumer; /** @@ -30,35 +31,64 @@ public RubiksCube() } } + private void rotateSides(SideLine s0, SideLine s1, SideLine s2, SideLine s3) + { + CubeColor[] line0 = getLine(s0); + CubeColor[] line1 = getLine(s1); + CubeColor[] line2 = getLine(s2); + CubeColor[] line3 = getLine(s3); + + setLine(s1, line0); + setLine(s2, line1); + setLine(s3, line2); + setLine(s0, line3); + } + + private CubeColor[] getLine(SideLine s) + { + CubeColor[][] matrix = getMatrix(s.pos); + CubeColor[] res = new CubeColor[3]; + for (int i = 0; i < 3; ++i) + { + res[i] = s.isRow ? matrix[s.idx][i] : matrix[i][s.idx]; + } + if (s.rev) + { + CubeColor tmp = res[0]; + res[0] = res[2]; + res[2] = tmp; + } + return res; + } + + private void setLine(SideLine s, CubeColor[] vals) + { + CubeColor[][] matrix = getMatrix(s.pos); + CubeColor[] data = s.rev ? new CubeColor[]{vals[2], vals[1], vals[0]} : vals; + + for (int i = 0; i < 3; ++i) + { + if (s.isRow) matrix[s.idx][i] = data[i]; + else matrix[i][s.idx] = data[i]; + } + } + @Override public void up(RotateDirection direction) { if (direction == RotateDirection.COUNTERCLOCKWISE) { - up(RotateDirection.CLOCKWISE); - up(RotateDirection.CLOCKWISE); - up(RotateDirection.CLOCKWISE); + rotate3(this::up); return; } rotateFaceMatrix(EdgePosition.UP); - - CubeColor[][] front = getMatrix(EdgePosition.FRONT); - CubeColor[][] left = getMatrix(EdgePosition.LEFT); - CubeColor[][] back = getMatrix(EdgePosition.BACK); - CubeColor[][] right = getMatrix(EdgePosition.RIGHT); - - CubeColor[] tmp = new CubeColor[3]; - - for (int i = 0; i < 3; ++i) tmp[i] = front[0][i]; - - for (int i = 0; i < 3; ++i) front[0][i] = right[0][i]; - - for (int i = 0; i < 3; ++i) right[0][i] = back[0][i]; - - for (int i = 0; i < 3; ++i) back[0][i] = left[0][i]; - - for (int i = 0; i < 3; ++i) left[0][i] = tmp[i]; + rotateSides( + new SideLine(EdgePosition.FRONT, 0, true, false), + new SideLine(EdgePosition.LEFT, 0, true, false), + new SideLine(EdgePosition.BACK, 0, true, false), + new SideLine(EdgePosition.RIGHT, 0, true, false) + ); } @Override @@ -66,30 +96,18 @@ public void down(RotateDirection direction) { if (direction == RotateDirection.COUNTERCLOCKWISE) { - down(RotateDirection.CLOCKWISE); - down(RotateDirection.CLOCKWISE); - down(RotateDirection.CLOCKWISE); + rotate3(this::down); return; } rotateFaceMatrix(EdgePosition.DOWN); - CubeColor[][] front = getMatrix(EdgePosition.FRONT); - CubeColor[][] right = getMatrix(EdgePosition.RIGHT); - CubeColor[][] back = getMatrix(EdgePosition.BACK); - CubeColor[][] left = getMatrix(EdgePosition.LEFT); - - CubeColor[] tmp = new CubeColor[3]; - - for (int i = 0; i < 3; ++i) tmp[i] = front[2][i]; - - for (int i = 0; i < 3; ++i) front[2][i] = left[2][i]; - - for (int i = 0; i < 3; ++i) left[2][i] = back[2][i]; - - for (int i = 0; i < 3; ++i) back[2][i] = right[2][i]; - - for (int i = 0; i < 3; ++i) right[2][i] = tmp[i]; + rotateSides( + new SideLine(EdgePosition.FRONT, 2, true, false), + new SideLine(EdgePosition.RIGHT, 2, true, false), + new SideLine(EdgePosition.BACK, 2, true, false), + new SideLine(EdgePosition.LEFT, 2, true, false) + ); } @@ -98,92 +116,56 @@ public void left(RotateDirection direction) { if (direction == RotateDirection.COUNTERCLOCKWISE) { - left(RotateDirection.CLOCKWISE); - left(RotateDirection.CLOCKWISE); - left(RotateDirection.CLOCKWISE); + rotate3(this::left); return; } rotateFaceMatrix(EdgePosition.LEFT); - CubeColor[][] up = getMatrix(EdgePosition.UP); - CubeColor[][] front = getMatrix(EdgePosition.FRONT); - CubeColor[][] down = getMatrix(EdgePosition.DOWN); - CubeColor[][] back = getMatrix(EdgePosition.BACK); - - CubeColor[] tmp = new CubeColor[3]; - - for (int i = 0; i < 3; ++i) tmp[i] = up[i][0]; - - for (int i = 0; i < 3; i++) up[i][0] = back[2 - i][2]; - - for (int i = 0; i < 3; i++) back[i][2] = down[2 - i][0]; - - for (int i = 0; i < 3; i++) down[i][0] = front[i][0]; - - for (int i = 0; i < 3; i++) front[i][0] = tmp[i]; + rotateSides( + new SideLine(EdgePosition.UP, 0, false, false), + new SideLine(EdgePosition.FRONT, 0, false, false), + new SideLine(EdgePosition.DOWN, 0, false, false), + new SideLine(EdgePosition.BACK, 2, false, true) + ); } @Override - public void right(RotateDirection direction) { - if (direction == RotateDirection.COUNTERCLOCKWISE) { - right(RotateDirection.CLOCKWISE); - right(RotateDirection.CLOCKWISE); - right(RotateDirection.CLOCKWISE); + public void right(RotateDirection direction) + { + if (direction == RotateDirection.COUNTERCLOCKWISE) + { + rotate3(this::right); return; } rotateFaceMatrix(EdgePosition.RIGHT); - - CubeColor[][] up = getMatrix(EdgePosition.UP); - CubeColor[][] back = getMatrix(EdgePosition.BACK); - CubeColor[][] down = getMatrix(EdgePosition.DOWN); - CubeColor[][] front = getMatrix(EdgePosition.FRONT); - - CubeColor[] temp = new CubeColor[3]; - - for (int i = 0; i < 3; i++) temp[i] = up[i][2]; - - for (int i = 0; i < 3; i++) up[i][2] = front[i][2]; - - for (int i = 0; i < 3; i++) front[i][2] = down[i][2]; - - for (int i = 0; i < 3; i++) down[i][2] = back[2 - i][0]; - - for (int i = 0; i < 3; i++) back[i][0] = temp[2 - i]; + rotateSides( + new SideLine(EdgePosition.UP, 2, false, false), + new SideLine(EdgePosition.BACK, 0, false, true), + new SideLine(EdgePosition.DOWN, 2, false, false), + new SideLine(EdgePosition.FRONT, 2, false, false) + ); } public void front(RotateDirection direction) { if (direction == RotateDirection.COUNTERCLOCKWISE) { - front(RotateDirection.CLOCKWISE); - front(RotateDirection.CLOCKWISE); - front(RotateDirection.CLOCKWISE); + rotate3(this::front); return; } rotateFaceMatrix(EdgePosition.FRONT); - CubeColor[][] up = getMatrix(EdgePosition.UP); - CubeColor[][] right = getMatrix(EdgePosition.RIGHT); - CubeColor[][] down = getMatrix(EdgePosition.DOWN); - CubeColor[][] left = getMatrix(EdgePosition.LEFT); - - - CubeColor[] tmp = new CubeColor[3]; - - for (int i = 0; i < 3; ++i) tmp[i] = up[2][i]; - - for (int i = 0; i < 3; ++i) up[2][i] = left[2 - i][2]; - - for (int i = 0; i < 3; ++i) left[i][2] = down[0][i]; - - for (int i = 0; i < 3; ++i) down[0][i] = right[2 - i][0]; - - for (int i = 0; i < 3; ++i) right[i][0] = tmp[i]; + rotateSides( + new SideLine(EdgePosition.UP, 2, true, false), + new SideLine(EdgePosition.RIGHT, 0, false, false), + new SideLine(EdgePosition.DOWN, 0, true, true), + new SideLine(EdgePosition.LEFT, 2, false, true) + ); } @@ -192,30 +174,18 @@ public void back(RotateDirection direction) { if (direction == RotateDirection.COUNTERCLOCKWISE) { - back(RotateDirection.CLOCKWISE); - back(RotateDirection.CLOCKWISE); - back(RotateDirection.CLOCKWISE); + rotate3(this::back); return; } rotateFaceMatrix(EdgePosition.BACK); - CubeColor[][] up = getMatrix(EdgePosition.UP); - CubeColor[][] left = getMatrix(EdgePosition.LEFT); - CubeColor[][] down = getMatrix(EdgePosition.DOWN); - CubeColor[][] right = getMatrix(EdgePosition.RIGHT); - - CubeColor[] tmp = new CubeColor[3]; - - for (int i = 0; i < 3; ++i) tmp[i] = up[0][i]; - - for (int i = 0; i < 3; ++i) up[0][i] = right[i][2]; - - for (int i = 0; i < 3; ++i) right[i][2] = down[2][2 - i]; - - for (int i = 0; i < 3; ++i) down[2][i] = left[i][0]; - - for (int i = 0; i < 3; ++i) left[i][0] = tmp[2 - i]; + rotateSides( + new SideLine(EdgePosition.UP, 0, true, true), + new SideLine(EdgePosition.LEFT, 0, false, false), + new SideLine(EdgePosition.DOWN, 2, true, false), + new SideLine(EdgePosition.RIGHT, 2, false, true) + ); } public Edge[] getEdges() @@ -229,7 +199,6 @@ public String toString() return Arrays.toString(edges); } - private CubeColor[][] getMatrix(EdgePosition pos) { return edges[pos.ordinal()].getParts(); @@ -244,7 +213,6 @@ private void rotateFaceMatrix(EdgePosition pos) } - private void transpose(CubeColor[][] matrix) { for (int i = 0; i < 3; ++i) @@ -267,4 +235,29 @@ private void reverseRows(CubeColor[][] matrix) matrix[i][2] = tmp; } } + + private void rotate3(Consumer f) + { + f.accept(RotateDirection.CLOCKWISE); + f.accept(RotateDirection.CLOCKWISE); + f.accept(RotateDirection.CLOCKWISE); + } + + private static class SideLine + { + EdgePosition pos; + int idx; + boolean isRow; + boolean rev; + + SideLine(EdgePosition p, int i, boolean row, boolean r) + { + pos = p; + idx = i; + isRow = row; + rev = r; + } + } + + } From fbf515a788cc2210f7e48a0f5328450cb362ac64 Mon Sep 17 00:00:00 2001 From: Satlykovs Date: Sat, 7 Feb 2026 13:35:11 +0300 Subject: [PATCH 3/4] feat: ATM task --- .../java/hse/java/lectures/lecture1/Game.java | 153 +++++++++- .../java/lectures/lecture2/task/Const.java | 28 ++ .../lectures/lecture2/task/IntExpression.java | 6 + .../hse/java/lectures/lecture2/task/Main.java | 19 ++ .../lectures/lecture2/task/Operation.java | 24 ++ .../hse/java/lectures/lecture2/task/Sub.java | 15 + .../hse/java/lectures/lecture2/task/Sum.java | 18 ++ .../java/lectures/lecture3/tasks/atm/Atm.java | 154 ++++++++-- src/test/java/hse/java/BaseTest.java | 2 +- .../java/practice/task1/CubeSimpleTest.java | 277 ++++++++++++++++++ 10 files changed, 659 insertions(+), 37 deletions(-) create mode 100644 src/main/java/hse/java/lectures/lecture2/task/Const.java create mode 100644 src/main/java/hse/java/lectures/lecture2/task/IntExpression.java create mode 100644 src/main/java/hse/java/lectures/lecture2/task/Main.java create mode 100644 src/main/java/hse/java/lectures/lecture2/task/Operation.java create mode 100644 src/main/java/hse/java/lectures/lecture2/task/Sub.java create mode 100644 src/main/java/hse/java/lectures/lecture2/task/Sum.java create mode 100644 src/test/java/hse/java/practice/task1/CubeSimpleTest.java diff --git a/src/main/java/hse/java/lectures/lecture1/Game.java b/src/main/java/hse/java/lectures/lecture1/Game.java index bf85f916..65950bca 100644 --- a/src/main/java/hse/java/lectures/lecture1/Game.java +++ b/src/main/java/hse/java/lectures/lecture1/Game.java @@ -2,27 +2,160 @@ import javax.swing.*; import java.awt.*; +import java.util.Random; +import java.util.concurrent.atomic.AtomicBoolean; -public class Game { - public static void main(String[] args) { + +public class Game +{ + + private static boolean checkWin(char[][] board, char sym) + { + for (int row = 0; row < 3; ++row) + { + if (board[row][0] == sym && board[row][1] == sym && board[row][2] == sym) + { + return true; + } + } + + for (int col = 0; col < 3; ++col) + { + if (board[0][col] == sym && board[1][col] == sym && board[2][col] == sym) + { + return true; + } + } + + if (board[0][0] == sym && board[1][1] == sym && board[2][2] == sym) return true; + if (board[0][2] == sym && board[1][1] == sym && board[2][0] == sym) return true; + + return false; + + } + + private static boolean isBoardFull(char[][] board) + { + for (int row = 0; row < 3; row++) + { + for (int col = 0; col < 3; col++) + { + if (board[row][col] == 0) return false; + } + } + return true; + } + + private static void botMove(JButton[][] buttons, char[][] board, Random random) + { + while (true) + { + int i = random.nextInt(3); + int j = random.nextInt(3); + if (board[i][j] == 0) + { + buttons[i][j].setText("O"); + board[i][j] = 'O'; + break; + } + } + } + + public static void main(String[] args) + { JFrame frame = new JFrame("XO"); + JLabel statusLabel = new JLabel("Your turn:", SwingConstants.CENTER); + frame.add(statusLabel, BorderLayout.NORTH); frame.setSize(300, 300); frame.setLocation(200, 200); + JButton[][] buttons = new JButton[3][3]; - JPanel panel = new JPanel(new GridLayout(3,3)); - for (int i = 0; i < 9; i++) { - JButton button = new JButton(); - button.addActionListener(a -> { - button.setText("X"); - }); - panel.add(button); + char[][] board = new char[3][3]; + + Random random = new Random(); + + + JPanel panel = new JPanel(new GridLayout(3, 3)); + + + AtomicBoolean gameActive = new AtomicBoolean(true); + AtomicBoolean playerTurn = new AtomicBoolean(true); + + + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + buttons[i][j] = new JButton(); + + int row = i; + int col = j; + + buttons[i][j].addActionListener(a -> + { + if (!gameActive.get() || !playerTurn.get() || !buttons[row][col].getText() + .isEmpty()) + { + return; + } + + buttons[row][col].setText("X"); + board[row][col] = 'X'; + + if (checkWin(board, 'X')) + { + gameActive.set(false); + statusLabel.setText("You win!"); + return; + + } else if (isBoardFull(board)) + { + gameActive.set(false); + statusLabel.setText("Draw"); + return; + } + + playerTurn.set(false); + + statusLabel.setText("Bot turn:"); + + Timer timer = new Timer(500, e -> + { + botMove(buttons, board, random); + + playerTurn.set(true); + + if (checkWin(board, 'O')) + { + gameActive.set(false); + statusLabel.setText("Bot win!"); + } else if (isBoardFull(board)) + { + gameActive.set(false); + statusLabel.setText("Draw"); + } else + { + statusLabel.setText("Your turn"); + } + }); + timer.setRepeats(false); + timer.start(); + }); + + panel.add(buttons[i][j]); + + + } } + frame.add(panel); - JDialog dialog; + frame.setVisible(true); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } } + diff --git a/src/main/java/hse/java/lectures/lecture2/task/Const.java b/src/main/java/hse/java/lectures/lecture2/task/Const.java new file mode 100644 index 00000000..547bb160 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture2/task/Const.java @@ -0,0 +1,28 @@ +package hse.java.lectures.lecture2.task; + + +public class Const implements IntExpression +{ + + private final int value; + + public Const(int value) + { + this.value = value; + } + + + @Override + public int eval() + { + return value; + } + + @Override + public String toString() + { + return Integer.toString(value); + } + + +} diff --git a/src/main/java/hse/java/lectures/lecture2/task/IntExpression.java b/src/main/java/hse/java/lectures/lecture2/task/IntExpression.java new file mode 100644 index 00000000..c826d604 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture2/task/IntExpression.java @@ -0,0 +1,6 @@ +package hse.java.lectures.lecture2.task; + +public interface IntExpression { + String toString(); + int eval(); +} diff --git a/src/main/java/hse/java/lectures/lecture2/task/Main.java b/src/main/java/hse/java/lectures/lecture2/task/Main.java new file mode 100644 index 00000000..a7a5037f --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture2/task/Main.java @@ -0,0 +1,19 @@ +package hse.java.lectures.lecture2.task; + + + + +public class Main { + + + + public static void main(String[] args) + { + IntExpression expr1 = new Sum(new Sum(new Const(2), new Const(3)), new Const(100)); + + + System.out.println(expr1.toString() + "=" + expr1.eval()); + + + } +} \ No newline at end of file diff --git a/src/main/java/hse/java/lectures/lecture2/task/Operation.java b/src/main/java/hse/java/lectures/lecture2/task/Operation.java new file mode 100644 index 00000000..749a1ece --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture2/task/Operation.java @@ -0,0 +1,24 @@ +package hse.java.lectures.lecture2.task; + + +public abstract class Operation implements IntExpression +{ + + protected final IntExpression left; + protected final IntExpression right; + private final String operationSymbol; + + protected Operation(IntExpression left, IntExpression right, String operationSymbol) + { + this.left = left; + this.right = right; + this.operationSymbol = operationSymbol; + } + + + @Override + public String toString() + { + return "(" + left.toString() + operationSymbol + right.toString() + ")"; + } +} diff --git a/src/main/java/hse/java/lectures/lecture2/task/Sub.java b/src/main/java/hse/java/lectures/lecture2/task/Sub.java new file mode 100644 index 00000000..e3e3eba1 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture2/task/Sub.java @@ -0,0 +1,15 @@ +package hse.java.lectures.lecture2.task; + +public class Sub extends Operation +{ + protected Sub(IntExpression left, IntExpression right) + { + super(left, right, "-"); + } + + @Override + public int eval() + { + return left.eval() - right.eval(); + } +} diff --git a/src/main/java/hse/java/lectures/lecture2/task/Sum.java b/src/main/java/hse/java/lectures/lecture2/task/Sum.java new file mode 100644 index 00000000..2cfd1060 --- /dev/null +++ b/src/main/java/hse/java/lectures/lecture2/task/Sum.java @@ -0,0 +1,18 @@ +package hse.java.lectures.lecture2.task; + + + +public class Sum extends Operation +{ + + protected Sum(IntExpression left, IntExpression right) + { + super(left, right, "+"); + } + + @Override + public int eval() + { + return left.eval() + right.eval(); + } +} diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java index 3fa91909..a2317791 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java +++ b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java @@ -1,44 +1,146 @@ package hse.java.lectures.lecture3.tasks.atm; -import java.util.Collections; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -public class Atm { - private enum Denomination { - D50(50), - D100(100), - D500(500), - D1000(1000), - D5000(5000); +import java.util.*; - private final int value; +public class Atm +{ + private static final Map IntToDenom = new HashMap<>(); - Denomination(int value) { - this.value = value; + + private final Map banknotes = new EnumMap<>(Denomination.class); + + public Atm() + { + for (Denomination d : Denomination.values()) + { + banknotes.put(d, 0); } + } + + public void deposit(Map banknotes) + { + + if (banknotes == null) throw new InvalidDepositException("Banknotes is null"); + for (var banknote : banknotes.entrySet()) + { + int value = banknote.getKey(); + int count = banknote.getValue(); + + if (count <= 0) throw new InvalidDepositException("Count must be positive. Your " + + "count: " + count); + + + if (Denomination.getDenomFromValue(value) == null) throw new InvalidDepositException( + "Invalid nominal value: " + value); + + + } + + for (var banknote : banknotes.entrySet()) + { + Denomination d = Denomination.getDenomFromValue(banknote.getKey()); + + this.banknotes.put(d, this.banknotes.get(d) + banknote.getValue()); + - int value() { - return value; } } - private final Map banknotes = new EnumMap<>(Denomination.class); + public Map withdraw(int amount) + { + if (amount <= 0) + throw new InvalidAmountException("Amount ust be positive. Your amount: " + amount); + + if (amount > getBalance()) throw new InsufficientFundsException("Not enough money in ATM"); + + Map moneySet = new EnumMap<>(Denomination.class); + + int remaining = amount; + + List sortedDenoms = new ArrayList<>(List.of(Denomination.values())); + sortedDenoms.sort(Comparator.comparingInt(Denomination::value).reversed()); + + for (Denomination d : sortedDenoms) + { + int availableCnt = this.banknotes.get(d); + + if (availableCnt > 0 && remaining >= d.value) + { + int needed = remaining / d.value; + + int canTake = Math.min(needed, availableCnt); + + moneySet.put(d, canTake); + remaining -= d.value * canTake; + } + } + + if (remaining != 0) throw new CannotDispenseException("Can't dispense suck amount of " + + "money"); + + Map res = new HashMap<>(); + for (var banknote : moneySet.entrySet()) + { + Denomination d = banknote.getKey(); + int cnt = banknote.getValue(); + + this.banknotes.put(d, this.banknotes.get(d) - cnt); + + res.put(d.value, cnt); + } + return res; - public Atm() { } - public void deposit(Map banknotes){} + public int getBalance() + { + int balance = 0; - public Map withdraw(int amount) { - return Map.of(); + for (var banknote : banknotes.entrySet()) + { + int cnt = banknote.getValue(); + int value = banknote.getKey().value; + + balance += cnt * value; + } + return balance; } - public int getBalance() { - return 0; + private enum Denomination + { + D50(50), + D100(100), + D500(500), + D1000(1000), + D5000(5000); + + private static final HashMap intToDenom = new HashMap<>(); + + static + { + for (Denomination d : values()) + { + intToDenom.put(d.value(), d); + } + } + + private final int value; + + + Denomination(int value) + { + this.value = value; + } + + static Denomination getDenomFromValue(int value) + { + return intToDenom.get(value); + } + + int value() + { + return value; + } } } diff --git a/src/test/java/hse/java/BaseTest.java b/src/test/java/hse/java/BaseTest.java index 45385341..b20e7b6f 100644 --- a/src/test/java/hse/java/BaseTest.java +++ b/src/test/java/hse/java/BaseTest.java @@ -6,6 +6,6 @@ public class BaseTest { @Test void test() { - + } } diff --git a/src/test/java/hse/java/practice/task1/CubeSimpleTest.java b/src/test/java/hse/java/practice/task1/CubeSimpleTest.java new file mode 100644 index 00000000..b13c4af7 --- /dev/null +++ b/src/test/java/hse/java/practice/task1/CubeSimpleTest.java @@ -0,0 +1,277 @@ +package hse.java.practice.task1; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +public class CubeSimpleTest { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + @Test + void printTest() { + RubiksCube cube = new RubiksCube(); + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(color, colors[i]); + } + } + } + } + + @Test + void frontClockwise() { + RubiksCube cube = new RubiksCube(); + cube.front(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("frontClockwieseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void frontCounterclockwise() { + RubiksCube cube = new RubiksCube(); + // Поворот против часовой стрелки = 3 поворота по часовой стрелке + cube.front(RotateDirection.COUNTERCLOCKWISE); + + // Проверяем, что 4 поворота против часовой возвращают в исходное состояние + cube.front(RotateDirection.COUNTERCLOCKWISE); + cube.front(RotateDirection.COUNTERCLOCKWISE); + cube.front(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void upClockwise() { + RubiksCube cube = new RubiksCube(); + cube.up(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("upClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void upCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.up(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void downClockwise() { + RubiksCube cube = new RubiksCube(); + cube.down(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("downClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void downCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.down(RotateDirection.COUNTERCLOCKWISE); + cube.down(RotateDirection.COUNTERCLOCKWISE); + cube.down(RotateDirection.COUNTERCLOCKWISE); + cube.down(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void leftClockwise() { + RubiksCube cube = new RubiksCube(); + cube.left(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("leftClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void leftCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.left(RotateDirection.COUNTERCLOCKWISE); + cube.left(RotateDirection.COUNTERCLOCKWISE); + cube.left(RotateDirection.COUNTERCLOCKWISE); + cube.left(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void rightClockwise() { + RubiksCube cube = new RubiksCube(); + cube.right(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("rightClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void rightCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void backClockwise() { + RubiksCube cube = new RubiksCube(); + cube.back(RotateDirection.CLOCKWISE); + + CubeColor[][][] state = readStateFromFile("backClockwiseState.json"); + + CubeColor[][][] actuallyState = Arrays.stream(cube.getEdges()) + .map(Edge::getParts) + .toArray(CubeColor[][][]::new); + + Assertions.assertArrayEquals(state, actuallyState); + } + + @Test + void backCounterclockwise() { + RubiksCube cube = new RubiksCube(); + cube.back(RotateDirection.COUNTERCLOCKWISE); + cube.back(RotateDirection.COUNTERCLOCKWISE); + cube.back(RotateDirection.COUNTERCLOCKWISE); + cube.back(RotateDirection.COUNTERCLOCKWISE); + + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + @Test + void combinedRotations() { + RubiksCube cube = new RubiksCube(); + + // Выполняем последовательность поворотов + cube.front(RotateDirection.CLOCKWISE); + cube.right(RotateDirection.CLOCKWISE); + cube.up(RotateDirection.CLOCKWISE); + + // Выполняем обратную последовательность + cube.up(RotateDirection.COUNTERCLOCKWISE); + cube.right(RotateDirection.COUNTERCLOCKWISE); + cube.front(RotateDirection.COUNTERCLOCKWISE); + + // Должны вернуться в исходное состояние + CubeColor[] colors = CubeColor.values(); + for (int i = 0; i < 6; i++) { + Edge edge = cube.getEdges()[i]; + CubeColor[][] edgeColors = edge.getParts(); + for (CubeColor[] row : edgeColors) { + for (CubeColor color : row) { + Assertions.assertEquals(colors[i], color); + } + } + } + } + + private CubeColor[][][] readStateFromFile(String fileName) { + String resourcePath = "hse/java/practice/task1/" + fileName; + try (InputStream is = CubeSimpleTest.class.getClassLoader().getResourceAsStream(resourcePath)) { + if (is == null) { + throw new IllegalArgumentException("Resource not found: " + resourcePath); + } + String json = new String(is.readAllBytes(), StandardCharsets.UTF_8); + return MAPPER.readValue(json, CubeColor[][][].class); + } catch (IOException e) { + throw new RuntimeException("Failed to read/parse state file: " + fileName, e); + } + } +} From a4b4a170f09d1df806382aa0566f141c4ba3ab92 Mon Sep 17 00:00:00 2001 From: Satlykovs Date: Sat, 7 Feb 2026 14:04:10 +0300 Subject: [PATCH 4/4] fix: =( --- src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java index d84776b8..bb634ee9 100644 --- a/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java +++ b/src/main/java/hse/java/lectures/lecture3/tasks/atm/Atm.java @@ -12,9 +12,9 @@ public Atm() { } - public void deposit(Map banknotes) {} + public void deposit(Map banknotes) {} - public Map withdraw(int amount) + public Map withdraw(int amount) { return Map.of(); } @@ -24,7 +24,7 @@ public int getBalance() return 0; } - private enum Denomination + public enum Denomination { D50(50), D100(100),