diff --git a/README.md b/README.md
index 5d686e9f..cb6ee53b 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,26 @@
# Java Core June 2021
-## *Nikolaev Artem*
+## *Tom Shandrikov*
| Number | Solution | Short description
| --- | --- | --- |
-| HW1 | [Console printer](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/master/src/main/java/homework_1) | The app that reads input arguments and prints them, until "error" argument |
+| HW1 | [Console printer](./src/main/java/homework_1) | This console app prints our words and number of letters until your input equals "error". |
+| HW2.1 | [Traffic Light](./src/main/java/homework_2/traffic_light) | This console app reads an integer of seconds and prints a color of traffic light.|
+| HW2.2 | [Pyramid Printer](./src/main/java/homework_2/pyramid_printer) | This console app prints a pyramid of "x". |
+| HW2.3 | [Random Chars Table](./src/main/java/homework_2/random_chars_table) | This console app makes a table of chars from A to Z and shows evens/odds of them depending on the strategy we have chosen. |
+| HW3.1 | [Immutable class](./src/main/java/homework_3) | This is an example of simple immutable class. |
+| HW3.2 | [JUnit Tests](./src/test/java/homework_2) | Tests for homework2. |
+| HW4.1 | [CustomFileReader](./src/main/java/homework_4/customFileReader) | Here you can see 4 different ways to read text from file.txt. |
+| HW4.2 | [Singleton](./src/main/java/homework_4/singleton) | Here are Basic and Thread-safe examples of Singleton. |
+| HW4.2 | [CustomAnnotation](./src/main/java/homework_4/customAnnotation) | This is an example of creating and using custom Annotations. |
+| HW5.1 | [PowerOfNumber](./src/main/java/homework_5/powerOfNumber) | This console app realizes Math.pow(int base, int n) method using recursion. |
+| HW5.2 | [CustomRegexMatcher](./src/main/java/homework_5/customRegexMatcher) | This console app verifies custom email with regex. |
+| HW6 | [MapProblemsGenerator](./src/main/java/homework_6/mapProblemsGenerator) | Here you can find example of incorrect hash method overriding and a case where we can loose information in our map. |
+| HW7 | [KittenToCatFunction](./src/main/java/homework_7/kittenToCatFunction) | This is an example of realization my functional interface that takes a Kitty as a parameter and returns a Cat. |
+| course_project | [Sea Battle](./src/main/java/course_project/sea_battle) | Course project "Sea Battle Game" is here. You can find description and rules in file: rules.txt. |
+
+[Link to my CodingBat](https://codingbat.com/done?user=ashandrikov@gmail.com&tag=8115696431)
+
+[Link to markdown giude (article)](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
+[Link to markdown giude (video)](https://www.youtube.com/watch?v=FFBTGdEMrQ4)
-[Link to markdown giude](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)
diff --git a/build.gradle b/build.gradle
index b91dc843..820ef2b2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,8 +10,16 @@ repositories {
}
dependencies {
+ compileOnly 'org.projectlombok:lombok:1.18.20'
+ annotationProcessor 'org.projectlombok:lombok:1.18.20'
+
+ testCompileOnly 'org.projectlombok:lombok:1.18.20'
+ testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
+
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
+
+ testCompile("org.junit.jupiter:junit-jupiter-params:5.7.0")
}
test {
diff --git a/src/main/java/course_project/sea_battle/GamePlayUpd.png b/src/main/java/course_project/sea_battle/GamePlayUpd.png
new file mode 100644
index 00000000..3c829327
Binary files /dev/null and b/src/main/java/course_project/sea_battle/GamePlayUpd.png differ
diff --git a/src/main/java/course_project/sea_battle/Main.java b/src/main/java/course_project/sea_battle/Main.java
new file mode 100644
index 00000000..56a1518a
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/Main.java
@@ -0,0 +1,9 @@
+package course_project.sea_battle;
+
+import course_project.sea_battle.controller.GameController;
+
+public class Main {
+ public static void main(String[] args) {
+ new GameController().start();
+ }
+}
diff --git a/src/main/java/course_project/sea_battle/boards/Board.java b/src/main/java/course_project/sea_battle/boards/Board.java
new file mode 100644
index 00000000..b4c65744
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/boards/Board.java
@@ -0,0 +1,24 @@
+package course_project.sea_battle.boards;
+
+public abstract class Board {
+
+ protected int[][] board;
+
+ public void setBasicGrids() {
+ board = new int[10][10];
+ for (int i = 0; i < 10; i++) {
+ for (int j = 0; j < 10; j++) {
+ board[i][j] = 0;
+ }
+ }
+ }
+
+ public int[][] getBoard() {
+ return board;
+ }
+
+ public void setBoard(int[][] board) {
+ this.board = board;
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/boards/MyBoard.java b/src/main/java/course_project/sea_battle/boards/MyBoard.java
new file mode 100644
index 00000000..836e0ae1
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/boards/MyBoard.java
@@ -0,0 +1,17 @@
+package course_project.sea_battle.boards;
+
+import course_project.sea_battle.model.Point;
+import course_project.sea_battle.model.Ship;
+
+import java.util.List;
+
+public class MyBoard extends Board {
+
+ public void placeShip(Ship ship) {
+ List coordinates = ship.getCoordinates();
+ for (Point point : coordinates) {
+ board[point.getX()][point.getY()] = 1;
+ }
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/controller/GameController.java b/src/main/java/course_project/sea_battle/controller/GameController.java
new file mode 100644
index 00000000..b4d29fa5
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/controller/GameController.java
@@ -0,0 +1,78 @@
+package course_project.sea_battle.controller;
+
+import course_project.sea_battle.boards.MyBoard;
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.model.Ship;
+import course_project.sea_battle.service.inputs.InputShipReader;
+import course_project.sea_battle.service.GameModeAndNameSetter;
+import course_project.sea_battle.service.inputs.InputShooterReader;
+import course_project.sea_battle.service.ShipPlacer;
+
+import java.util.Scanner;
+
+import static course_project.sea_battle.utils.Constants.*;
+
+public class GameController extends Thread {
+
+ private final Scanner scanner = new Scanner(System.in);
+ private final InputShipReader inputShipReader = new InputShipReader(scanner);
+
+ private Player player1;
+ private Player player2;
+
+ public GameController() {
+ this.player1 = new Player(new MyBoard(), new MyBoard());
+ this.player2 = new Player(new MyBoard(), new MyBoard());
+ }
+
+ @Override
+ public void run() {
+ setUpNames();
+ setUpShips();
+ play();
+ defineWinner();
+ }
+
+ public void setUpNames() {
+ new GameModeAndNameSetter(inputShipReader).setNames(player1, player2);
+ }
+
+ public void setUpShips() {
+ new ShipPlacer(inputShipReader).placeShip(player1, player2);
+ new ShipPlacer(inputShipReader).placeShip(player2, player1);
+ }
+
+ public void play() {
+ while (bothPlayersHaveShips(player1, player2)) {
+ new InputShooterReader(scanner).checkAndValidatePlayerShot(player1, player2);
+ new InputShooterReader(scanner).checkAndValidatePlayerShot(player2, player1);
+ }
+ }
+
+ public boolean bothPlayersHaveShips(Player player1, Player player2) {
+ return countShips(player1) > 0 && countShips(player2) > 0;
+ }
+
+ public long countShips(Player player) {
+ return player.getMyShips().stream().filter(Ship::isAlive).count();
+ }
+
+ public void defineWinner() {
+ if (countShips(player1) == 0 && countShips(player2) == 0) {
+ System.out.println(TIE);
+ } else if (countShips(player1) == 0) {
+ System.out.println(GAMEOVER + player2.getName() + "!");
+ } else if (countShips(player2) == 0) {
+ System.out.println(GAMEOVER + player1.getName() + "!");
+ }
+ }
+
+ public Player getPlayer1() {
+ return player1;
+ }
+
+ public Player getPlayer2() {
+ return player2;
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/model/Player.java b/src/main/java/course_project/sea_battle/model/Player.java
new file mode 100644
index 00000000..fe489abb
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/model/Player.java
@@ -0,0 +1,53 @@
+package course_project.sea_battle.model;
+
+import course_project.sea_battle.boards.MyBoard;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Player {
+ private String name;
+ private MyBoard myBoard;
+ private MyBoard myShots;
+ private boolean isComputer;
+ private final List myShips = new ArrayList<>();
+
+ public Player(MyBoard myBoard, MyBoard enemyBoard) {
+ this.myBoard = myBoard;
+ this.myShots = enemyBoard;
+ myBoard.setBasicGrids();
+ myShots.setBasicGrids();
+ }
+
+ public long countShips() {
+ return getMyShips().stream().filter(Ship::isAlive).count();
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getMyShips() {
+ return myShips;
+ }
+
+ public MyBoard getMyBoard() {
+ return myBoard;
+ }
+
+ public MyBoard getMyShots() {
+ return myShots;
+ }
+
+ public boolean isComputer() {
+ return isComputer;
+ }
+
+ public void setComputer(boolean computer) {
+ isComputer = computer;
+ }
+}
diff --git a/src/main/java/course_project/sea_battle/model/Point.java b/src/main/java/course_project/sea_battle/model/Point.java
new file mode 100644
index 00000000..ab58e2da
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/model/Point.java
@@ -0,0 +1,29 @@
+package course_project.sea_battle.model;
+
+import lombok.Data;
+
+@Data
+public class Point {
+ private final int x;
+ private final int y;
+
+ @Override
+ public String toString() {
+ return "[" + x +
+ "," + y +
+ "]";
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ Point point = (Point) o;
+ return x == point.x && y == point.y;
+ }
+
+ @Override
+ public int hashCode() {
+ return Integer.hashCode(x) + Integer.hashCode(y);
+ }
+}
diff --git a/src/main/java/course_project/sea_battle/model/Ship.java b/src/main/java/course_project/sea_battle/model/Ship.java
new file mode 100644
index 00000000..36704528
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/model/Ship.java
@@ -0,0 +1,30 @@
+package course_project.sea_battle.model;
+
+import java.util.List;
+
+public class Ship {
+ private final List coordinates;
+ private int lives;
+
+ public Ship(List coordinates) {
+ this.coordinates = coordinates;
+ this.lives = coordinates.size();
+ }
+
+ public int getLives() {
+ return lives;
+ }
+
+ public void setLives(int lives) {
+ this.lives = lives;
+ }
+
+ public boolean isAlive() {
+ return lives > 0;
+ }
+
+ public List getCoordinates() {
+ return coordinates;
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/model/Shot.java b/src/main/java/course_project/sea_battle/model/Shot.java
new file mode 100644
index 00000000..f777e8cd
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/model/Shot.java
@@ -0,0 +1,7 @@
+package course_project.sea_battle.model;
+
+public enum Shot {
+ MISS,
+ HIT,
+ KILLED
+}
diff --git a/src/main/java/course_project/sea_battle/rules b/src/main/java/course_project/sea_battle/rules
new file mode 100644
index 00000000..47a9b54e
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/rules
@@ -0,0 +1,18 @@
+GENERAL
+2 gameController modes are available: Player vs Player and Player vs Computer (very easy).
+Each player has 10 ships: 1*4deck, 2*3, 3*2, 4*1.
+
+SHIP PLACEMENT
+You can choose how to place ships: manually or automatically.
+It's not allowed to place ships close to each other (diagonal cells count as well).
+You put a ship by pointing its topLeft point and with position ("v" - vertical, "h" - horizontal).
+ So your input should be like this: [A7 V] or [b1 h].
+
+RULES
+Shot format: [A7] or [b1].
+You cannot shoot out of board or cells that you have shot before.
+When you destroy a ship all cells around are filled automatically and you cannot shoot them anymore (cause there are no ships).
+Each player has same count of moves.
+Game over when one of player (or both) don't have "alive" ships.
+
+
diff --git a/src/main/java/course_project/sea_battle/service/GameModeAndNameSetter.java b/src/main/java/course_project/sea_battle/service/GameModeAndNameSetter.java
new file mode 100644
index 00000000..1bee0499
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/service/GameModeAndNameSetter.java
@@ -0,0 +1,50 @@
+package course_project.sea_battle.service;
+
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.service.inputs.InputReader;
+import lombok.SneakyThrows;
+
+import static course_project.sea_battle.utils.Constants.*;
+
+public class GameModeAndNameSetter {
+ private final InputReader inputReader;
+
+ private int gameMode;
+
+ public GameModeAndNameSetter(InputReader inputReader) {
+ this.inputReader = inputReader;
+ }
+
+ @SneakyThrows
+ public void setNames(Player player1, Player player2) {
+
+ defineGameMode();
+
+ System.out.println(PL1);
+ String player1Name = inputReader.readLine();
+ player1.setName(player1Name);
+ System.out.println("Hello, " + player1Name + "!");
+
+ if (gameMode == 1) {
+ System.out.println(PL2);
+ String player2Name = inputReader.readLine();
+ player2.setName(player2Name);
+ System.out.println("Hello, " + player2Name + "!");
+ } else if (gameMode == 2) {
+ player2.setName("Computer");
+ player2.setComputer(true);
+ }
+ }
+
+ private void defineGameMode() {
+ while (true) {
+ System.out.println(SHOOSEGAMEMODE);
+ String gameModeInput = inputReader.readLine();
+ if (gameModeInput.matches("[1]|[2]")) {
+ gameMode = Integer.parseInt(gameModeInput);
+ break;
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/service/ShipPlacer.java b/src/main/java/course_project/sea_battle/service/ShipPlacer.java
new file mode 100644
index 00000000..37d630e5
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/service/ShipPlacer.java
@@ -0,0 +1,78 @@
+package course_project.sea_battle.service;
+
+import course_project.sea_battle.boards.MyBoard;
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.model.Point;
+import course_project.sea_battle.model.Ship;
+import course_project.sea_battle.service.inputs.InputShipReader;
+import lombok.SneakyThrows;
+
+import java.util.List;
+
+import static course_project.sea_battle.view.BoardPrinter.showBoards;
+import static course_project.sea_battle.utils.Constants.*;
+
+public class ShipPlacer {
+ private final InputShipReader inputShipReader;
+ private int shipPlacementMode;
+
+ public ShipPlacer(InputShipReader inputShipReader) {
+ this.inputShipReader = inputShipReader;
+ }
+
+ @SneakyThrows
+ public void placeShip(Player player1, Player player2) {
+
+ defineShipPlacementMode(player1);
+
+ MyBoard board = player1.getMyBoard();
+ if (!player1.isComputer()) {
+ showBoards(player1);
+ }
+
+ for (int shipSize = 4; shipSize >= 1; shipSize--) {
+ for (int shipNumber = 0; shipNumber <= 4 - shipSize; shipNumber++) {
+ if (shipPlacementMode == 1) {
+ System.out.println(player1.getName() + ", please, input top left coordinate for the ship (" + shipSize + " points) and orientation. Example: [A5 h] or [A8 v]");
+ }
+
+ inputShipReader.getAndValidateInput(shipSize, board, shipPlacementMode);
+ List coordinates = inputShipReader.getValidCoordinates();
+
+ Ship ship = new Ship(coordinates);
+ board.placeShip(ship);
+ player1.getMyShips().add(ship);
+
+ if (shipPlacementMode == 1) {
+ System.out.println(PLACED);
+ showBoards(player1);
+ }
+ }
+ }
+
+ if (shipPlacementMode == 2 && !player1.isComputer()) {
+ System.out.println(DONE);
+ showBoards(player1);
+ Thread.sleep(200);
+ }
+ if (!player1.isComputer() && !player2.isComputer()) {
+ inputShipReader.printBigSpace();
+ }
+ }
+
+ public void defineShipPlacementMode(Player player) {
+ if (player.isComputer()) {
+ shipPlacementMode = 2;
+ } else {
+ while (true) {
+ System.out.println(player.getName() + CHOOSESHIPPLACEMENTMODE);
+ String gameModeInput = inputShipReader.readLine();
+ if (gameModeInput.matches("[1]|[2]")) {
+ shipPlacementMode = Integer.parseInt(gameModeInput);
+ break;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/service/inputs/InputReader.java b/src/main/java/course_project/sea_battle/service/inputs/InputReader.java
new file mode 100644
index 00000000..1493a9b4
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/service/inputs/InputReader.java
@@ -0,0 +1,28 @@
+package course_project.sea_battle.service.inputs;
+
+import java.util.Scanner;
+
+import static course_project.sea_battle.utils.Constants.NEXTMOVE;
+import static course_project.sea_battle.utils.Constants.NEXTMOVE2;
+
+public abstract class InputReader {
+ protected Scanner scanner;
+
+ public String readLine() {
+ return scanner.nextLine();
+ }
+
+ public void printBigSpace() {
+ System.out.println(NEXTMOVE);
+ readLine();
+ System.out.println("\n\n\n\n\n\n\n\n\n\n");
+ }
+
+ public void printBigSpaceInShooter(boolean hasSence) {
+ if (hasSence) {
+ System.out.println(NEXTMOVE2);
+ readLine();
+ System.out.println("\n\n\n\n\n\n\n\n\n\n");
+ }
+ }
+}
diff --git a/src/main/java/course_project/sea_battle/service/inputs/InputShipReader.java b/src/main/java/course_project/sea_battle/service/inputs/InputShipReader.java
new file mode 100644
index 00000000..c3df2c4e
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/service/inputs/InputShipReader.java
@@ -0,0 +1,146 @@
+package course_project.sea_battle.service.inputs;
+
+import course_project.sea_battle.boards.MyBoard;
+import course_project.sea_battle.model.Point;
+
+import java.util.*;
+
+import static course_project.sea_battle.utils.Constants.*;
+
+public class InputShipReader extends InputReader {
+ private int x;
+ private int y;
+ private Random random = new Random();
+
+ private String position;
+ private List coordinates;
+
+ public InputShipReader(Scanner scanner) {
+ this.scanner = scanner;
+ }
+
+ public void getAndValidateInput(int shipSize, MyBoard board, int gameMode) {
+ while (true) {
+ if (gameMode == 1) {
+ String input = readLine();
+ if (!isValidInput(input)) continue;
+ } else if (gameMode == 2) {
+ getAutomaticCoordinates();
+ }
+
+ Point topLeftPoint = new Point(x, y);
+ if (!isShipWithinBoard(shipSize, gameMode)) continue;
+ coordinates = findCoordinates(shipSize, topLeftPoint);
+ if (shipsDoNotCross(board, shipSize, gameMode)) break;
+ }
+ }
+
+ public void getAutomaticCoordinates() {
+ x = random.nextInt(10);
+ y = random.nextInt(10);
+ position = random.nextInt(2) == 0 ? "v" : "h";
+ }
+
+ public boolean isValidInput(String input) {
+ if (input.matches("[a-jA-J]([1-9]|10) (v|h|V|H)")) {
+ String[] coords = input.split(" ");
+ y = Character.getNumericValue(coords[0].charAt(0)) - 10;
+ x = Integer.parseInt(coords[0].substring(1)) - 1;
+ position = coords[1].toLowerCase();
+ return true;
+ } else {
+ System.out.println(INPUTSHIPERROR);
+ return false;
+ }
+ }
+
+ public boolean isShipWithinBoard(int shipSize, int gameMode) {
+ Point rightBottomPoint = position.equalsIgnoreCase("v")
+ ? new Point(x + shipSize, y)
+ : new Point(x, y + shipSize);
+ if (rightBottomPoint.getX() > 10 || rightBottomPoint.getY() > 10) {
+ if (gameMode == 1) System.out.println(OUTOFBOARD);
+ return false;
+ }
+ return true;
+ }
+
+ public List findCoordinates(int shipSize, Point topLeftPoint) {
+ coordinates = new ArrayList<>();
+
+ int x1 = topLeftPoint.getX();
+ int y1 = topLeftPoint.getY();
+
+ for (int i = 0; i < shipSize; i++) {
+ coordinates.add(new Point(x1, y1));
+ if (position.equals("v")) {
+ x1++;
+ } else if (position.equals("h")) {
+ y1++;
+ }
+ }
+ return coordinates;
+ }
+
+ public boolean shipsDoNotCross(MyBoard board, int shipSize, int gameMode) {
+ HashSet allCoordinates = new HashSet<>();
+ for (int i = 0; i < shipSize; i++) {
+ allCoordinates.add(new Point(x, y));
+ if (x > 0) {
+ allCoordinates.add(new Point(x - 1, y));
+ }
+ if (y > 0) {
+ allCoordinates.add(new Point(x, y - 1));
+ }
+ if (x < 9) {
+ allCoordinates.add(new Point(x + 1, y));
+ }
+ if (y < 9) {
+ allCoordinates.add(new Point(x, y + 1));
+ }
+ if (x > 0 && y > 0) {
+ allCoordinates.add(new Point(x - 1, y - 1));
+ }
+ if (x < 9 && y < 9) {
+ allCoordinates.add(new Point(x + 1, y + 1));
+ }
+ if (x > 0 && y < 9) {
+ allCoordinates.add(new Point(x - 1, y + 1));
+ }
+ if (x < 9 && y > 0) {
+ allCoordinates.add(new Point(x + 1, y - 1));
+ }
+ if (position.equals("v")) {
+ x++;
+ } else {
+ y++;
+ }
+ }
+ long count = allCoordinates.stream()
+ .mapToInt(e -> board.getBoard()[e.getX()][e.getY()])
+ .distinct()
+ .count();
+ if (count > 1) {
+ if (gameMode == 1) System.out.println(SHIPSCROSS);
+ return false;
+ }
+ return true;
+ }
+
+ public List getValidCoordinates() {
+ return coordinates;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/service/inputs/InputShooterReader.java b/src/main/java/course_project/sea_battle/service/inputs/InputShooterReader.java
new file mode 100644
index 00000000..9ec52f6c
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/service/inputs/InputShooterReader.java
@@ -0,0 +1,209 @@
+package course_project.sea_battle.service.inputs;
+
+import course_project.sea_battle.boards.Board;
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.model.Point;
+import course_project.sea_battle.model.Ship;
+import course_project.sea_battle.model.Shot;
+import lombok.SneakyThrows;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static course_project.sea_battle.utils.Constants.*;
+import static course_project.sea_battle.view.BoardPrinter.showBoards;
+
+public class InputShooterReader extends InputReader {
+ private int x;
+ private int y;
+ private Shot shot;
+ private Ship currentShip;
+ private Random random = new Random();
+
+ public InputShooterReader(Scanner scanner) {
+ this.scanner = scanner;
+ }
+
+ @SneakyThrows
+ public void checkAndValidatePlayerShot(Player player1, Player player2) {
+ if (!player1.isComputer()) {
+ if (!player2.isComputer()) {
+ showBoards(player1);
+ }
+ System.out.println(player1.getName() + MAKESHOT);
+ }
+
+ while (true) {
+
+ if (!player1.isComputer()) {
+ String input = readLine();
+ if (!isValidInput(input)) continue;
+ } else {
+ defineShot();
+ }
+ if (isShooted(player1, player2)) continue;
+
+ if (player1.isComputer()) {
+ System.out.println(COMPUTERMOVE);
+ Thread.sleep(2000);
+ }
+
+ getShotResult(player2);
+ putOnBoard(player1.getMyShots(), new Point(x, y), shot);
+ putOnBoard(player2.getMyBoard(), new Point(x, y), shot);
+
+ if (!isGameContinue(player1, player2, shot)) break;
+ }
+ }
+
+ public void defineShot() {
+ x = random.nextInt(10);
+ y = random.nextInt(10);
+ }
+
+ public boolean isValidInput(String input) {
+ if (input.matches("[a-jA-J]([1-9]|10)")) {
+ y = Character.getNumericValue(input.charAt(0)) - 10;
+ x = Integer.parseInt(input.substring(1)) - 1;
+ return true;
+ } else {
+ System.out.println(INPUTSHOTERROR);
+ return false;
+ }
+ }
+
+ public boolean isShooted(Player me, Player enemy) {
+ if (enemy.getMyBoard().getBoard()[x][y] == 3 || enemy.getMyBoard().getBoard()[x][y] == 2) {
+ if (!me.isComputer()) {
+ System.out.println(CHECKED);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public void getShotResult(Player enemy) {
+ if (enemy.getMyBoard().getBoard()[x][y] == 1) {
+ findOutHitOrKilled(enemy);
+ } else {
+ shot = Shot.MISS;
+ }
+ }
+
+ public void findOutHitOrKilled(Player enemy) {
+ for (Ship ship : enemy.getMyShips()) {
+ if (ship.getCoordinates().contains(new Point(x, y))) {
+ ship.setLives(ship.getLives() - 1);
+ if (ship.getLives() == 0) {
+ shot = Shot.KILLED;
+ currentShip = ship;
+ } else {
+ shot = Shot.HIT;
+ }
+ }
+ }
+ }
+
+ public static void putOnBoard(Board board, Point shotPoint, Shot shot) {
+ int[][] tempBoard = board.getBoard();
+ if (shot == Shot.MISS) {
+ tempBoard[shotPoint.getX()][shotPoint.getY()] = 2;
+ } else {
+ tempBoard[shotPoint.getX()][shotPoint.getY()] = 3;
+ }
+ board.setBoard(tempBoard);
+ }
+
+ public void fillCellsAroundDestroyedShip(Ship ship, Player me, Player enemy) {
+
+ List coordinatesOfTheShip = ship.getCoordinates();
+ Set coordinatesAroundTheShip = new HashSet<>();
+ for (Point point : coordinatesOfTheShip) {
+ int x1 = point.getX();
+ int y1 = point.getY();
+
+ if (x1 > 0) {
+ coordinatesAroundTheShip.add(new Point(x1 - 1, y1));
+ }
+ if (y1 > 0) {
+ coordinatesAroundTheShip.add(new Point(x1, y1 - 1));
+ }
+ if (x1 < 9) {
+ coordinatesAroundTheShip.add(new Point(x1 + 1, y1));
+ }
+ if (y1 < 9) {
+ coordinatesAroundTheShip.add(new Point(x1, y1 + 1));
+ }
+ if (x1 > 0 && y1 > 0) {
+ coordinatesAroundTheShip.add(new Point(x1 - 1, y1 - 1));
+ }
+ if (x1 < 9 && y1 < 9) {
+ coordinatesAroundTheShip.add(new Point(x1 + 1, y1 + 1));
+ }
+ if (x1 > 0 && y1 < 9) {
+ coordinatesAroundTheShip.add(new Point(x1 - 1, y1 + 1));
+ }
+ if (x1 < 9 && y1 > 0) {
+ coordinatesAroundTheShip.add(new Point(x1 + 1, y1 - 1));
+ }
+ }
+
+ int[][] enemyMainBoard = enemy.getMyBoard().getBoard();
+
+ Set filteredPointsAround = coordinatesAroundTheShip.stream()
+ .distinct()
+ .filter(e -> (enemyMainBoard[e.getX()][e.getY()] == 0))
+ .collect(Collectors.toSet());
+
+ for (Point point : filteredPointsAround) {
+ putOnBoard(me.getMyShots(), point, Shot.MISS);
+ putOnBoard(enemy.getMyBoard(), point, Shot.MISS);
+ }
+ }
+
+ @SneakyThrows
+ public boolean isGameContinue(Player me, Player enemy, Shot shot) {
+ if (shot == Shot.KILLED) {
+ System.err.println("KILLED!");
+ System.out.println(enemy.getName() + " has " + enemy.countShips() + " ship(s) left.");
+ fillCellsAroundDestroyedShip(currentShip, me, enemy);
+ Thread.sleep(500);
+ if (!me.isComputer()) {
+ showBoards(me);
+ } else {
+ showBoards(enemy);
+ }
+ if (enemy.countShips() == 0) {
+ System.out.println(me.getName() + KILLALL);
+ printBigSpaceInShooter(!me.isComputer() && !enemy.isComputer());
+ return false;
+ } else {
+ if (!me.isComputer()) {
+ System.out.println(me.getName() + MAKESHOT);
+ }
+ }
+ } else if (shot == Shot.HIT) {
+ System.err.println("HIT!");
+ Thread.sleep(500);
+ if (!me.isComputer()) {
+ showBoards(me);
+ System.out.println(me.getName() + MAKESHOT);
+ } else {
+ showBoards(enemy);
+ }
+
+ } else if (shot == Shot.MISS) {
+ System.err.println("MISS!");
+ Thread.sleep(500);
+ if (!me.isComputer()) {
+ showBoards(me);
+ } else {
+ showBoards(enemy);
+ }
+ printBigSpaceInShooter(!me.isComputer() && !enemy.isComputer());
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/course_project/sea_battle/utils/Constants.java b/src/main/java/course_project/sea_battle/utils/Constants.java
new file mode 100644
index 00000000..b9a2ac4a
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/utils/Constants.java
@@ -0,0 +1,34 @@
+package course_project.sea_battle.utils;
+
+public class Constants {
+ public static final String SHOOSEGAMEMODE = "Please, choose game mode:\n1: player vs player\n2: player vs computer";
+ public static final String PL1 = "Player 1, please, input your name:";
+ public static final String PL2 = "Player 2, please, input your name:";
+
+ public static final String PLACED = "Ship is placed!";
+ public static final String CHOOSESHIPPLACEMENTMODE = ", please, choose ship placement mode:\n1: manual\n2: automatic";
+ public static final String NEXTMOVE = "Press ENTER to finish your move";
+ public static final String DONE = "\nAll ships are placed!";
+
+ public static final String INPUTSHIPERROR = "Input should be like this: [A7 h] or [B2 h]. Try again!";
+ public static final String OUTOFBOARD = "Impossible to place ship here because it is out of board!";
+ public static final String SHIPSCROSS = "Impossible to place ship here because ship crosses with another one!";
+
+ public static final String RED = "\u001B[31m";
+ public static final String GREEN = "\u001B[32m";
+ public static final String RESET = "\u001B[0m";
+ public static final String CYAN = "\u001B[36m";
+ public static final String MISS = GREEN + "0" + RESET;
+ public static final String HIT = RED + "X" + RESET;
+ public static final String WAVE = CYAN + "~" + RESET;
+
+ public static final String MAKESHOT = ", make your shot in format: [A6] or [b1]";
+ public static final String INPUTSHOTERROR = "Input should be like this: [A7] or [b2]. Try again!";
+ public static final String CHECKED = "Cell is checked. Make another shot!";
+ public static final String KILLALL = ", you destroyed all enemy ships. Congratulations!";
+ public static final String NEXTMOVE2 = "Press ENTER to finish your move";
+ public static final String COMPUTERMOVE = "Computer is thinking...";
+
+ public static final String TIE = "Game over. It's a TIE!";
+ public static final String GAMEOVER = "Game over. The winner is: ";
+}
diff --git a/src/main/java/course_project/sea_battle/view/BoardPrinter.java b/src/main/java/course_project/sea_battle/view/BoardPrinter.java
new file mode 100644
index 00000000..36620669
--- /dev/null
+++ b/src/main/java/course_project/sea_battle/view/BoardPrinter.java
@@ -0,0 +1,71 @@
+package course_project.sea_battle.view;
+
+import course_project.sea_battle.model.Player;
+
+import static course_project.sea_battle.utils.Constants.*;
+
+public class BoardPrinter {
+
+ public static synchronized void showBoards(Player player) {
+ int[][] myField = player.getMyBoard().getBoard();
+ int[][] enemyField = player.getMyShots().getBoard();
+ showHeader(player);
+ for (int i = 0; i < 10; i++) {
+ System.out.format("%3d", i + 1);
+ for (int j = 0; j < 23; j++) {
+ if (j < 10) {
+ switch (myField[i][j]) {
+ case 0:
+ System.out.printf(" %s", WAVE);
+ break;
+ case 1:
+ System.out.printf(" %s", "W");
+ break;
+ case 2:
+ System.out.printf(" %s", MISS);
+ break;
+ case 3:
+ System.out.printf(" %s", HIT);
+ break;
+ default:
+ }
+ } else if (j < 12) {
+ System.out.print("\t");
+ } else if (j == 12) {
+ System.out.printf("%3d", i + 1);
+ } else {
+ switch (enemyField[i][j - 13]) {
+ case 0:
+ System.out.printf(" %s", WAVE);
+ break;
+ case 2:
+ System.out.printf(" %s", MISS);
+ break;
+ case 3:
+ System.out.printf(" %s", HIT);
+ break;
+ default:
+ }
+ }
+ }
+ System.out.println();
+ }
+ }
+
+ public static void showHeader(Player player) {
+ System.out.println();
+ System.out.println("\t\t\t\t\t\tMY BOARD (" + player.getName() + ") vs ENEMY BOARD");
+ System.out.println();
+ showHighLine();
+ System.out.print("\t\t");
+ showHighLine();
+ System.out.println();
+ }
+
+ public static void showHighLine() {
+ System.out.print("\t");
+ for (int i = 0; i < 10; i++) {
+ System.out.format("%3s", (char) (i + 65) + " ");
+ }
+ }
+}
diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java
index 07c029a2..e2df3188 100644
--- a/src/main/java/homework_1/Main.java
+++ b/src/main/java/homework_1/Main.java
@@ -2,8 +2,17 @@
public class Main {
- public static void main(String[] args) {
- System.out.println("Hello homework!");
- }
+ private static final String RED = "\u001B[31m";
+ private static final String BLACK = "\u001B[0m";
+ public static void main(String[] args) {
+
+ for (String str : args) {
+ if (str.equals("error")) {
+ System.out.println(RED + "Alarm!" + BLACK);
+ return;
+ }
+ System.out.println(str + " " + str.length() + " letters");
+ }
+ }
}
diff --git a/src/main/java/homework_2/pyramid_printer/Main.java b/src/main/java/homework_2/pyramid_printer/Main.java
new file mode 100644
index 00000000..71e33035
--- /dev/null
+++ b/src/main/java/homework_2/pyramid_printer/Main.java
@@ -0,0 +1,8 @@
+package homework_2.pyramid_printer;
+
+public class Main {
+
+ public static void main(String[] args) {
+ new PyramidPrinter().run();
+ }
+}
diff --git a/src/main/java/homework_2/pyramid_printer/PyramidPrinter.java b/src/main/java/homework_2/pyramid_printer/PyramidPrinter.java
new file mode 100644
index 00000000..70ee7dbe
--- /dev/null
+++ b/src/main/java/homework_2/pyramid_printer/PyramidPrinter.java
@@ -0,0 +1,45 @@
+package homework_2.pyramid_printer;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class PyramidPrinter {
+
+ private static final String ERROR = "Only 1 non-negative integer is allowed as passed parameter";
+
+ public void run() {
+ System.out.println("Please, input a number:");
+
+ try {
+ int countX = bufferedReaderReadConsole();
+ validateInput(countX);
+ printConsole(countX);
+ } catch (IOException | IllegalArgumentException e) {
+ System.out.println(ERROR);
+ }
+ }
+
+ private void printConsole(int countX) {
+ StringBuilder result = new StringBuilder("");
+ for (int i = 1; i <= countX; i++) {
+ for (int j = 0; j < i; j++) {
+ result.append("x");
+ }
+ result.append("\n");
+ }
+ System.out.println(result);
+ }
+
+ private int bufferedReaderReadConsole() throws IOException, NumberFormatException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ return Integer.parseInt(reader.readLine());
+ }
+ }
+
+ private void validateInput(int i) {
+ if (i < 0) {
+ throw new IllegalArgumentException();
+ }
+ }
+}
diff --git a/src/main/java/homework_2/random_chars_table/Main.java b/src/main/java/homework_2/random_chars_table/Main.java
new file mode 100644
index 00000000..be586c4b
--- /dev/null
+++ b/src/main/java/homework_2/random_chars_table/Main.java
@@ -0,0 +1,8 @@
+package homework_2.random_chars_table;
+
+public class Main {
+
+ public static void main(String[] args) {
+ new RandomCharsTable().run();
+ }
+}
diff --git a/src/main/java/homework_2/random_chars_table/RandomCharsTable.java b/src/main/java/homework_2/random_chars_table/RandomCharsTable.java
new file mode 100644
index 00000000..0db0598c
--- /dev/null
+++ b/src/main/java/homework_2/random_chars_table/RandomCharsTable.java
@@ -0,0 +1,85 @@
+package homework_2.random_chars_table;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Random;
+
+public class RandomCharsTable {
+
+ private static final String ERROR = "Passed parameters should match the format [positive integer] [positive integer] [even|odd]";
+
+ private int length;
+ private int width;
+ private String strategy;
+
+ public void run() {
+
+ System.out.println("[Input example: 2 3 odd]");
+ System.out.println("Please, input 2 positive numbers and a strategy (even/odd)");
+
+ try {
+ String inputFull = bufferedReaderReadConsole();
+ parseInput(inputFull);
+ validateInputData(length, width, strategy);
+ String strategyRes = createCharTable();
+ System.out.println(strategyRes);
+ } catch (IOException | IllegalArgumentException e) {
+ System.out.println(ERROR);
+ }
+ }
+
+ private String bufferedReaderReadConsole() throws IOException, NumberFormatException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ return reader.readLine();
+ }
+ }
+
+ private void parseInput(String s) {
+
+ String[] array = s.split(" ");
+
+ if (array.length != 3) {
+ throw new IllegalArgumentException();
+ }
+
+ length = Integer.parseInt(array[0]);
+ width = Integer.parseInt(array[1]);
+ strategy = array[2];
+ }
+
+ private void validateInputData(int x, int y, String str) {
+ if (x < 1 || y < 1 || (!str.equals("odd") && !str.equals("even"))) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ private String createCharTable() {
+
+ char[][] table = new char[length][width];
+ StringBuilder strategyEven = new StringBuilder("Even letters -");
+ StringBuilder strategyOdd = new StringBuilder("Odd letters -");
+
+ for (int i = 0; i < length; i++) {
+ System.out.print("|");
+
+ for (int j = 0; j < width; j++) {
+ Random r = new Random();
+ int x = (r.nextInt(26) + 65);
+ table[i][j] = (char) x;
+ if (x % 2 == 0) {
+ strategyEven.append(" " + table[i][j] + ",");
+ } else {
+ strategyOdd.append(" " + table[i][j] + ",");
+ }
+ System.out.print(" " + table[i][j] + " |");
+ }
+ System.out.println();
+ }
+
+ strategyOdd = strategyOdd.deleteCharAt(strategyOdd.length() - 1);
+ strategyEven = strategyEven.deleteCharAt(strategyEven.length() - 1);
+
+ return "even".equals(strategy) ? strategyEven.toString() : strategyOdd.toString();
+ }
+}
diff --git a/src/main/java/homework_2/traffic_light/Main.java b/src/main/java/homework_2/traffic_light/Main.java
new file mode 100644
index 00000000..3ff7f428
--- /dev/null
+++ b/src/main/java/homework_2/traffic_light/Main.java
@@ -0,0 +1,8 @@
+package homework_2.traffic_light;
+
+public class Main {
+
+ public static void main(String[] args) {
+ new TrafficLight().run();
+ }
+}
diff --git a/src/main/java/homework_2/traffic_light/TrafficLight.java b/src/main/java/homework_2/traffic_light/TrafficLight.java
new file mode 100644
index 00000000..0c09df39
--- /dev/null
+++ b/src/main/java/homework_2/traffic_light/TrafficLight.java
@@ -0,0 +1,50 @@
+package homework_2.traffic_light;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class TrafficLight {
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m" + "RED" + RESET;
+ private static final String GREEN = "\u001B[32m" + "GREEN" + RESET;
+ private static final String YELLOW = "\u001B[33m" + "YELLOW" + RESET;
+ private static final String ERROR = "Only 1 non-negative integer is allowed as passed parameter";
+
+ public void run() {
+ System.out.println("Please, input a number of seconds:");
+ try {
+ int seconds = bufferedReaderReadConsole();
+ validateInput(seconds);
+ System.out.println(showLight(seconds));
+ } catch (NumberFormatException | IOException ex) {
+ System.out.println(ERROR);
+ } catch (IllegalArgumentException ex) {
+ System.out.println(ex.getMessage());
+ }
+ }
+
+ private int bufferedReaderReadConsole() throws IOException, NumberFormatException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ return Integer.parseInt(reader.readLine());
+ }
+ }
+
+ private void validateInput(int i) throws IllegalArgumentException{
+ if (i < 0) {
+ throw new IllegalArgumentException(ERROR);
+ } else if (i > 86399) {
+ throw new IllegalArgumentException("The day is over");
+ }
+ }
+
+ private String showLight(int i) {
+
+ int secondsMod = i % 60;
+ return secondsMod < 35 ? GREEN
+ : secondsMod < 40 ? YELLOW
+ : secondsMod < 55 ? RED
+ : YELLOW;
+ }
+}
diff --git a/src/main/java/homework_3/Person.java b/src/main/java/homework_3/Person.java
new file mode 100644
index 00000000..3e3d5b8b
--- /dev/null
+++ b/src/main/java/homework_3/Person.java
@@ -0,0 +1,73 @@
+package homework_3;
+
+import java.util.ArrayList;
+import java.util.List;
+/*
+Class must be declared as final;
+All members must be private;
+There are no setters;
+Getters must return copies of mutable objects;
+Parameterized constructor must perform Deep Copy.
+ */
+
+public final class Person {
+ private final int age;
+ private final String name;
+ private final ArrayList hobbies;
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public List getHobbies() {
+ if (hobbies != null){
+ return new ArrayList<>(hobbies);
+ }
+ return new ArrayList<>();
+ }
+
+ public Person(int age, String name, List listHobbies) {
+ this.age = age;
+ this.name = name;
+ this.hobbies = new ArrayList<>(listHobbies);
+ }
+
+ public Person(int age, String name) {
+ this.hobbies = null;
+ this.age = age;
+ this.name = name;
+ }
+
+ public Person addNewHobby (String hobby){
+ List updatedHobbyList = getHobbies();
+ updatedHobbyList.add(hobby);
+ return new Person(age, name, updatedHobbyList);
+ }
+
+ public static void main(String[] args) {
+ ArrayList listHobbies = new ArrayList<>();
+ listHobbies.add("Dancing");
+ listHobbies.add("Travelling");
+
+ Person me = new Person(27, "Tom", listHobbies);
+ System.out.println("Me before changes = " + me);
+
+ me = me.addNewHobby("Painting");
+ System.out.println("Me after changes = " + me);
+ }
+
+ @Override
+ public String toString() {
+ return "Person{" +
+ "age=" + age +
+ ", name='" + name + '\'' +
+ ", hobbies=" + hobbies +
+ '}';
+ }
+
+}
+
diff --git a/src/main/java/homework_4/customAnnotation/ClassCoffeeAnnotation.java b/src/main/java/homework_4/customAnnotation/ClassCoffeeAnnotation.java
new file mode 100644
index 00000000..30e1782f
--- /dev/null
+++ b/src/main/java/homework_4/customAnnotation/ClassCoffeeAnnotation.java
@@ -0,0 +1,32 @@
+package homework_4.customAnnotation;
+
+import java.lang.annotation.*;
+
+import static java.lang.annotation.ElementType.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(TYPE)
+@Inherited
+public @interface ClassCoffeeAnnotation {
+ enum Size {SMALL, MEDIUM, BIG}
+ Size size() default Size.MEDIUM;
+ boolean hasMilk() default false;
+ int price();
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(METHOD)
+@interface AskForCoffeeAnnotation {
+ String value();
+}
+
+@Target(value= ElementType.METHOD)
+@Retention(value= RetentionPolicy.RUNTIME)
+@interface StartMakingCoffee {
+}
+
+@Target(value=ElementType.METHOD)
+@Retention(value= RetentionPolicy.RUNTIME)
+@interface StopMakingCoffee {
+}
+
diff --git a/src/main/java/homework_4/customAnnotation/Coffee.java b/src/main/java/homework_4/customAnnotation/Coffee.java
new file mode 100644
index 00000000..2ef376ce
--- /dev/null
+++ b/src/main/java/homework_4/customAnnotation/Coffee.java
@@ -0,0 +1,35 @@
+package homework_4.customAnnotation;
+
+@ClassCoffeeAnnotation(price = 100)
+public class Coffee {
+ int price;
+ boolean hasMilk;
+ ClassCoffeeAnnotation.Size size;
+
+ public Coffee() {
+ ClassCoffeeAnnotation annotation = this.getClass().getAnnotation(ClassCoffeeAnnotation.class);
+
+ this.price = annotation.price();
+ this.hasMilk = annotation.hasMilk();
+ this.size = annotation.size();
+ }
+
+ @AskForCoffeeAnnotation("Give me please this one!")
+ public void askForCoffee() throws NoSuchMethodException {
+ System.out.println(this.getClass().getMethod("askForCoffee").getDeclaredAnnotation(AskForCoffeeAnnotation.class).value());
+ }
+
+ @StartMakingCoffee
+ public void createCoffee(){
+ //Some business logic
+ }
+
+ @StopMakingCoffee
+ public void stopCoffee(){
+ //Some business logic
+ }
+
+}
+
+
+
diff --git a/src/main/java/homework_4/customAnnotation/Main.java b/src/main/java/homework_4/customAnnotation/Main.java
new file mode 100644
index 00000000..f801fd40
--- /dev/null
+++ b/src/main/java/homework_4/customAnnotation/Main.java
@@ -0,0 +1,31 @@
+package homework_4.customAnnotation;
+
+import java.lang.reflect.Method;
+
+public class Main {
+ public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
+
+ Coffee myCoffee = new Coffee();
+
+ System.out.println("Size: " + myCoffee.size);
+ System.out.println("With milk: " + myCoffee.hasMilk);
+ System.out.println("Price: " + myCoffee.price + "₽");
+
+ myCoffee.askForCoffee();
+ System.out.println();
+
+ boolean hasStart=false;
+ boolean hasStop=false;
+
+ Method[] method = Class.forName("homework_4.customAnnotation.Coffee").getMethods();
+ for(Method md: method){
+ if(md.isAnnotationPresent(StartMakingCoffee.class)) {hasStart=true;}
+ if(md.isAnnotationPresent(StopMakingCoffee.class)) {hasStop=true;}
+ }
+
+ System.out.println("Start making coffee - " + hasStart);
+ System.out.println("Making nice coffee...");
+ System.out.println("Stop making coffee - " + hasStop);
+ }
+
+}
diff --git a/src/main/java/homework_4/customFileReader/CustomFileReader.java b/src/main/java/homework_4/customFileReader/CustomFileReader.java
new file mode 100644
index 00000000..49b20eb5
--- /dev/null
+++ b/src/main/java/homework_4/customFileReader/CustomFileReader.java
@@ -0,0 +1,72 @@
+package homework_4.customFileReader;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Scanner;
+
+public class CustomFileReader {
+
+ private final String filename;
+
+ private final StringBuilder result = new StringBuilder();
+
+ public CustomFileReader(String filename) {
+ this.filename = filename;
+ }
+
+ // using FileReader
+ public void run1() throws IOException {
+
+ try (FileReader reader = new FileReader(filename)) {
+ int ch;
+ while ((ch = reader.read()) != -1) {
+ char x = (char) ch;
+ if (x == '.' || x == ',') {
+ continue;
+ }
+ result.append(x);
+ }
+ }
+ System.out.println(result);
+ }
+
+
+ // using BufferedReader
+ public void run2() throws IOException {
+
+ try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ line = line.replaceAll("[,.]", "");
+ result.append(line + "\n");
+ }
+ }
+ System.out.println(result);
+ }
+
+ // using Scanner
+ public void run3() throws IOException {
+
+ try (Scanner scanner = new Scanner(Paths.get(filename))) {
+ String line;
+ while (scanner.hasNextLine()) {
+ line = scanner.nextLine().replaceAll("[,.]", "");
+ result.append(line + "\n");
+ }
+ }
+ System.out.println(result);
+ }
+
+ // using Files.readAllBytes
+ public void run4() throws IOException {
+
+ String content = new String(Files.readAllBytes(Paths.get(filename)));
+ content = content.replaceAll("[,.]", "");
+ result.append(content);
+ System.out.println(result);
+ }
+
+}
diff --git a/src/main/java/homework_4/customFileReader/Main.java b/src/main/java/homework_4/customFileReader/Main.java
new file mode 100644
index 00000000..dd4b4a7d
--- /dev/null
+++ b/src/main/java/homework_4/customFileReader/Main.java
@@ -0,0 +1,16 @@
+package homework_4.customFileReader;
+
+import java.io.IOException;
+
+public class Main {
+
+ private static String filename = "src/main/resources/custom_file_reader/file.txt";
+
+ public static void main(String[] args) throws IOException {
+ new CustomFileReader(filename).run1();
+ new CustomFileReader(filename).run2();
+ new CustomFileReader(filename).run3();
+ new CustomFileReader(filename).run4();
+ }
+
+}
diff --git a/src/main/java/homework_4/singleton/Singleton.java b/src/main/java/homework_4/singleton/Singleton.java
new file mode 100644
index 00000000..da06f6ba
--- /dev/null
+++ b/src/main/java/homework_4/singleton/Singleton.java
@@ -0,0 +1,37 @@
+package homework_4.singleton;
+
+//Basic Singleton
+
+public class Singleton {
+ private static Singleton uniqueInstance;
+
+ private Singleton() {
+ }
+
+ public static Singleton getInstance() {
+ if (uniqueInstance == null) {
+ uniqueInstance = new Singleton();
+ }
+ return uniqueInstance;
+ }
+
+}
+
+//Thread safe realization of Singleton
+
+class SingletonThreadSafe {
+ private static volatile SingletonThreadSafe uniqueInstance;
+
+ private SingletonThreadSafe() {
+ }
+
+ public static SingletonThreadSafe getInstance() {
+ if (uniqueInstance == null) {
+ synchronized (SingletonThreadSafe.class) {
+ uniqueInstance = new SingletonThreadSafe();
+ }
+ }
+ return uniqueInstance;
+ }
+
+}
diff --git a/src/main/java/homework_5/customRegexMatcher/CustomRegexMatcher.java b/src/main/java/homework_5/customRegexMatcher/CustomRegexMatcher.java
new file mode 100644
index 00000000..2e0b7f6a
--- /dev/null
+++ b/src/main/java/homework_5/customRegexMatcher/CustomRegexMatcher.java
@@ -0,0 +1,32 @@
+package homework_5.customRegexMatcher;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class CustomRegexMatcher {
+
+ public void run() {
+ System.out.println("Please, input your Email");
+ try {
+ String input = bufferedReaderReadConsole();
+ System.out.println(regex(input));
+ } catch (IOException | IllegalArgumentException ex) {
+ System.out.println(false);
+ }
+ }
+
+ private String bufferedReaderReadConsole() throws IOException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ String str = reader.readLine();
+ if (str == null) {
+ throw new IllegalArgumentException();
+ }
+ return str;
+ }
+ }
+
+ public boolean regex(String s) {
+ return s.matches("[\\w\\.\\-+!#%$&'*/=?`^{|}~]+@[\\w\\.]+\\.(com|ru|ua|kz|by)");
+ }
+}
diff --git a/src/main/java/homework_5/customRegexMatcher/Main.java b/src/main/java/homework_5/customRegexMatcher/Main.java
new file mode 100644
index 00000000..e6f903cb
--- /dev/null
+++ b/src/main/java/homework_5/customRegexMatcher/Main.java
@@ -0,0 +1,7 @@
+package homework_5.customRegexMatcher;
+
+public class Main {
+ public static void main(String[] args) {
+ new CustomRegexMatcher().run();
+ }
+}
diff --git a/src/main/java/homework_5/powerOfNumber/Main.java b/src/main/java/homework_5/powerOfNumber/Main.java
new file mode 100644
index 00000000..3274a5f6
--- /dev/null
+++ b/src/main/java/homework_5/powerOfNumber/Main.java
@@ -0,0 +1,7 @@
+package homework_5.powerOfNumber;
+
+public class Main {
+ public static void main(String[] args) {
+ new PowerOfNumber().run();
+ }
+}
diff --git a/src/main/java/homework_5/powerOfNumber/PowerOfNumber.java b/src/main/java/homework_5/powerOfNumber/PowerOfNumber.java
new file mode 100644
index 00000000..b4e23378
--- /dev/null
+++ b/src/main/java/homework_5/powerOfNumber/PowerOfNumber.java
@@ -0,0 +1,51 @@
+package homework_5.powerOfNumber;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class PowerOfNumber {
+ private static final String ERROR = "Only 2 non-negative integers are allowed";
+
+ public void run() {
+ System.out.println("Please, input 2 non-negative numbers:");
+ try {
+ String input = bufferedReaderReadConsole();
+ int[] array = validateInput(input);
+ int i1 = array[0];
+ int i2 = array[1];
+ System.out.println(powerN(i1, i2));
+ } catch (IOException | IllegalArgumentException ex) {
+ System.out.println(ERROR);
+ }
+ }
+
+ private String bufferedReaderReadConsole() throws IOException {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
+ String str = reader.readLine();
+ if (str == null) {
+ throw new IllegalArgumentException();
+ }
+ return str;
+ }
+ }
+
+ private int[] validateInput(String s) {
+ String[] array = s.trim().replaceAll("( )+", " ").split(" ");
+ if (array.length != 2) {
+ throw new IllegalArgumentException();
+ }
+ int i1 = Integer.parseInt(array[0]);
+ int i2 = Integer.parseInt(array[1]);
+ if (i1 < 0 || i2 < 0) {
+ throw new IllegalArgumentException();
+ }
+ return new int[]{i1, i2};
+ }
+
+ public int powerN(int base, int n) {
+ if (n < 1) return 1;
+ return base * (powerN(base, n - 1));
+ }
+}
+
diff --git a/src/main/java/homework_6/mapProblemsGenerator/MapProblemsCollisionGenerator.java b/src/main/java/homework_6/mapProblemsGenerator/MapProblemsCollisionGenerator.java
new file mode 100644
index 00000000..ea8f02a1
--- /dev/null
+++ b/src/main/java/homework_6/mapProblemsGenerator/MapProblemsCollisionGenerator.java
@@ -0,0 +1,28 @@
+package homework_6.mapProblemsGenerator;
+
+/**
+ * Class MapProblemsCollisionGenerator with incorrect hashCode() method that creates
+ * collisions every time.
+ */
+
+public final class MapProblemsCollisionGenerator {
+ private final int someField;
+
+ public MapProblemsCollisionGenerator(int n) {
+ this.someField = n;
+ }
+
+ @Override
+ public int hashCode() {
+ return 1;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MapProblemsCollisionGenerator generator = (MapProblemsCollisionGenerator) o;
+ return someField == generator.someField;
+ }
+
+}
diff --git a/src/main/java/homework_6/mapProblemsGenerator/MapProblemsMutableGenerator.java b/src/main/java/homework_6/mapProblemsGenerator/MapProblemsMutableGenerator.java
new file mode 100644
index 00000000..1eeb3cce
--- /dev/null
+++ b/src/main/java/homework_6/mapProblemsGenerator/MapProblemsMutableGenerator.java
@@ -0,0 +1,37 @@
+package homework_6.mapProblemsGenerator;
+
+import java.util.Objects;
+
+/**
+ * Class Dog with mutable field age.
+ */
+
+public final class MapProblemsMutableGenerator {
+ private int someField;
+
+ public MapProblemsMutableGenerator(int n) {
+ this.someField = n;
+ }
+
+ public int getSomeField() {
+ return someField;
+ }
+
+ public void setSomeField(int someField) {
+ this.someField = someField;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ MapProblemsMutableGenerator generator = (MapProblemsMutableGenerator) o;
+ return someField == generator.someField;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(someField);
+ }
+
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/Cat.java b/src/main/java/homework_7/kittenToCatFunction/Cat.java
new file mode 100644
index 00000000..01d79ad1
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/Cat.java
@@ -0,0 +1,37 @@
+package homework_7.kittenToCatFunction;
+
+public abstract class Cat {
+ private int age;
+ private String name;
+ private Kitten kitten;
+
+ public Cat(int age, String name, Kitten kitten) {
+ this.age = age;
+ this.name = name;
+ this.kitten = kitten;
+ }
+
+ public Kitten getKitten() {
+ return kitten;
+ }
+
+ public void setKitten(Kitten kitten) {
+ this.kitten = kitten;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/EgyptCat.java b/src/main/java/homework_7/kittenToCatFunction/EgyptCat.java
new file mode 100644
index 00000000..6f69c7a7
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/EgyptCat.java
@@ -0,0 +1,7 @@
+package homework_7.kittenToCatFunction;
+
+public class EgyptCat extends Cat {
+ public EgyptCat(int age, String name, Kitten kitten) {
+ super(age, name, kitten);
+ }
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/EgyptKitten.java b/src/main/java/homework_7/kittenToCatFunction/EgyptKitten.java
new file mode 100644
index 00000000..9b9e49fa
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/EgyptKitten.java
@@ -0,0 +1,7 @@
+package homework_7.kittenToCatFunction;
+
+public class EgyptKitten extends Kitten {
+ public EgyptKitten(int age, String name) {
+ super(age, name);
+ }
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/Kitten.java b/src/main/java/homework_7/kittenToCatFunction/Kitten.java
new file mode 100644
index 00000000..b6b37052
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/Kitten.java
@@ -0,0 +1,27 @@
+package homework_7.kittenToCatFunction;
+
+public abstract class Kitten {
+ private int age;
+ private String name;
+
+ public Kitten(int age, String name) {
+ this.age = age;
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/KittenToCatFunction.java b/src/main/java/homework_7/kittenToCatFunction/KittenToCatFunction.java
new file mode 100644
index 00000000..1d29e024
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/KittenToCatFunction.java
@@ -0,0 +1,6 @@
+package homework_7.kittenToCatFunction;
+
+@FunctionalInterface
+public interface KittenToCatFunction {
+ Cat grow(Kitten k);
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/Main.java b/src/main/java/homework_7/kittenToCatFunction/Main.java
new file mode 100644
index 00000000..466a5338
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/Main.java
@@ -0,0 +1,24 @@
+package homework_7.kittenToCatFunction;
+
+public class Main {
+
+ public static void main(String[] args) {
+
+ Kitten kitten = new EgyptKitten(1, "Push");
+
+ KittenToCatFunction function = x -> {
+ if (x instanceof EgyptKitten) {
+ return new EgyptCat(x.getAge() + 3, x.getName(), x);
+ } else {
+ return new SomeCat(x.getAge() + 3, x.getName(), x);
+ }
+ };
+
+ Cat cat = function.grow(kitten);
+
+ System.out.println("bigCat.getClass() = " + cat.getClass());
+ System.out.println("bigCat.getAge() = " + cat.getAge());
+ System.out.println("bigCat.getName() = " + cat.getName());
+ }
+
+}
diff --git a/src/main/java/homework_7/kittenToCatFunction/SomeCat.java b/src/main/java/homework_7/kittenToCatFunction/SomeCat.java
new file mode 100644
index 00000000..ad54436d
--- /dev/null
+++ b/src/main/java/homework_7/kittenToCatFunction/SomeCat.java
@@ -0,0 +1,7 @@
+package homework_7.kittenToCatFunction;
+
+public class SomeCat extends Cat{
+ public SomeCat(int age, String name, Kitten kitten) {
+ super(age, name, kitten);
+ }
+}
diff --git a/src/main/resources/custom_file_reader/file.txt b/src/main/resources/custom_file_reader/file.txt
new file mode 100644
index 00000000..7cda6d00
--- /dev/null
+++ b/src/main/resources/custom_file_reader/file.txt
@@ -0,0 +1,4 @@
+Я вас любил: любовь еще, быть может,
+В душе моей угасла не совсем;
+Но пусть она вас больше не тревожит;
+Я не хочу печалить вас ничем.
\ No newline at end of file
diff --git a/src/test/java/course_project/sea_battle/GameControllerTest.java b/src/test/java/course_project/sea_battle/GameControllerTest.java
new file mode 100644
index 00000000..e3bdc77a
--- /dev/null
+++ b/src/test/java/course_project/sea_battle/GameControllerTest.java
@@ -0,0 +1,236 @@
+package course_project.sea_battle;
+
+import base.UnitBase;
+import course_project.sea_battle.controller.GameController;
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.model.Point;
+import course_project.sea_battle.model.Ship;
+import course_project.sea_battle.service.inputs.InputShipReader;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Scanner;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class GameControllerTest extends UnitBase {
+
+ private static final String INPUTSHIPERROR = "Input should be like this: [A7 h] or [B2 h]. Try again!";
+ private static final String OUTOFBOARD = "Impossible to place ship here because it is out of board!";
+ private static final String TIE = "Game over. It's a TIE!";
+ private static final String GAMEOVER = "Game over. The winner is: ";
+
+ @Test
+ void testNameSetter() {
+ String input = "1\n" +
+ "Tom\n" +
+ "Vera\n";
+ setInput(input);
+
+ GameController gameController = new GameController();
+ gameController.setUpNames();
+
+ Player player1 = gameController.getPlayer1();
+ Player player2 = gameController.getPlayer2();
+
+ assertEquals("Tom", player1.getName());
+ assertEquals("Vera", player2.getName());
+ }
+
+ @Test
+ void testValidCoordsShipPlacing() {
+ String input = "1\n" +
+ "a1 h\n" +
+ "a3 h\n" +
+ "a5 h\n" +
+ "a7 h\n" +
+ "a9 h\n" +
+ "f1 h\n" +
+ "f3 h\n" +
+ "f5 h\n" +
+ "f7 h\n" +
+ "f9 h\n" +
+ "\n" +
+ "1\n" +
+ "a1 h\n" +
+ "a3 h\n" +
+ "a5 h\n" +
+ "a7 h\n" +
+ "a9 h\n" +
+ "f1 h\n" +
+ "f3 h\n" +
+ "f5 h\n" +
+ "f7 h\n" +
+ "f9 h\n" +
+ "\n";
+ setInput(input);
+
+ GameController gameController = new GameController();
+ gameController.setUpShips();
+
+ long numOfShips1 = gameController.getPlayer1().countShips();
+ long numOfShips2 = gameController.getPlayer2().countShips();
+
+ assertEquals(10, numOfShips1);
+ assertEquals(10, numOfShips2);
+ }
+
+ @Test
+ void testOnlyValidCoordsShipPlacing() {
+ String input = "1\n" +
+ "a1 h\n" +
+ "a2 h\n" +
+ "a\n" +
+ "a6v\n" +
+ "a10 v\n" +
+ "a3 h\n" +
+ "a5 h\n" +
+ "a7 h\n" +
+ "a9 h\n" +
+ "f1 h\n" +
+ "f3 h\n" +
+ "f5 h\n" +
+ "f7 h\n" +
+ "f9 h\n" +
+ "\n" +
+ "1\n" +
+ "a1 h\n" +
+ "a3 h\n" +
+ "a5 h\n" +
+ "a7 h\n" +
+ "a9 h\n" +
+ "f1 h\n" +
+ "f3 h\n" +
+ "f5 h\n" +
+ "f7 h\n" +
+ "f9 h\n" +
+ "\n";
+ setInput(input);
+
+ GameController gameController = new GameController();
+ gameController.setUpShips();
+
+ long numOfShips1 = gameController.getPlayer1().countShips();
+ long numOfShips2 = gameController.getPlayer2().countShips();
+
+ assertEquals(10, numOfShips1);
+ assertEquals(10, numOfShips2);
+ }
+
+ @Test
+ void testComputerShipPlacing() {
+ String input = "2\n" +
+ "\n" +
+ "2\n" +
+ "\n";
+ setInput(input);
+
+ GameController gameController = new GameController();
+ gameController.setUpShips();
+
+ long numOfShips1 = gameController.getPlayer1().countShips();
+ long numOfShips2 = gameController.getPlayer2().countShips();
+
+ assertEquals(10, numOfShips1);
+ assertEquals(10, numOfShips2);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"a6", "d1 g", "d1 v 1", ""})
+ void givenInvalidShipCoords_whenSetUpShips_ThenError(String input) {
+ setInput(input);
+ new InputShipReader(new Scanner(System.in)).isValidInput(input);
+ assertEquals(INPUTSHIPERROR, getOutput());
+ }
+
+ @Test
+ void givenOutOfBoardShipCoords_whenSetUpShips_ThenError() {
+ InputShipReader inputShipReader = new InputShipReader(new Scanner(System.in));
+ inputShipReader.setX(7);
+ inputShipReader.setY(0);
+ inputShipReader.setPosition("v");
+
+ assertTrue(inputShipReader.isShipWithinBoard(3, 1));
+ assertFalse(inputShipReader.isShipWithinBoard(4, 1));
+ assertEquals(OUTOFBOARD, getOutput());
+ }
+
+ @Test
+ void testShooter() {
+ String input = "a1\n" +
+ "b1\n" +
+ "\n" +
+ "a10\n" +
+ "\n";
+ setInput(input);
+
+ List coordinates = new ArrayList<>();
+ coordinates.add(new Point(0, 0));
+ coordinates.add(new Point(0, 1));
+ Ship ship = new Ship(coordinates);
+
+ List coordinates2 = new ArrayList<>();
+ coordinates.add(new Point(9, 9));
+ Ship ship2 = new Ship(coordinates2);
+
+ GameController gameController = new GameController();
+ gameController.getPlayer1().getMyShips().add(ship);
+ gameController.getPlayer2().getMyShips().add(ship2);
+
+ gameController.getPlayer1().getMyBoard().placeShip(ship);
+ gameController.getPlayer2().getMyBoard().placeShip(ship2);
+
+ int numOfPlayer1AllShips = gameController.getPlayer1().getMyShips().size();
+ int numOfPlayer2AllShips = gameController.getPlayer1().getMyShips().size();
+
+ assertEquals(1, numOfPlayer1AllShips);
+ assertEquals(1, numOfPlayer2AllShips);
+
+ gameController.play();
+
+ long numOfPlayer1AliveShips = gameController.getPlayer1().getMyShips().stream()
+ .filter(Ship::isAlive)
+ .count();
+ long numOfPlayer2AliveShips = gameController.getPlayer2().getMyShips().stream()
+ .filter(Ship::isAlive)
+ .count();
+
+ assertEquals(1, numOfPlayer1AliveShips);
+ assertEquals(0, numOfPlayer2AliveShips);
+ }
+
+ @Test
+ void testDefineWinner() {
+ GameController gameController = new GameController();
+ Player player1 = gameController.getPlayer1();
+ Player player2 = gameController.getPlayer2();
+ player1.setName("Tom");
+ player2.setName("Vera");
+
+ Ship ship = new Ship(Arrays.asList(new Point(1, 1)));
+ List tomShips = gameController.getPlayer1().getMyShips();
+ tomShips.add(ship);
+
+ gameController.defineWinner();
+
+ assertEquals(GAMEOVER + "Tom!", getOutput());
+ removeFromOutput(GAMEOVER + "Tom!");
+
+ List veraShips = gameController.getPlayer2().getMyShips();
+ veraShips.add(ship);
+ tomShips.remove(0);
+
+ gameController.defineWinner();
+ assertEquals(GAMEOVER + "Vera!", getOutput());
+ removeFromOutput(GAMEOVER + "Vera!");
+
+ veraShips.remove(0);
+ gameController.defineWinner();
+ assertEquals(TIE, getOutput());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/course_project/sea_battle/ModelTest.java b/src/test/java/course_project/sea_battle/ModelTest.java
new file mode 100644
index 00000000..296edb6c
--- /dev/null
+++ b/src/test/java/course_project/sea_battle/ModelTest.java
@@ -0,0 +1,71 @@
+package course_project.sea_battle;
+
+import course_project.sea_battle.boards.MyBoard;
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.model.Point;
+import course_project.sea_battle.model.Ship;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ModelTest {
+ @Test
+ void testPoint() {
+ Point point1 = new Point(1, 2);
+ Point point2 = new Point(1, 2);
+ Point point3 = new Point(3, 3);
+
+ assertEquals(1, point1.getX());
+ assertEquals(2, point1.getY());
+ assertEquals(point1, point2);
+ assertEquals(point1.hashCode(), point2.hashCode());
+ assertNotEquals(point1, point3);
+ assertEquals("[1,2]", point1.toString());
+ }
+
+ @Test
+ void testShip() {
+ ArrayList shipCoordinates = new ArrayList<>();
+ shipCoordinates.add(new Point(0, 0));
+ shipCoordinates.add(new Point(0, 1));
+
+ Ship ship = new Ship(shipCoordinates);
+
+ assertEquals(shipCoordinates, ship.getCoordinates());
+ assertEquals(2, ship.getCoordinates().size());
+
+ assertTrue(ship.isAlive());
+ assertEquals(2, ship.getLives());
+ ship.setLives(0);
+ assertFalse(ship.isAlive());
+ }
+
+ @Test
+ void testBoard() {
+ int[][] myBoardTest = new int[10][10];
+
+ MyBoard myBoard = new MyBoard();
+ MyBoard myShots = new MyBoard();
+
+ Player player = new Player(myBoard, myShots);
+ assertEquals(0, player.getMyShips().size());
+
+ List coordinates = new ArrayList<>();
+ coordinates.add(new Point(0, 0));
+ coordinates.add(new Point(0, 1));
+
+ Ship ship = new Ship(coordinates);
+ player.getMyBoard().placeShip(ship);
+ player.getMyShips().add(ship);
+
+ assertEquals(1, player.getMyShips().size());
+
+ myBoardTest[0][0] = 1;
+ myBoardTest[0][1] = 1;
+ assertArrayEquals(myBoardTest, myBoard.getBoard());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/course_project/sea_battle/ViewTest.java b/src/test/java/course_project/sea_battle/ViewTest.java
new file mode 100644
index 00000000..18dea7e1
--- /dev/null
+++ b/src/test/java/course_project/sea_battle/ViewTest.java
@@ -0,0 +1,143 @@
+package course_project.sea_battle;
+
+import base.UnitBase;
+import course_project.sea_battle.boards.MyBoard;
+import course_project.sea_battle.model.Player;
+import course_project.sea_battle.model.Point;
+import course_project.sea_battle.model.Ship;
+import course_project.sea_battle.model.Shot;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+
+import static course_project.sea_battle.service.inputs.InputShooterReader.putOnBoard;
+import static course_project.sea_battle.view.BoardPrinter.showBoards;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class ViewTest extends UnitBase {
+
+ private static final String CYAN = "\u001B[36m";
+ private static final String RESET = "\u001B[0m";
+ private static final String GREEN = "\u001B[32m";
+ private static final String RED = "\u001B[31m";
+
+ private static final String MISS = GREEN + "0" + RESET;
+ private static final String HIT = RED + "X" + RESET;
+ private static final String WAVE = CYAN + "~" + RESET;
+
+ MyBoard myBoard;
+ MyBoard myShots;
+ Player player1;
+
+ @Test
+ void testBoardPrinterEmptyBoard() {
+ createPlayers();
+ player1.setName("Tom");
+
+ showBoards(player1);
+ String expected = "MY BOARD (Tom) vs ENEMY BOARD\n" + "\n" +
+ "\t A B C D E F G H I J \t\t\t A B C D E F G H I J \n" +
+ " 1 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 1 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 2 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 2 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~";
+
+ assertEquals(expected, getOutput().replace(WAVE, "~").replaceAll("\r", ""));
+ }
+
+ @Test
+ void testBoardPrinterShipPlacer() {
+ createPlayers();
+
+ Ship ship1 = new Ship(Arrays.asList(new Point(0, 1), new Point(1, 1)));
+ myBoard.placeShip(ship1);
+
+ showBoards(player1);
+ String expected = "MY BOARD (null) vs ENEMY BOARD\n" + "\n" +
+ "\t A B C D E F G H I J \t\t\t A B C D E F G H I J \n" +
+ " 1 ~ W ~ ~ ~ ~ ~ ~ ~ ~\t\t 1 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 2 ~ W ~ ~ ~ ~ ~ ~ ~ ~\t\t 2 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~";
+
+ assertEquals(expected, getOutput().replace(WAVE, "~").replaceAll("\r", ""));
+ }
+
+ @Test
+ void testBoardPrinterMyShots() {
+ createPlayers();
+
+ putOnBoard(myShots, new Point(0, 0), Shot.MISS);
+ putOnBoard(myShots, new Point(1, 1), Shot.HIT);
+ putOnBoard(myShots, new Point(2, 2), Shot.KILLED);
+
+ showBoards(player1);
+ String expected = "MY BOARD (null) vs ENEMY BOARD\n" + "\n" +
+ "\t A B C D E F G H I J \t\t\t A B C D E F G H I J \n" +
+ " 1 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 1 0 ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 2 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 2 ~ X ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 3 ~ ~ X ~ ~ ~ ~ ~ ~ ~\n" +
+ " 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~";
+
+ assertEquals(expected, getOutput()
+ .replace(WAVE, "~")
+ .replace(MISS, "0")
+ .replace(HIT, "X")
+ .replaceAll("\r", ""));
+
+ }
+
+ @Test
+ void testBoardPrinterEnemyShots() {
+ createPlayers();
+
+ putOnBoard(myBoard, new Point(0, 1), Shot.MISS);
+ putOnBoard(myBoard, new Point(0, 2), Shot.HIT);
+ putOnBoard(myBoard, new Point(0, 3), Shot.KILLED);
+
+ showBoards(player1);
+ String expected = "MY BOARD (null) vs ENEMY BOARD\n" + "\n" +
+ "\t A B C D E F G H I J \t\t\t A B C D E F G H I J \n" +
+ " 1 ~ 0 X X ~ ~ ~ ~ ~ ~\t\t 1 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 2 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 2 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 3 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 4 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 5 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 6 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 8 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 9 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\n" +
+ " 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~\t\t 10 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~";
+
+ assertEquals(expected, getOutput()
+ .replace(WAVE, "~")
+ .replace(MISS, "0")
+ .replace(HIT, "X")
+ .replaceAll("\r", ""));
+ }
+
+ private void createPlayers() {
+ myBoard = new MyBoard();
+ myShots = new MyBoard();
+ player1 = new Player(myBoard, myShots);
+ }
+
+}
diff --git a/src/test/java/homework_2/PyramidPrinterTest.java b/src/test/java/homework_2/PyramidPrinterTest.java
new file mode 100644
index 00000000..129f8e7f
--- /dev/null
+++ b/src/test/java/homework_2/PyramidPrinterTest.java
@@ -0,0 +1,45 @@
+package homework_2;
+
+import base.UnitBase;
+import homework_2.pyramid_printer.PyramidPrinter;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class PyramidPrinterTest extends UnitBase {
+
+ private static final String ERROR = "Only 1 non-negative integer is allowed as passed parameter";
+
+ @Test
+ void given3_whenRun_then3linesOfX() {
+ setInput("3");
+ runPrintRemoveFromOutput();
+
+ assertEquals("x", getOutputLines()[0]);
+ assertEquals("xx", getOutputLines()[1]);
+ assertEquals("xxx", getOutputLines()[2]);
+ }
+
+ @Test
+ void given0_whenRun_thenEmpty() {
+ setInput("0");
+ runPrintRemoveFromOutput();
+ assertEquals("", getOutput());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"2 3", "abc", "-1"})
+ void givenERROR_whenRun_thenERROR(String input) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertEquals(ERROR, getOutput());
+ }
+
+ private void runPrintRemoveFromOutput() {
+ new PyramidPrinter().run();
+ printOut();
+ removeFromOutput("Please, input a number:");
+ }
+}
diff --git a/src/test/java/homework_2/RandomCharsTableTest.java b/src/test/java/homework_2/RandomCharsTableTest.java
new file mode 100644
index 00000000..692eec62
--- /dev/null
+++ b/src/test/java/homework_2/RandomCharsTableTest.java
@@ -0,0 +1,62 @@
+package homework_2;
+
+import base.UnitBase;
+import homework_2.random_chars_table.RandomCharsTable;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class RandomCharsTableTest extends UnitBase {
+
+ private static final String ERROR = "Passed parameters should match the format [positive integer] [positive integer] [even|odd]";
+
+ @Test
+ void given22odd_whenRun_thenRandomOutput() {
+ setInput("2 2 odd");
+ runPrintRemoveFromOutput();
+
+ boolean tableLine1 = getOutputLines()[0].matches("^[A-Z| ]{9}");
+ boolean tableLine2 = getOutputLines()[1].matches("^[A-Z| ]{9}");
+ boolean strategy = getOutputLines()[2].startsWith("Odd letters ");
+ String afterStrategy = getOutputLines()[2].substring(12);
+ boolean tableLine3 = afterStrategy.matches("^[ACEGIKMOQSUWY, -]*");
+
+ assertTrue(tableLine1);
+ assertTrue(tableLine2);
+ assertTrue(strategy);
+ assertTrue(tableLine3);
+ }
+
+ @Test
+ void given13even_whenRun_thenRandomOutput() {
+ setInput("1 3 even");
+ runPrintRemoveFromOutput();
+
+ boolean tableLine1 = getOutputLines()[0].matches("^[A-Z| ]{13}");
+ boolean strategy = getOutputLines()[1].startsWith("Even letters ");
+ String afterStrategy = getOutputLines()[1].substring(13);
+ boolean tableLine3 = afterStrategy.matches("^[BDFHJLNPRTVXZ, -]*");
+
+ assertTrue(tableLine1);
+ assertTrue(strategy);
+ assertTrue(tableLine3);
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"2 a odd", "2 -3 even", "2 3 odd 2", "2 3 ods", "2 3"})
+ void givenERROR_whenRun_thenERROR(String input) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertEquals(ERROR, getOutput());
+ }
+
+ private void runPrintRemoveFromOutput() {
+ new RandomCharsTable().run();
+ printOut();
+ removeFromOutput("[Input example: 2 3 odd]");
+ removeFromOutput("Please, input 2 positive numbers and a strategy (even/odd)");
+ }
+}
diff --git a/src/test/java/homework_2/TrafficLightTest.java b/src/test/java/homework_2/TrafficLightTest.java
new file mode 100644
index 00000000..3438ea62
--- /dev/null
+++ b/src/test/java/homework_2/TrafficLightTest.java
@@ -0,0 +1,57 @@
+package homework_2;
+
+import base.UnitBase;
+import homework_2.traffic_light.TrafficLight;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class TrafficLightTest extends UnitBase {
+
+ private static final String ERROR = "Only 1 non-negative integer is allowed as passed parameter";
+
+ @Test
+ void given2_whenRun_thenGreen() {
+ setInput("2");
+ runPrintRemoveFromOutput();
+ assertTrue(getOutput().contains("GREEN"));
+ }
+
+ @Test
+ void given95_whenRun_thenYellow() {
+ setInput("95");
+ runPrintRemoveFromOutput();
+ assertTrue(getOutput().contains("YELLOW"));
+ }
+
+ @Test
+ void given100_whenRun_thenRed() {
+ setInput("160");
+ runPrintRemoveFromOutput();
+ assertTrue(getOutput().contains("RED"));
+ }
+
+ @Test
+ void givenBigNumber_whenRun_thenDayIsOver() {
+ setInput("86400");
+ runPrintRemoveFromOutput();
+ assertEquals("The day is over", getOutput());
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"1 2", "-1", "abc"})
+ void givenERROR_whenRun_thenERROR(String input) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertEquals(ERROR, getOutput());
+ }
+
+ private void runPrintRemoveFromOutput() {
+ new TrafficLight().run();
+ printOut();
+ removeFromOutput("Please, input a number of seconds:");
+ }
+}
diff --git a/src/test/java/homework_4/customAnnotation/CoffeeTest.java b/src/test/java/homework_4/customAnnotation/CoffeeTest.java
new file mode 100644
index 00000000..595e4e87
--- /dev/null
+++ b/src/test/java/homework_4/customAnnotation/CoffeeTest.java
@@ -0,0 +1,44 @@
+package homework_4.customAnnotation;
+
+import base.UnitBase;
+import org.junit.jupiter.api.Test;
+
+import static homework_4.customAnnotation.ClassCoffeeAnnotation.Size.SMALL;
+import static org.junit.jupiter.api.Assertions.*;
+
+class CoffeeTest extends UnitBase {
+
+ @Test
+ void givenDefault_whenMainRun_thenStandartOutput() throws ClassNotFoundException, NoSuchMethodException {
+ new Main().main(new String[]{});
+ assertEquals("Size: MEDIUM", getOutputLines()[0]);
+ assertEquals("With milk: false", getOutputLines()[1]);
+ assertEquals("Price: 100₽", getOutputLines()[2]);
+ assertEquals("Give me please this one!", getOutputLines()[3]);
+ assertEquals("Start making coffee - true", getOutputLines()[5]);
+ assertEquals("Stop making coffee - true", getOutputLines()[7]);
+ }
+
+ @Test
+ void givenNoParameters_whenCreateExistingCoffee_thenFieldsAreEqual() {
+ Coffee myCoffee = new Coffee();
+
+ assertFalse(myCoffee.hasMilk);
+ assertEquals(100, myCoffee.price);
+ assertEquals("MEDIUM", myCoffee.size.toString());
+ }
+
+ @Test
+ void givenAnnotaionParameters_whenExtendsCoffee_thenFieldsDiffer() {
+
+ @ClassCoffeeAnnotation(price = 200, hasMilk = true, size = SMALL)
+ class NextCoffee extends Coffee {};
+
+ Coffee myCoffee = new NextCoffee();
+
+ assertTrue(myCoffee.hasMilk);
+ assertEquals(200, myCoffee.price);
+ assertEquals("SMALL", myCoffee.size.toString());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/homework_4/customFileReader/CustomFileReaderTest.java b/src/test/java/homework_4/customFileReader/CustomFileReaderTest.java
new file mode 100644
index 00000000..8b4fc5eb
--- /dev/null
+++ b/src/test/java/homework_4/customFileReader/CustomFileReaderTest.java
@@ -0,0 +1,60 @@
+package homework_4.customFileReader;
+
+import base.UnitBase;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.file.NoSuchFileException;
+import java.util.Arrays;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+class CustomFileReaderTest extends UnitBase {
+
+ private final String[] expected = new String[]
+ {"Я вас любил: любовь еще быть может",
+ "В душе моей угасла не совсем;",
+ "Но пусть она вас больше не тревожит;",
+ "Я не хочу печалить вас ничем"};
+
+ private String filename = "src/main/resources/custom_file_reader/file.txt";
+
+ @Test
+ void givenTextFile_whenRun1_thenEquals() throws IOException {
+ new CustomFileReader(filename).run1();
+ assertEquals(Arrays.toString(expected), Arrays.toString(getOutputLines()));
+ }
+
+ @Test
+ void givenTextFile_whenRun2_thenEquals() throws IOException {
+ new CustomFileReader(filename).run2();
+ assertEquals(Arrays.toString(expected), Arrays.toString(getOutputLines()));
+ }
+
+ @Test
+ void givenTextFile_whenRun3_thenEquals() throws IOException {
+ new CustomFileReader(filename).run3();
+ assertEquals(Arrays.toString(expected), Arrays.toString(getOutputLines()));
+ }
+
+ @Test
+ void givenTextFile_whenRun4_thenEquals() throws IOException {
+ new CustomFileReader(filename).run4();
+ assertEquals(Arrays.toString(expected), Arrays.toString(getOutputLines()));
+ }
+
+ @Test
+ void givenNotExistingFile_whenRun_thenException() {
+
+ filename = "src/main/resources/custom_file_reader/fileX.txt";
+
+ Assertions.assertThrows(FileNotFoundException.class, () -> new CustomFileReader(filename).run1());
+ Assertions.assertThrows(FileNotFoundException.class, () -> new CustomFileReader(filename).run2());
+
+ Assertions.assertThrows(NoSuchFileException.class, () -> new CustomFileReader(filename).run3());
+ Assertions.assertThrows(NoSuchFileException.class, () -> new CustomFileReader(filename).run4());
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/homework_4/singleton/SingletonTest.java b/src/test/java/homework_4/singleton/SingletonTest.java
new file mode 100644
index 00000000..b76a873a
--- /dev/null
+++ b/src/test/java/homework_4/singleton/SingletonTest.java
@@ -0,0 +1,16 @@
+package homework_4.singleton;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class SingletonTest {
+
+ @Test
+ void given2objects_whenRun_thenEquals() {
+ Singleton singleton = Singleton.getInstance();
+ Singleton singleton2 = Singleton.getInstance();
+ assertEquals(singleton, singleton2);
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/homework_5/customRegexMatcher/CustomRegexMatcherTest.java b/src/test/java/homework_5/customRegexMatcher/CustomRegexMatcherTest.java
new file mode 100644
index 00000000..3897d131
--- /dev/null
+++ b/src/test/java/homework_5/customRegexMatcher/CustomRegexMatcherTest.java
@@ -0,0 +1,38 @@
+package homework_5.customRegexMatcher;
+
+import base.UnitBase;
+import homework_5.powerOfNumber.PowerOfNumber;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class CustomRegexMatcherTest extends UnitBase {
+
+ @ParameterizedTest
+ @ValueSource(strings = {"ashandrikov@gmail.com", "123abc@yandex.ru", "r_n-13@mail.i.ua"})
+ void givenCorrectEmail_whenRun_thenTrue(String input) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertTrue(Boolean.parseBoolean(getOutput()));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"as.ua", "a@gmail.com a@gmail.com", "", "a@.ru"})
+ void givenIncorrectEmail_whenRun_thenFalse(String input) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertFalse(Boolean.parseBoolean(getOutput()));
+ }
+
+ private void runPrintRemoveFromOutput() {
+ new CustomRegexMatcher().run();
+ printOut();
+ removeFromOutput("Please, input your Email");
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/homework_5/powerOfNumber/PowerOfNumberTest.java b/src/test/java/homework_5/powerOfNumber/PowerOfNumberTest.java
new file mode 100644
index 00000000..60d936b2
--- /dev/null
+++ b/src/test/java/homework_5/powerOfNumber/PowerOfNumberTest.java
@@ -0,0 +1,49 @@
+package homework_5.powerOfNumber;
+
+import base.UnitBase;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class PowerOfNumberTest extends UnitBase {
+ private static final String ERROR = "Only 2 non-negative integers are allowed";
+
+ @ParameterizedTest
+ @MethodSource("testCases")
+ void givenCorrectInput_whenRun_thenCorrectOutput(String input, String expected) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertEquals(expected, getOutput());
+ }
+
+ static Stream testCases() {
+ return Stream.of(
+ Arguments.of("1 2", "1"),
+ Arguments.of("2 0", "1"),
+ Arguments.of("3 3", "27"),
+ Arguments.of("0 0", "1"),
+ Arguments.of("0 5", "0"),
+ Arguments.of(" 3 3 ", "27")
+ );
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"2 -1", "abc abc", "1", " 1 2 3", "", "-1 1"})
+ void givenERROR_whenRun_thenERROR(String input) {
+ setInput(input);
+ runPrintRemoveFromOutput();
+ assertEquals(ERROR, getOutput());
+ }
+
+ private void runPrintRemoveFromOutput() {
+ new PowerOfNumber().run();
+ printOut();
+ removeFromOutput("Please, input 2 non-negative numbers:");
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/homework_6/mapProblemsGenerator/MapProblemsGeneratorTest.java b/src/test/java/homework_6/mapProblemsGenerator/MapProblemsGeneratorTest.java
new file mode 100644
index 00000000..f114dda3
--- /dev/null
+++ b/src/test/java/homework_6/mapProblemsGenerator/MapProblemsGeneratorTest.java
@@ -0,0 +1,35 @@
+package homework_6.mapProblemsGenerator;
+
+import base.UnitBase;
+import org.junit.jupiter.api.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class MapProblemsGeneratorTest extends UnitBase {
+
+ @Test
+ void testCatClass() {
+ MapProblemsCollisionGenerator generator1 = new MapProblemsCollisionGenerator(3);
+ MapProblemsCollisionGenerator generator2 = new MapProblemsCollisionGenerator(4);
+ assertEquals(generator1.hashCode(), generator2.hashCode());
+ assertNotEquals(generator1, generator2);
+ }
+
+ @Test
+ void testDatClass() {
+ MapProblemsMutableGenerator generator1 = new MapProblemsMutableGenerator(3);
+ MapProblemsMutableGenerator generator2 = new MapProblemsMutableGenerator(3);
+ MapProblemsMutableGenerator generator3 = new MapProblemsMutableGenerator(4);
+ assertEquals(generator1, generator2);
+ assertNotEquals(generator1, generator3);
+
+ Map map = new HashMap<>();
+ map.put(generator1, "someString");
+ generator1.setSomeField(4);
+ assertFalse(map.containsKey(generator1));
+ }
+
+}
\ No newline at end of file