diff --git a/README.md b/README.md index 5d686e9f..fb0701e0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,25 @@ # Java Core June 2021 -## *Nikolaev Artem* +## *Chertov Nikita* | 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](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_1) | The app that reads input arguments and prints them, until "error" argument | +| HW2.1 | [Pyramid Printer](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_2/pyramid_printer) | The app prints pyramid of entered height with "x" symbols| +| HW2.2 | [Traffic Light](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_2/traffic_light) | The app shows traffic light corresponding to entered time of the day| +| HW2.3 | [Random Chars Table](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_2/random_chars_table) | The app prints table of randomized letters and outputs list of odd/even letters in it| +| HW2 Tests | [Tests](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/test/java/homework_2_test/) | Tests for homework 2| +| HW3 | [Immutable Class](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_3) | Cafe class that shows immutable class' key features | +| HW4.1 | [Custom Annotation](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_4/custom_annotation) | Default User Info declares custom annotation and Profile class uses it| +| HW4.2 | [Custom File Reader](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_4/custom_file_reader) | The app reads text from file and outputs it without dots and commas| +| HW4.3 | [Singleton](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_4/singleton) | Theater class as an example of singleton pattern| +| HW4 Tests | [Tests](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/test/java/homework_4_test/) | Tests for homework 4| +| HW5.1 | [Power of number](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_5/power_of_number) | The app that raises a number to a power | +| HW5.2 | [Custom regex matcher](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_5/custom_regex_matcher) | The app that checks input text for IP | +| HW5 Tests | [Tests](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/test/java/homework_5_test/) | Tests for homework 5| +| HW6 | [Map problems generator](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_6/) | Class with subclasses that create collisions and retrieval problems in hashmap | +| HW6 Tests | [Tests](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/test/java/homework_6_test/) | Tests for homework 6| +| HW7 | [Functional Interface](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/homework_7/) | Functional interface with method to transform Kitten and subclasses to Cat and subclasses | +| CP | [Course project](https://github.com/NikolaevArtem/Java_Core_June_2021/tree/feature/ChertovNikita/src/main/java/course_project/) | Sea battle game | -[Link to markdown giude](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet) +[Link to my CodingBat](https://codingbat.com/done?user=sotheres@gmail.com&tag=6008519258) \ No newline at end of file diff --git a/build.gradle b/build.gradle index b91dc843..522c2e14 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,7 @@ repositories { dependencies { 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/Main.java b/src/main/java/course_project/Main.java new file mode 100644 index 00000000..83ee5215 --- /dev/null +++ b/src/main/java/course_project/Main.java @@ -0,0 +1,8 @@ +package course_project; + +public class Main { + + public static void main(String[] args) { + new SeaBattle().playVsComputer(); + } +} diff --git a/src/main/java/course_project/SeaBattle.java b/src/main/java/course_project/SeaBattle.java new file mode 100644 index 00000000..dcf61d07 --- /dev/null +++ b/src/main/java/course_project/SeaBattle.java @@ -0,0 +1,108 @@ +package course_project; + +import course_project.components.Coordinate; +import course_project.components.PlayingField; +import course_project.util.PlayingFieldPrinter; +import course_project.util.user_input_reader.UserInputReader; +import course_project.util.user_input_reader.UserShotInputReader; +import course_project.util.ship_placer.ComputerShipPlacer; +import course_project.util.ship_placer.UserShipPlacer; + +import java.util.Random; +import java.util.Scanner; + +public class SeaBattle { + + final PlayingField playersField = new PlayingField(); + final PlayingField enemyField = new PlayingField(); + final PlayingFieldPrinter printer = new PlayingFieldPrinter(); + private final Scanner scanner = new Scanner(System.in); + private final Random randomGenerator = new Random(); + private boolean isHit; + + public void playVsComputer() { + placePlayersShips(); + placeComputerShips(); + makeMoves(); + defineWinner(); + closeInput(); + } + + void placePlayersShips() { + new UserShipPlacer(scanner).placeShips(playersField); + } + + void placeComputerShips() { + new ComputerShipPlacer().placeShips(enemyField); + } + + void makeMoves() { + UserInputReader inputReader = new UserShotInputReader(scanner); + while (!playersField.getPlayersShips().isEmpty() && !enemyField.getPlayersShips().isEmpty()) { + playersMove(inputReader); + computersMove(); + } + } + + private void playersMove(UserInputReader inputReader) { + do { + System.out.println("Enemy field:"); + printer.printShotCells(enemyField); + Coordinate shotCoordinate = inputReader.getPointFromInput(); + playersShot(shotCoordinate); + delayPrint(); + } while (isHit && !enemyField.getPlayersShips().isEmpty()); + } + + private void playersShot(Coordinate point) { + isHit = enemyField.placeShot(point); + } + + private void delayPrint() { + try { + Thread.sleep(700); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + + private void computersMove() { + if (!enemyField.getPlayersShips().isEmpty()) { + do { + enemyShot(); + delayPrint(); + System.out.println("Your field:"); + printer.printField(playersField); + } while (isHit && !playersField.getPlayersShips().isEmpty()); + } + } + + private void enemyShot() { + Coordinate cell = createCellToShoot(); + System.out.println("Computer shoot at : " + cell); + isHit = playersField.placeShot(cell); + } + + private Coordinate createCellToShoot() { + Coordinate cellToShoot; + do { + int x = randomGenerator.nextInt(10); + int y = randomGenerator.nextInt(10); + cellToShoot = new Coordinate(x, y); + } while (playersField.isCellShot(cellToShoot)); + + return cellToShoot; + } + + private void closeInput() { + scanner.close(); + } + + void defineWinner() { + if (enemyField.getPlayersShips().isEmpty()) { + System.out.println("Player won!"); + } else { + System.out.println("Computer won!"); + } + } +} diff --git a/src/main/java/course_project/components/Coordinate.java b/src/main/java/course_project/components/Coordinate.java new file mode 100644 index 00000000..d5bc230e --- /dev/null +++ b/src/main/java/course_project/components/Coordinate.java @@ -0,0 +1,45 @@ +package course_project.components; + +public final class Coordinate { + + private final int x; + private final int y; + + public Coordinate(int x, int y) { + this.x = x; + this.y = y; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof Coordinate)) { + return false; + } + Coordinate other = (Coordinate) obj; + + return (x == other.x) && (y == other.y); + } + + @Override + public int hashCode() { + int result = Integer.hashCode(x); + result = 31 * result + Integer.hashCode(y); + return result; + } + + @Override + public String toString() { + return "" + (char) (y + 65) + (x + 1); + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } +} diff --git a/src/main/java/course_project/components/PlayingField.java b/src/main/java/course_project/components/PlayingField.java new file mode 100644 index 00000000..69224768 --- /dev/null +++ b/src/main/java/course_project/components/PlayingField.java @@ -0,0 +1,87 @@ +package course_project.components; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PlayingField { + + private final int[][] fleet = new int[10][10]; + private final boolean[][] cellsShot = new boolean[10][10]; + private final Map coordinateToShip = new HashMap<>(32); // size for 10 ships and no rehashing + private final List playersShips = new ArrayList<>(); + + public Map getCoordinateMapping() { + return coordinateToShip; + } + + public List getPlayersShips() { + return playersShips; + } + + public int[][] getFleet() { + return fleet; + } + + public boolean[][] getCellsShot() { + return cellsShot; + } + + public boolean isCellShot(Coordinate cell) { + return cellsShot[cell.getX()][cell.getY()]; + } + + public void placeShip(Ship ship) { + int size = ship.getSize(); + for (Coordinate cell : ship.getCoordinates()) { + fleet[cell.getX()][cell.getY()] = size; + coordinateToShip.put(cell, ship); + } + playersShips.add(ship); + } + + public boolean placeShot(Coordinate cell) { + if (!cellsShot[cell.getX()][cell.getY()]) { + cellsShot[cell.getX()][cell.getY()] = true; + if (coordinateToShip.containsKey(cell)) { + System.out.println("Hit"); + shootAtShip(coordinateToShip.get(cell)); + return true; + } + } + System.out.println("Miss"); + return false; + } + + private void shootAtShip(Ship hitShip) { + hitShip.gotShot(); + if (hitShip.isSunk()) { + sinkShip(hitShip); + } + } + + private void sinkShip(Ship hitShip) { + playersShips.remove(hitShip); + markAdjacentCells(hitShip); + System.out.println(hitShip.getSize() + "-deck ship is sunk"); + } + + private void markAdjacentCells(Ship hitShip) { + for (Coordinate c : hitShip.getCoordinates()) { + if (c.getX() > 0) { + cellsShot[c.getX() - 1][c.getY()] = true; + } + if (c.getX() < 9) { + cellsShot[c.getX() + 1][c.getY()] = true; + } + if (c.getY() > 0) { + cellsShot[c.getX()][c.getY() - 1] = true; + } + if (c.getY() < 9) { + cellsShot[c.getX()][c.getY() + 1] = true; + } + } + } + +} diff --git a/src/main/java/course_project/components/Ship.java b/src/main/java/course_project/components/Ship.java new file mode 100644 index 00000000..e546ff6e --- /dev/null +++ b/src/main/java/course_project/components/Ship.java @@ -0,0 +1,37 @@ +package course_project.components; + +import java.util.ArrayList; +import java.util.List; + +public class Ship { + + private final int size; + private final List coordinates; + private int health; + private boolean sunk; + + public Ship(int size, List coordinates) { + health = size; + this.size = size; + this.coordinates = new ArrayList<>(coordinates); + } + + public List getCoordinates() { + return new ArrayList<>(coordinates); + } + + public void gotShot() { + health--; + if (health == 0) { + sunk = true; + } + } + + public int getSize() { + return size; + } + + public boolean isSunk() { + return sunk; + } +} diff --git a/src/main/java/course_project/util/PlayingFieldPrinter.java b/src/main/java/course_project/util/PlayingFieldPrinter.java new file mode 100644 index 00000000..1cede036 --- /dev/null +++ b/src/main/java/course_project/util/PlayingFieldPrinter.java @@ -0,0 +1,76 @@ +package course_project.util; + +import course_project.components.PlayingField; + +public class PlayingFieldPrinter { + + public void printField(PlayingField field) { + printHeader(); + printShipsAndShots(field); + } + + private void printHeader() { + System.out.print("\t"); + for (int i = 0; i < 10; i++) { + char ch = (char) (i + 65); + System.out.print(ch + " "); + } + System.out.println(); + } + + private void printShipsAndShots(PlayingField field) { + int rowNumber = 1; + int[][] fleet = field.getFleet(); + boolean[][] cellsShot = field.getCellsShot(); + + for (int i = 0; i < fleet.length; i++) { + System.out.print(rowNumber++ + "\t"); + for (int j = 0; j < fleet[0].length; j++) { + if (fleet[i][j] == 0) { + if (cellsShot[i][j]) { + System.out.print("* "); + } else { + System.out.print("- "); + } + } else { + if (cellsShot[i][j]) { + System.out.print("X "); + } else { + System.out.print(fleet[i][j] + " "); + } + } + } + System.out.println(); + } + System.out.println(); + } + + public void printShotCells(PlayingField field) { + printHeader(); + printShots(field); + } + + private void printShots(PlayingField field) { + int rowNumber = 1; + int[][] fleet = field.getFleet(); + boolean[][] cellsShot = field.getCellsShot(); + + for (int i = 0; i < cellsShot.length; i++) { + System.out.print(rowNumber++ + "\t"); + for (int j = 0; j < cellsShot[0].length; j++) { + if (cellsShot[i][j]) { + if (fleet[i][j] == 0) { + System.out.print("* "); + } else { + System.out.print("X "); + } + } else { + System.out.print("- "); + } + } + System.out.println(); + } + System.out.println(); + } + +} diff --git a/src/main/java/course_project/util/ship_placer/ComputerShipPlacer.java b/src/main/java/course_project/util/ship_placer/ComputerShipPlacer.java new file mode 100644 index 00000000..342bfc51 --- /dev/null +++ b/src/main/java/course_project/util/ship_placer/ComputerShipPlacer.java @@ -0,0 +1,75 @@ +package course_project.util.ship_placer; + +import course_project.components.Coordinate; +import course_project.components.PlayingField; +import course_project.components.Ship; + +import java.util.ArrayList; +import java.util.Random; +import java.util.Set; + +public class ComputerShipPlacer implements ShipPlacer { + + private final Random randomGenerator = new Random(); + private PlayingField playingField; + private int sizeOfShip; + + public void placeShips(PlayingField playingField) { + this.playingField = playingField; + placeShipsOfAllSizes(); + } + + private void placeShipsOfAllSizes() { + for (sizeOfShip = 4; sizeOfShip >= 1; sizeOfShip--) { + placeShipsOfCurrentSize(); + } + } + + private void placeShipsOfCurrentSize() { + for (int shipNumber = 0; shipNumber <= 4 - sizeOfShip; shipNumber++) { + ArrayList coordinatesList = generateCoordinates(); + Ship ship = new Ship(sizeOfShip, coordinatesList); + playingField.placeShip(ship); + } + } + + private ArrayList generateCoordinates() { + ArrayList shipCoordinates; + Set occupiedCells = playingField.getCoordinateMapping().keySet(); + + do { + boolean verticalOrientation = randomGenerator.nextInt(2) == 1; + Coordinate topLeftPoint = createTopLeftPoint(verticalOrientation); + shipCoordinates = createAllOtherCoordinates(topLeftPoint, verticalOrientation); + } while (isShipCollidesOrAdjacent(shipCoordinates, occupiedCells)); + + return shipCoordinates; + } + + private Coordinate createTopLeftPoint(boolean vertOrientation) { + Coordinate topLeft; + do { + int x = randomGenerator.nextInt(10); + int y = randomGenerator.nextInt(10); + topLeft = new Coordinate(x, y); + } while (isNotValidForCurrentSizeOfShip(topLeft, vertOrientation, sizeOfShip)); + + return topLeft; + } + + private ArrayList createAllOtherCoordinates(Coordinate topLeft, boolean verticalOrientation) { + ArrayList coordinatesList = new ArrayList<>(); + coordinatesList.add(topLeft); + if (verticalOrientation) { + for (int i = 1; i < sizeOfShip; i++) { + coordinatesList.add(new Coordinate(topLeft.getX() + i, topLeft.getY())); + } + } else { + for (int i = 1; i < sizeOfShip; i++) { + coordinatesList.add(new Coordinate(topLeft.getX(), topLeft.getY() + i)); + } + } + return coordinatesList; + } + +} diff --git a/src/main/java/course_project/util/ship_placer/ShipPlacer.java b/src/main/java/course_project/util/ship_placer/ShipPlacer.java new file mode 100644 index 00000000..d1cfcdfd --- /dev/null +++ b/src/main/java/course_project/util/ship_placer/ShipPlacer.java @@ -0,0 +1,50 @@ +package course_project.util.ship_placer; + +import course_project.components.Coordinate; +import course_project.components.PlayingField; + +import java.util.ArrayList; +import java.util.Set; + +public interface ShipPlacer { + + void placeShips(PlayingField playingField); + + default boolean isShipCollidesOrAdjacent(ArrayList shipCoordinates, Set occupiedCells) { + for (Coordinate c : shipCoordinates) { + if (occupiedCells.contains(c) || isAdjacentToOccupiedCell(c, occupiedCells)) { + return true; + } + } + return false; + } + + default boolean isAdjacentToOccupiedCell(Coordinate shipsCoordinate, Set occupiedCells) { + ArrayList adjacentCoordinates = new ArrayList<>(); + + if (shipsCoordinate.getX() > 0) { + adjacentCoordinates.add(new Coordinate(shipsCoordinate.getX() - 1, shipsCoordinate.getY())); + } + if (shipsCoordinate.getX() < 9) { + adjacentCoordinates.add(new Coordinate(shipsCoordinate.getX() + 1, shipsCoordinate.getY())); + } + if (shipsCoordinate.getY() > 0) { + adjacentCoordinates.add(new Coordinate(shipsCoordinate.getX(), shipsCoordinate.getY() - 1)); + } + if (shipsCoordinate.getY() < 9) { + adjacentCoordinates.add(new Coordinate(shipsCoordinate.getX(), shipsCoordinate.getY() + 1)); + } + for (Coordinate adjacentCoordinate : adjacentCoordinates) { + if (occupiedCells.contains(adjacentCoordinate)) { + return true; + } + } + return false; + } + + // Make sure there is enough room for ship + default boolean isNotValidForCurrentSizeOfShip(Coordinate cell, boolean verticalOrientation, int sizeOfShip) { + return ((cell.getX() > (10 - sizeOfShip)) && verticalOrientation) + || ((cell.getY() > (10 - sizeOfShip)) && !verticalOrientation); + } +} diff --git a/src/main/java/course_project/util/ship_placer/UserShipPlacer.java b/src/main/java/course_project/util/ship_placer/UserShipPlacer.java new file mode 100644 index 00000000..663dad06 --- /dev/null +++ b/src/main/java/course_project/util/ship_placer/UserShipPlacer.java @@ -0,0 +1,96 @@ +package course_project.util.ship_placer; + +import course_project.components.Coordinate; +import course_project.components.PlayingField; +import course_project.components.Ship; +import course_project.util.PlayingFieldPrinter; +import course_project.util.user_input_reader.UserShipInputReader; + +import java.util.ArrayList; +import java.util.Scanner; +import java.util.Set; + +public class UserShipPlacer implements ShipPlacer { + + private final UserShipInputReader inputReader; + private PlayingField playingField; + private int sizeOfShip; + + public UserShipPlacer(Scanner scanner) { + inputReader = new UserShipInputReader(scanner); + } + + public void placeShips(PlayingField playingField) { + new PlayingFieldPrinter().printField(playingField); + this.playingField = playingField; + placeShipsOfAllSizes(); + } + + private void placeShipsOfAllSizes() { + System.out.println("Enter top left coordinates and orientation of the ship\n" + + "in A-J 1-10 ver/hor format (e.g. A1 ver)\n"); + for (sizeOfShip = 4; sizeOfShip >= 1; sizeOfShip--) { + System.out.println("Placing " + sizeOfShip + "-deck ships"); + placeShipsOfCurrentSize(); + } + } + + private void placeShipsOfCurrentSize() { + for (int shipNumber = 1; shipNumber <= 5 - sizeOfShip; shipNumber++) { + ArrayList coordinatesList = getCoordinatesFromInput(shipNumber); + Ship ship = new Ship(sizeOfShip, coordinatesList); + playingField.placeShip(ship); + } + } + + private ArrayList getCoordinatesFromInput(int shipNumber) { + Set occupiedCells = playingField.getCoordinateMapping().keySet(); + System.out.println(shipNumber + " ship:"); + + ArrayList shipCoordinates = tryToGetCoordinates(); + while (isShipCollidesOrAdjacent(shipCoordinates, occupiedCells)) { + System.out.println("Ship collides with or adjacent to another. Please repeat input"); + shipCoordinates = tryToGetCoordinates(); + } + + return shipCoordinates; + } + + private ArrayList tryToGetCoordinates() { + Coordinate topLeftPoint = getTopLeftPoint(); + String orientation = inputReader.getOrientation(); + return createAllOtherCoordinates(topLeftPoint, orientation); + } + + private Coordinate getTopLeftPoint() { + boolean vertOrientation; + Coordinate topLeft; + + topLeft = inputReader.getPointFromInput(); + vertOrientation = inputReader.getOrientation().equals("ver"); + while (isNotValidForCurrentSizeOfShip(topLeft, vertOrientation, sizeOfShip)) { + System.out.println("Coordinate is invalid (ship doesn't fit into field). Please repeat input"); + topLeft = inputReader.getPointFromInput(); + vertOrientation = inputReader.getOrientation().equals("ver"); + } + + return topLeft; + } + + private ArrayList createAllOtherCoordinates(Coordinate topLeft, String orientation) { + ArrayList coordinatesList = new ArrayList<>(); + coordinatesList.add(topLeft); + + if (orientation.equalsIgnoreCase("ver")) { + for (int i = 1; i < sizeOfShip; i++) { + coordinatesList.add(new Coordinate(topLeft.getX() + i, topLeft.getY())); + } + } else { + for (int i = 1; i < sizeOfShip; i++) { + coordinatesList.add(new Coordinate(topLeft.getX(), topLeft.getY() + i)); + } + } + return coordinatesList; + } + +} diff --git a/src/main/java/course_project/util/user_input_reader/UserInputReader.java b/src/main/java/course_project/util/user_input_reader/UserInputReader.java new file mode 100644 index 00000000..b93e1df3 --- /dev/null +++ b/src/main/java/course_project/util/user_input_reader/UserInputReader.java @@ -0,0 +1,23 @@ +package course_project.util.user_input_reader; + +import course_project.components.Coordinate; + +import java.util.Scanner; + +public abstract class UserInputReader { + + protected Scanner scanner; + protected int x; + protected int y; + + public abstract Coordinate getPointFromInput(); + + protected void resetState() { + x = -1; // reset state of a reader + y = -1; // to receive next input + } + + protected boolean outOfRange(int x, int y) { + return (x < 0 || x > 9) || (y < 0 || y > 9); + } +} diff --git a/src/main/java/course_project/util/user_input_reader/UserShipInputReader.java b/src/main/java/course_project/util/user_input_reader/UserShipInputReader.java new file mode 100644 index 00000000..bd0264fd --- /dev/null +++ b/src/main/java/course_project/util/user_input_reader/UserShipInputReader.java @@ -0,0 +1,44 @@ +package course_project.util.user_input_reader; + +import course_project.components.Coordinate; + +import java.util.Scanner; + +public class UserShipInputReader extends UserInputReader { + + private String orientation; + + public UserShipInputReader(Scanner scanner) { + this.scanner = scanner; + } + + public String getOrientation() { + return orientation; + } + + public Coordinate getPointFromInput() { + resetState(); + while (outOfRange(x, y)) { + String input = scanner.nextLine(); + parseInput(input); + validateInput(); + } + return new Coordinate(x, y); + } + + private void parseInput(String input) { + if (input.matches("[a-jA-J]([1-9]|10) (ver|hor)")) { + String[] inputWords = input.split(" "); + x = Integer.parseInt(inputWords[0].substring(1)) - 1; + y = inputWords[0].toUpperCase().charAt(0) - 65; + orientation = inputWords[1]; + } + } + + private void validateInput() { + if (outOfRange(x, y)) { + System.out.println("Coordinates should be in range A-J, 1-10 (e.g. A1-J10)"); + System.out.println("Orientation should be \"ver\" or \"hor\""); + } + } +} diff --git a/src/main/java/course_project/util/user_input_reader/UserShotInputReader.java b/src/main/java/course_project/util/user_input_reader/UserShotInputReader.java new file mode 100644 index 00000000..a2900f08 --- /dev/null +++ b/src/main/java/course_project/util/user_input_reader/UserShotInputReader.java @@ -0,0 +1,36 @@ +package course_project.util.user_input_reader; + +import course_project.components.Coordinate; + +import java.util.Scanner; + +public class UserShotInputReader extends UserInputReader { + + public UserShotInputReader(Scanner scanner) { + this.scanner = scanner; + } + + public Coordinate getPointFromInput() { + System.out.print("Enter coordinate to shoot at in A-J 1-10 format (e.g. A1): "); + resetState(); + while (outOfRange(x, y)) { + String input = scanner.nextLine(); + parseInputForShot(input); + validateInputForShot(); + } + return new Coordinate(x, y); + } + + private void parseInputForShot(String input) { + if (input.matches("[a-jA-J]([1-9]|10)")) { + x = Integer.parseInt(input.substring(1)) - 1; + y = input.toUpperCase().charAt(0) - 65; + } + } + + private void validateInputForShot() { + if (outOfRange(x, y)) { + System.out.println("Coordinates should be in range A-J, 1-10 (e.g. A1-J10)"); + } + } +} diff --git a/src/main/java/homework_1/Main.java b/src/main/java/homework_1/Main.java index 07c029a2..fa21d3a1 100644 --- a/src/main/java/homework_1/Main.java +++ b/src/main/java/homework_1/Main.java @@ -2,8 +2,13 @@ public class Main { - public static void main(String[] args) { - System.out.println("Hello homework!"); - } - + public static void main(String[] args) { + for (String arg : args) { + if (arg.equals("error")) { + System.err.println("Alarm!"); + break; + } + System.out.println(arg + ": " + arg.length()); + } + } } 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..eaa7e9dd --- /dev/null +++ b/src/main/java/homework_2/pyramid_printer/PyramidPrinter.java @@ -0,0 +1,29 @@ +package homework_2.pyramid_printer; + +import java.util.Scanner; + +public class PyramidPrinter { + + public void run() { + System.out.print("Enter pyramid height: "); + + int height; + try (Scanner scan = new Scanner(System.in)) { + String input = scan.nextLine().trim(); + height = Integer.parseInt(input); + if (height < 0) { + throw new IllegalArgumentException(); + } + } catch (RuntimeException e) { + System.out.println("Only 1 non-negative integer is allowed as passed parameter"); + return; + } + + for (int i = 0; i < height; i++) { + for (int j = 0; j < i + 1; j++) { + System.out.print("x"); + } + System.out.println(); + } + } +} \ No newline at end of file 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..cab57499 --- /dev/null +++ b/src/main/java/homework_2/random_chars_table/RandomCharsTable.java @@ -0,0 +1,43 @@ +package homework_2.random_chars_table; + +import java.util.Scanner; + +public class RandomCharsTable { + + public void run() { + System.out.print("Enter length, width of the table and choose even or odd letters: "); + + int rows; + int columns; + String strategy; + try (Scanner scan = new Scanner(System.in)) { + rows = scan.nextInt(); + columns = scan.nextInt(); + strategy = scan.nextLine().trim(); + validateInput(rows, columns, strategy); + } catch (RuntimeException e) { + System.out.println("Passed parameters should match the format " + + "[positive integer] [positive integer] [even|odd]"); + return; + } + + TablePrinter tp = new TablePrinter(rows, columns, strategy); + tp.printTable(); + tp.printLetters(); + } + + private void validateInput(int row, int column, String strategy) { + if (row <= 0) { + throw new IllegalArgumentException(); + } + if (column <= 0) { + throw new IllegalArgumentException(); + } + if (strategy.split(" ").length > 1) { + throw new IllegalArgumentException(); + } + if (!"even".equalsIgnoreCase(strategy) && !"odd".equalsIgnoreCase(strategy)) { + throw new IllegalArgumentException(); + } + } +} diff --git a/src/main/java/homework_2/random_chars_table/TablePrinter.java b/src/main/java/homework_2/random_chars_table/TablePrinter.java new file mode 100644 index 00000000..15b19b38 --- /dev/null +++ b/src/main/java/homework_2/random_chars_table/TablePrinter.java @@ -0,0 +1,46 @@ +package homework_2.random_chars_table; + +import java.util.LinkedList; +import java.util.List; + +class TablePrinter { + + private final int rows; + private final int columns; + private final int remains; + private final String strategy; + private List charList; + + public TablePrinter(int rows, int columns, String strategy) { + this.rows = rows; + this.columns = columns; + this.strategy = strategy; + remains = "even".equalsIgnoreCase(strategy) ? 0 : 1; + } + + public void printTable() { + charList = new LinkedList<>(); + for (int i = 0; i < rows; i++) { + System.out.print("|"); + for (int j = 0; j < columns; j++) { + char ch = (char) (Math.round(Math.random() * 25) + 65); + if (ch % 2 == remains && !charList.contains(ch)) { + charList.add(ch); + } + System.out.print(ch + "|"); + } + System.out.println(); + } + } + + public void printLetters() { + System.out.print(strategy + " letters - "); + for (int i = 0; i < charList.size(); i++) { + if (i != charList.size() - 1) { + System.out.print(charList.get(i) + ", "); + } else { + System.out.println(charList.get(i)); + } + } + } +} diff --git a/src/main/java/homework_2/traffic_light/ExtraModeTrafficLight.java b/src/main/java/homework_2/traffic_light/ExtraModeTrafficLight.java new file mode 100644 index 00000000..61905c57 --- /dev/null +++ b/src/main/java/homework_2/traffic_light/ExtraModeTrafficLight.java @@ -0,0 +1,39 @@ +package homework_2.traffic_light; + +import java.time.LocalTime; +import java.time.format.DateTimeParseException; +import java.util.Scanner; + +public class ExtraModeTrafficLight { + + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_YELLOW = "\u001B[33m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_RESET = "\u001B[0m"; + + public void run() { + System.out.print("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + int passedSeconds; + try (Scanner scan = new Scanner(System.in)) { + String input = scan.nextLine().trim(); + LocalTime lc = LocalTime.parse(input); + passedSeconds = lc.toSecondOfDay(); + } catch (DateTimeParseException e) { + System.out.println("Not a valid hh:mm:ss format"); + return; + } + + int calculationSeconds = passedSeconds % 60; + String light; + if (calculationSeconds >= 0 && calculationSeconds < 35) { + light = ANSI_GREEN + "GREEN" + ANSI_RESET; + } else if ((calculationSeconds >= 35 && calculationSeconds < 40) || calculationSeconds >= 55) { + light = ANSI_YELLOW + "YELLOW" + ANSI_RESET; + } else { + light = ANSI_RED + "RED" + ANSI_RESET; + } + + System.out.println(light); + } +} \ No newline at end of file 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..f40680e2 --- /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 ExtraModeTrafficLight().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..5a7b5a21 --- /dev/null +++ b/src/main/java/homework_2/traffic_light/TrafficLight.java @@ -0,0 +1,49 @@ +package homework_2.traffic_light; + +import java.util.Scanner; + +public class TrafficLight { + + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_YELLOW = "\u001B[33m"; + private static final String ANSI_RED = "\u001B[31m"; + private static final String ANSI_RESET = "\u001B[0m"; + + public void run() { + System.out.print("Enter time in seconds: "); + + int passedSeconds; + try (Scanner scan = new Scanner(System.in)) { + String input = scan.nextLine().trim(); + passedSeconds = Integer.parseInt(input); + validateInput(passedSeconds); + } catch (NumberFormatException e) { + System.out.println("Only 1 non-negative integer is allowed as passed parameter"); + return; + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + return; + } + + int calculationSeconds = passedSeconds % 60; + String light; + if (calculationSeconds >= 0 && calculationSeconds < 35) { + light = ANSI_GREEN + "GREEN" + ANSI_RESET; + } else if ((calculationSeconds >= 35 && calculationSeconds < 40) || calculationSeconds >= 55) { + light = ANSI_YELLOW + "YELLOW" + ANSI_RESET; + } else { + light = ANSI_RED + "RED" + ANSI_RESET; + } + + System.out.println(light); + } + + private void validateInput(int passedSeconds) { + if (passedSeconds < 0) { + throw new IllegalArgumentException("Only 1 non-negative integer is allowed as passed parameter"); + } + if (passedSeconds >= 86400) { + throw new IllegalArgumentException("The day is over"); + } + } +} \ No newline at end of file diff --git a/src/main/java/homework_3/Cafe.java b/src/main/java/homework_3/Cafe.java new file mode 100644 index 00000000..e648f877 --- /dev/null +++ b/src/main/java/homework_3/Cafe.java @@ -0,0 +1,68 @@ +package homework_3; + +/** + * Immutable class has next characteristics:

+ * - it's final, to prevent breaking immutability through inheritance

+ * - it has private and final fields so client doesn't have direct access

+ * - it uses "defencive copying": doesn't work with reference type directly, + * but copies objects into own fields, and returns copies of it's own objects instead of direct references

+ * - it has no setter methods for fields

+ * - if there is need to change it's fields it returns a new object

+ * Immutable class is extremely well encapsulated! + */ + +public final class Cafe { + + private final StringBuilder name; + private final double averageCheck; + private final int seats; + + public Cafe(StringBuilder name, double check, int seats) { + this.name = new StringBuilder(name); + averageCheck = check; + this.seats = seats; + } + + public Cafe(double check, int seats) { + this.name = null; + averageCheck = check; + this.seats = seats; + } + + public StringBuilder getName() { + if (name != null) { + return new StringBuilder(name); + } + return new StringBuilder("Nameless cafe"); + } + + public double getAverageCheck() { + return averageCheck; + } + + public int getSeats() { + return seats; + } + + public Cafe changeNumOfSeats(int newSeats) { + return new Cafe(name, averageCheck, newSeats); + } + + public static void main(String[] args) { + StringBuilder name = new StringBuilder("Bushe"); + Cafe cafe = new Cafe(name, 1100.0, 40); + + StringBuilder cafeName = cafe.getName(); + System.out.println("Cafe's name: " + cafeName); + + name.append("2"); + System.out.println("Altered name var: " + name); + System.out.println("Cafe's name after alteration: " + cafe.getName()); + + cafeName.append("10"); + System.out.println("Cafe's name after alteration through received reference : " + cafe.getName()); + + Cafe modifiedCafe = cafe.changeNumOfSeats(45); + System.out.println("Does modified cafe is the same cafe? - " + (cafe == modifiedCafe)); + } +} diff --git a/src/main/java/homework_4/custom_annotation/DefaultUserInfo.java b/src/main/java/homework_4/custom_annotation/DefaultUserInfo.java new file mode 100644 index 00000000..8f388f0c --- /dev/null +++ b/src/main/java/homework_4/custom_annotation/DefaultUserInfo.java @@ -0,0 +1,15 @@ +package homework_4.custom_annotation; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target(TYPE) +public @interface DefaultUserInfo { + + String name(); + int id(); +} \ No newline at end of file diff --git a/src/main/java/homework_4/custom_annotation/Profile.java b/src/main/java/homework_4/custom_annotation/Profile.java new file mode 100644 index 00000000..f504eac2 --- /dev/null +++ b/src/main/java/homework_4/custom_annotation/Profile.java @@ -0,0 +1,26 @@ +package homework_4.custom_annotation; + +@DefaultUserInfo(name = "Nikita", id = 1) +public class Profile { + + private final String name; + private final int id; + + public Profile() { + name = Profile.class.getDeclaredAnnotation(DefaultUserInfo.class).name(); + id = Profile.class.getDeclaredAnnotation(DefaultUserInfo.class).id(); + } + + public Profile(String name, int id) { + this.name = name; + this.id = id; + } + + public String getName() { + return name; + } + + public int getId() { + return id; + } +} \ No newline at end of file diff --git a/src/main/java/homework_4/custom_file_reader/CustomFileReader.java b/src/main/java/homework_4/custom_file_reader/CustomFileReader.java new file mode 100644 index 00000000..c7a45dd1 --- /dev/null +++ b/src/main/java/homework_4/custom_file_reader/CustomFileReader.java @@ -0,0 +1,165 @@ +package homework_4.custom_file_reader; + +import java.io.*; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.file.*; +import java.util.Scanner; +import java.util.stream.Stream; + +public class CustomFileReader { + + private static final String FILE_NOT_FOUND_MESSAGE = "File not found"; + private static final String PATH_TO_FILE = "src/main/resources/custom_file_reader/"; + + private final String sourceFile; + + public CustomFileReader() { + String defaultFileName = "file.txt"; + sourceFile = PATH_TO_FILE + defaultFileName; + } + + public CustomFileReader(String fileName) { + sourceFile = PATH_TO_FILE + fileName; + } + + public void run1() { + readByByte(); + } + + public void run2() { + readBytesInBuffer(); + } + + public void run3() { + readCharsInBuffer(); + } + + public void run4() { + readCharsFromCharacterStream(); + } + + public void run5() { + readWithScanner(); + } + + public void run6() { + readWithNIO(); + } + + public void run7() { + readWithNIO2(); + } + + private void readByByte() { + try (FileInputStream inputStream = new FileInputStream(sourceFile)) { + int charsAvailable = inputStream.available(); + StringBuilder readText = new StringBuilder(); + while (charsAvailable > 0) { + char next = (char) inputStream.read(); + if ((next != '.') && (next != ',')) { + readText.append(next); + } + charsAvailable--; + } + System.out.println(readText); + } catch (FileNotFoundException exc) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readBytesInBuffer() { + try (BufferedInputStream bufferedInputStream = new BufferedInputStream( + new FileInputStream(sourceFile))) { + int charsAvailable = bufferedInputStream.available(); + byte[] input = new byte[charsAvailable]; + int byteRead = bufferedInputStream.read(input); + if (byteRead != -1) { + String readText = new String(input); + readText = removePunctuation(readText); + System.out.println(readText); + } + } catch (FileNotFoundException exc) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readCharsInBuffer() { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader( + new FileInputStream(sourceFile)))) { + String readText = reader.readLine(); + while (readText != null) { + readText = removePunctuation(readText); + System.out.println(readText); + readText = reader.readLine(); + } + } catch (FileNotFoundException exc) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readCharsFromCharacterStream() { + try (BufferedReader reader = new BufferedReader(new FileReader(sourceFile))) { + String readText = reader.readLine(); + while (readText != null) { + readText = removePunctuation(readText); + System.out.println(readText); + readText = reader.readLine(); + } + } catch (FileNotFoundException exc) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readWithScanner() { + try (Scanner scanner = new Scanner(new File(sourceFile))) { + while (scanner.hasNext()) { + String readText = scanner.nextLine(); + readText = removePunctuation(readText); + System.out.println(readText); + } + } catch (FileNotFoundException e) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } + } + + private void readWithNIO() { + try (FileChannel fileChannel = new FileInputStream(sourceFile).getChannel()) { + int availableBytes = (int) fileChannel.size(); + ByteBuffer buffer = ByteBuffer.allocate(availableBytes); + fileChannel.read(buffer); + String readText = new String(buffer.array()); + readText = removePunctuation(readText); + System.out.println(readText); + } catch (FileNotFoundException exc) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void readWithNIO2() { + Path path = Paths.get(sourceFile); + try (Stream lines = Files.lines(path)) { + lines.map(n -> n = n.replaceAll("[,.]", "")) + .forEach(System.out::println); + } catch (NoSuchFileException exc) { + System.out.println(FILE_NOT_FOUND_MESSAGE); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private String removePunctuation(String text) { + return text.replaceAll("[.,]", ""); + } +} diff --git a/src/main/java/homework_4/custom_file_reader/Main.java b/src/main/java/homework_4/custom_file_reader/Main.java new file mode 100644 index 00000000..ff3ecf81 --- /dev/null +++ b/src/main/java/homework_4/custom_file_reader/Main.java @@ -0,0 +1,8 @@ +package homework_4.custom_file_reader; + +public class Main { + + public static void main(String[] args) { + new CustomFileReader().run1(); + } +} diff --git a/src/main/java/homework_4/singleton/Theater.java b/src/main/java/homework_4/singleton/Theater.java new file mode 100644 index 00000000..4407e7cf --- /dev/null +++ b/src/main/java/homework_4/singleton/Theater.java @@ -0,0 +1,31 @@ +package homework_4.singleton; + +public class Theater { + + private static Theater instance; + private final boolean[][] seats; + + private Theater() { + seats = new boolean[21][11]; + } + + public static Theater getInstance() { + if (instance == null) { + instance = new Theater(); + } + return instance; + } + + public boolean bookSeat(int row, int seat) { + if ((row < 1) || (row > 20) || (seat < 1) || (seat > 10)) { + System.out.println("Invalid seat value"); + return false; + } + if (!seats[row][seat]) { + seats[row][seat] = true; + return true; + } else { + return false; + } + } +} diff --git a/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java b/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java new file mode 100644 index 00000000..06c4f00b --- /dev/null +++ b/src/main/java/homework_5/custom_regex_matcher/CustomRegexMatcher.java @@ -0,0 +1,36 @@ +package homework_5.custom_regex_matcher; + +import java.util.Scanner; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class CustomRegexMatcher { + + private static final String BYTE_VALUE = "((25[0-5])|(2[0-4][0-9])|([0-1][0-9][0-9])|([0-9][0-9])|([0-9]))"; // leading zeros allowed + private static final String IP_REGEX = BYTE_VALUE + + "\\." + BYTE_VALUE + + "\\." + BYTE_VALUE + + "\\." + BYTE_VALUE; + + public void run() { + System.out.print("Enter ip-address for validation: "); + String input = getInput(); + validateInput(input); + } + + private String getInput() { + Scanner scanner = new Scanner(System.in); + String input = ""; + if (scanner.hasNext()) { + input = scanner.nextLine(); + } + scanner.close(); + return input; + } + + private void validateInput(String input) { + Pattern pattern = Pattern.compile(IP_REGEX); + Matcher matcher = pattern.matcher(input); + System.out.println(matcher.matches()); + } +} diff --git a/src/main/java/homework_5/custom_regex_matcher/Main.java b/src/main/java/homework_5/custom_regex_matcher/Main.java new file mode 100644 index 00000000..e1e20462 --- /dev/null +++ b/src/main/java/homework_5/custom_regex_matcher/Main.java @@ -0,0 +1,8 @@ +package homework_5.custom_regex_matcher; + +public class Main { + + public static void main(String[] args) { + new CustomRegexMatcher().run(); + } +} diff --git a/src/main/java/homework_5/power_of_number/Main.java b/src/main/java/homework_5/power_of_number/Main.java new file mode 100644 index 00000000..89300565 --- /dev/null +++ b/src/main/java/homework_5/power_of_number/Main.java @@ -0,0 +1,8 @@ +package homework_5.power_of_number; + +public class Main { + + public static void main(String[] args) { + new PowerOfNumber().run(); + } +} diff --git a/src/main/java/homework_5/power_of_number/PowerOfNumber.java b/src/main/java/homework_5/power_of_number/PowerOfNumber.java new file mode 100644 index 00000000..2010bb2b --- /dev/null +++ b/src/main/java/homework_5/power_of_number/PowerOfNumber.java @@ -0,0 +1,57 @@ +package homework_5.power_of_number; + +import java.util.Scanner; + +public class PowerOfNumber { + + private int number; + private int power; + private boolean validInput = true; + + public void run() { + System.out.print("Enter number and power: "); + getInput(); + if (validInput) { + System.out.println(power(number, power)); + } + } + + private void getInput() { + try (Scanner scanner = new Scanner(System.in)) { + String tail = parseInput(scanner); + validateInput(tail); + } catch (RuntimeException e) { + System.out.println("Only 2 non-negative integers are allowed"); + validInput = false; + } + } + + private String parseInput(Scanner scanner) { + number = scanner.nextInt(); + power = scanner.nextInt(); + if (scanner.hasNextLine()) { + return scanner.nextLine().trim(); + } else { + return ""; + } + } + + private void validateInput(String tail) { + if (number < 0) { + throw new IllegalArgumentException(); + } + if (power < 0) { + throw new IllegalArgumentException(); + } + if (!tail.equals("")) { + throw new IllegalArgumentException(); + } + } + + private int power(int num, int pow) { + if (pow == 0) { + return 1; + } + return num * power(num, pow - 1); + } +} diff --git a/src/main/java/homework_6/MapProblemsGenerator.java b/src/main/java/homework_6/MapProblemsGenerator.java new file mode 100644 index 00000000..0259d25b --- /dev/null +++ b/src/main/java/homework_6/MapProblemsGenerator.java @@ -0,0 +1,69 @@ +package homework_6; + +public class MapProblemsGenerator { + + public static class MapCollisionKey { + + private final String name; + private int equalsCalls; // If there is a collision, we have to call equals to resolve it + + public MapCollisionKey(String name) { + this.name = name; + } + + public int getEqualsCalls() { + return equalsCalls; + } + + @Override + public boolean equals(Object obj) { + equalsCalls++; + if (this == obj) { + return true; + } + if ((obj == null) || (obj.getClass() != this.getClass())) { + return false; + } + MapCollisionKey col = (MapCollisionKey) obj; + + return name.equals(col.name); + } + + @Override + public int hashCode() { + return 7; + } + } + + public static class MutableKey { + + private final StringBuilder name; + + public MutableKey(String name) { + this.name = new StringBuilder(name); + } + + public StringBuilder getName() { + return name; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if ((obj == null) || (obj.getClass() != this.getClass())) { + return false; + } + MutableKey mKey = (MutableKey) obj; + + return name.toString().equals(mKey.name.toString()); + } + + @Override + public int hashCode() { + return name.toString().hashCode(); + } + } + +} diff --git a/src/main/java/homework_7/KittenToCatFunction.java b/src/main/java/homework_7/KittenToCatFunction.java new file mode 100644 index 00000000..14173419 --- /dev/null +++ b/src/main/java/homework_7/KittenToCatFunction.java @@ -0,0 +1,10 @@ +package homework_7; + +import homework_7.util.Cat; +import homework_7.util.Kitten; + +@FunctionalInterface +public interface KittenToCatFunction { + + R grow(T obj); +} diff --git a/src/main/java/homework_7/Main.java b/src/main/java/homework_7/Main.java new file mode 100644 index 00000000..f583c49e --- /dev/null +++ b/src/main/java/homework_7/Main.java @@ -0,0 +1,23 @@ +package homework_7; + +import homework_7.util.Cat; +import homework_7.util.Kitten; + +import java.util.Random; + +public class Main { + + public static void main(String[] args) { + Kitten kitty = new Kitten(1, "Playful", "White"); + System.out.println("kitty = " + kitty); + + KittenToCatFunction transform = obj -> new Cat(obj.getAge() + 2, new Random().nextInt(10) + 1, obj.getColor()); + + Cat cat = timeToGetOlder(transform, kitty); + System.out.println("cat = " + cat); + } + + public static Cat timeToGetOlder(KittenToCatFunction transform, Kitten kitten) { + return transform.grow(kitten); + } +} diff --git a/src/main/java/homework_7/util/Cat.java b/src/main/java/homework_7/util/Cat.java new file mode 100644 index 00000000..20ec7560 --- /dev/null +++ b/src/main/java/homework_7/util/Cat.java @@ -0,0 +1,35 @@ +package homework_7.util; + +public class Cat { + + private int age; + private final int activityLevel; + private final String color; + + public Cat(int age, int activityLevel, String color) { + this.age = age; + this.activityLevel = activityLevel; + this.color = color; + } + + public int getAge() { + return age; + } + + public int getActivityLevel() { + return activityLevel; + } + + public String getColor() { + return color; + } + + @Override + public String toString() { + return "Cat{" + + "age=" + age + + ", activityLevel=" + activityLevel + + ", color='" + color + '\'' + + '}'; + } +} diff --git a/src/main/java/homework_7/util/Kitten.java b/src/main/java/homework_7/util/Kitten.java new file mode 100644 index 00000000..4a3f3e83 --- /dev/null +++ b/src/main/java/homework_7/util/Kitten.java @@ -0,0 +1,35 @@ +package homework_7.util; + +public class Kitten { + + private int age; + private final String mood; + private final String color; + + public Kitten(int age, String mood, String color) { + this.age = age; + this.mood = mood; + this.color = color; + } + + public int getAge() { + return age; + } + + public String getMood() { + return mood; + } + + public String getColor() { + return color; + } + + @Override + public String toString() { + return "Kitten{" + + "age=" + age + + ", mood='" + mood + '\'' + + ", color='" + color + '\'' + + '}'; + } +} 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..0165ac4b --- /dev/null +++ b/src/main/resources/custom_file_reader/file.txt @@ -0,0 +1,2 @@ +Hello there! I'm a test string. +Use me for demonstration, please. \ No newline at end of file diff --git a/src/test/java/course_project/ComponentsTest.java b/src/test/java/course_project/ComponentsTest.java new file mode 100644 index 00000000..680a4379 --- /dev/null +++ b/src/test/java/course_project/ComponentsTest.java @@ -0,0 +1,80 @@ +package course_project; + +import course_project.components.Coordinate; +import course_project.components.PlayingField; +import course_project.components.Ship; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class ComponentsTest { + + @Test + void testCoordinate() { + Coordinate cell1 = new Coordinate(0, 1); + Coordinate cell2 = new Coordinate(0, 1); + + assertEquals(0, cell1.getX()); + assertEquals(1, cell1.getY()); + assertEquals(cell1, cell2); + assertEquals(cell1.hashCode(), cell2.hashCode()); + assertEquals("B1", cell1.toString()); + } + + @Test + void testShip() { + ArrayList shipCoordinates = new ArrayList<>(); + shipCoordinates.add(new Coordinate(0, 0)); + shipCoordinates.add(new Coordinate(0, 1)); + + Ship ship = new Ship(shipCoordinates.size(), shipCoordinates); + + assertEquals(shipCoordinates, ship.getCoordinates()); + assertEquals(shipCoordinates.size(), ship.getSize()); + + assertFalse(ship.isSunk()); + ship.gotShot(); + ship.gotShot(); + assertTrue(ship.isSunk()); + } + + @Test + void testPlayingField() { + int[][] fleet = new int[10][10]; + boolean[][] cellsShot = new boolean[10][10]; + HashMap coordinateToShip = new HashMap<>(32); + ArrayList playersShips = new ArrayList<>(); + + PlayingField field = new PlayingField(); + + List list = Arrays.asList(new Coordinate(0, 0), new Coordinate(0, 1)); + Ship ship = new Ship(list.size(), list); + + field.placeShip(ship); + assertEquals(1, field.getPlayersShips().size()); + assertEquals(2, field.getCoordinateMapping().size()); + + fleet[0][0] = 2; + fleet[0][1] = 2; + assertArrayEquals(fleet, field.getFleet()); + + assertTrue(field.placeShot(new Coordinate(0, 0))); + assertFalse(field.placeShot(new Coordinate(0, 0))); + + assertTrue(field.placeShot(new Coordinate(0, 1))); + assertEquals(0, field.getPlayersShips().size()); + + assertTrue(field.isCellShot(new Coordinate(0, 0))); + cellsShot[0][0] = true; + cellsShot[0][1] = true; + cellsShot[0][2] = true; + cellsShot[1][0] = true; + cellsShot[1][1] = true; + assertArrayEquals(cellsShot, field.getCellsShot()); + } +} diff --git a/src/test/java/course_project/SeaBattleTest.java b/src/test/java/course_project/SeaBattleTest.java new file mode 100644 index 00000000..35c235bf --- /dev/null +++ b/src/test/java/course_project/SeaBattleTest.java @@ -0,0 +1,107 @@ +package course_project; + +import base.UnitBase; +import course_project.components.Coordinate; +import course_project.components.PlayingField; +import course_project.components.Ship; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class SeaBattleTest extends UnitBase { + + @Test + void testPlacing() { + String input = "H1 hor\n" + + "A1 hor\n" + + "A2 hor\n" + + "A3 hor\n" + + "A5 hor\n" + + "A7 hor\n" + + "A9 hor\n" + + "D9 ver\n" + + "J1 ver\n" + + "J3 ver\n" + + "J5 ver\n" + + "Z5 ver\n" + + "J7 ver"; + setInput(input); + + SeaBattle seaBattle = new SeaBattle(); + + seaBattle.placePlayersShips(); + int numOfPlayersShips = seaBattle.playersField.getPlayersShips().size(); + + assertEquals(10, numOfPlayersShips); + + seaBattle.placeComputerShips(); + int numOfComputerShips = seaBattle.enemyField.getPlayersShips().size(); + + assertEquals(10, numOfComputerShips); + } + + @Test + void testMoves() { + String input = "A10\n" + + "A1"; + setInput(input); + + List coordinates = new ArrayList<>(); + + coordinates.add(new Coordinate(0, 0)); + Ship ship1 = new Ship(1, coordinates); + + coordinates.add(new Coordinate(0, 1)); + Ship ship2 = new Ship(1, coordinates); + + SeaBattle seaBattle = new SeaBattle(); + addShipToField(coordinates, ship1, seaBattle.enemyField); + addShipToField(coordinates, ship2, seaBattle.playersField); + + int numOfPlayerShips = seaBattle.playersField.getPlayersShips().size(); + int numOfComputerShips = seaBattle.enemyField.getPlayersShips().size(); + + assertEquals(1, numOfPlayerShips); + assertEquals(1, numOfComputerShips); + + seaBattle.makeMoves(); + + numOfPlayerShips = seaBattle.playersField.getPlayersShips().size(); + numOfComputerShips = seaBattle.enemyField.getPlayersShips().size(); + + assertEquals(1, numOfPlayerShips); + assertEquals(0, numOfComputerShips); + } + + private void addShipToField(List coordinates, Ship ship1, PlayingField field) { + field.getPlayersShips().add(ship1); + Map map = field.getCoordinateMapping(); + map.put(coordinates.get(0), ship1); + } + + @Test + void testDefineWinner() { + SeaBattle seaBattle = new SeaBattle(); + Ship ship = new Ship(1, Arrays.asList(new Coordinate(0, 0))); + List playersShips = seaBattle.playersField.getPlayersShips(); + playersShips.add(ship); + + seaBattle.defineWinner(); + + assertEquals("Player won!", getOutput()); + + removeFromOutput("Player won!"); + playersShips.remove(0); + + seaBattle.enemyField.getPlayersShips().add(ship); + + seaBattle.defineWinner(); + + assertEquals("Computer won!", getOutput()); + } +} diff --git a/src/test/java/course_project/UtilTest.java b/src/test/java/course_project/UtilTest.java new file mode 100644 index 00000000..6a6eb0a4 --- /dev/null +++ b/src/test/java/course_project/UtilTest.java @@ -0,0 +1,118 @@ +package course_project; + +import base.UnitBase; +import course_project.components.Coordinate; +import course_project.components.PlayingField; +import course_project.components.Ship; +import course_project.util.PlayingFieldPrinter; +import course_project.util.ship_placer.ComputerShipPlacer; +import course_project.util.ship_placer.ShipPlacer; +import course_project.util.ship_placer.UserShipPlacer; +import course_project.util.user_input_reader.UserShotInputReader; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class UtilTest extends UnitBase { + + @Test + void testPlacingFieldPrinter() { + PlayingField field = new PlayingField(); + Ship ship1 = new Ship(1, Arrays.asList(new Coordinate(0, 0))); + Ship ship2 = new Ship(2, Arrays.asList(new Coordinate(0, 2), new Coordinate(0, 3))); + + field.placeShip(ship1); + field.placeShip(ship2); + field.placeShot(new Coordinate(0, 0)); + + String printedField = "\tA B C D E F G H I J \r\n" + // testing on Windows, so \r\n + "1\tX * 2 2 - - - - - - \r\n" + + "2\t* - - - - - - - - - \r\n" + + "3\t- - - - - - - - - - \r\n" + + "4\t- - - - - - - - - - \r\n" + + "5\t- - - - - - - - - - \r\n" + + "6\t- - - - - - - - - - \r\n" + + "7\t- - - - - - - - - - \r\n" + + "8\t- - - - - - - - - - \r\n" + + "9\t- - - - - - - - - - \r\n" + + "10\t- - - - - - - - - -"; + + PlayingFieldPrinter printer = new PlayingFieldPrinter(); + printer.printField(field); + + assertTrue(getOutput().contains(printedField)); + + printer.printShotCells(field); + + String printedShots = "\tA B C D E F G H I J \r\n" + + "1\tX * - - - - - - - - \r\n" + + "2\t* - - - - - - - - - \r\n" + + "3\t- - - - - - - - - - \r\n" + + "4\t- - - - - - - - - - \r\n" + + "5\t- - - - - - - - - - \r\n" + + "6\t- - - - - - - - - - \r\n" + + "7\t- - - - - - - - - - \r\n" + + "8\t- - - - - - - - - - \r\n" + + "9\t- - - - - - - - - - \r\n" + + "10\t- - - - - - - - - -"; + + assertTrue(getOutput().contains(printedShots)); + } + + @Test + void testUserShipPlacer() { + String input = "H1 hor\n" + + "A1 hor\n" + + "A2 hor\n" + + "A3 hor\n" + + "A5 hor\n" + + "A7 hor\n" + + "A9 hor\n" + + "D9 ver\n" + + "J1 ver\n" + + "J3 ver\n" + + "J5 ver\n" + + "Z5 ver\n" + + "J7 ver"; + setInput(input); + + PlayingField field = new PlayingField(); + ShipPlacer placer = new UserShipPlacer(new Scanner(System.in)); + + placer.placeShips(field); + + int actualSize = field.getPlayersShips().size(); + + assertEquals(10, actualSize); + } + + @Test + void testComputerShipPlacer() { + PlayingField field = new PlayingField(); + ShipPlacer placer = new ComputerShipPlacer(); + + placer.placeShips(field); + + int actualSize = field.getPlayersShips().size(); + + assertEquals(10, actualSize); + } + + @Test + void testUserShotInputReader() { + String input = "A11\n" + + "A10"; + setInput(input); + + Coordinate expected = new Coordinate(9, 0); + + UserShotInputReader reader = new UserShotInputReader(new Scanner(System.in)); + Coordinate pointFromReader = reader.getPointFromInput(); + + assertEquals(expected, pointFromReader); + } +} diff --git a/src/test/java/homework_2_test/pyramid_printer/PyramidPrinterTest.java b/src/test/java/homework_2_test/pyramid_printer/PyramidPrinterTest.java new file mode 100644 index 00000000..e4b7921c --- /dev/null +++ b/src/test/java/homework_2_test/pyramid_printer/PyramidPrinterTest.java @@ -0,0 +1,110 @@ +package homework_2_test.pyramid_printer; + +import base.UnitBase; +import homework_2.pyramid_printer.PyramidPrinter; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; + + +public class PyramidPrinterTest extends UnitBase { + + private final String errorMsg = "Only 1 non-negative integer is allowed as passed parameter"; + + @Test + void givenThree_whenRun_thenPrintPyramid() { + setInput("3"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + StringBuilder out = new StringBuilder("x"); + for (int i = 0; i < 3; i++) { + assertEquals(out.toString(), getOutputLines()[i]); + out.append("x"); + } + } + + @Test + void givenThreeAndSpaces_whenRun_thenPrintPyramid() { + setInput(" 3 "); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + StringBuilder out = new StringBuilder("x"); + for (int i = 0; i < 3; i++) { + assertEquals(out.toString(), getOutputLines()[i]); + out.append("x"); + } + } + + @Test + void givenZero_whenRun_thenEmptyOutput() { + setInput("0"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals("", getOutput()); + } + + @Test + void givenNegativeNumber_whenRun_thenErrorMessage() { + setInput("-1"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoNumbers_whenRun_thenErrorMessage() { + setInput("2 2"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenWord_whenRun_thenErrorMessage() { + setInput("three"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenValidNumberAndWord_whenRun_thenErrorMessage() { + setInput("3 three"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenFloatingPoint_whenRun_thenErrorMessage() { + setInput("3.0"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenNonAlphabetic_whenRun_thenErrorMessage() { + setInput("$"); + new PyramidPrinter().run(); + + removeFromOutput("Enter pyramid height: "); + + assertEquals(errorMsg, getOutput()); + } +} \ No newline at end of file diff --git a/src/test/java/homework_2_test/random_chars_table/RandomCharsTableTest.java b/src/test/java/homework_2_test/random_chars_table/RandomCharsTableTest.java new file mode 100644 index 00000000..45cd5616 --- /dev/null +++ b/src/test/java/homework_2_test/random_chars_table/RandomCharsTableTest.java @@ -0,0 +1,200 @@ +package homework_2_test.random_chars_table; + +import base.UnitBase; + +import homework_2.random_chars_table.RandomCharsTable; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class RandomCharsTableTest extends UnitBase { + + private final String errorMsg = "Passed parameters should match the format " + + "[positive integer] [positive integer] [even|odd]"; + + @Test + void givenTwoTwoOdd_whenRun_thenPrintTableAndLetters() { + setInput("2 2 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + for (int i = 0; i < 2; i++) { + String[] letters = getOutputLines()[i].split("\\|"); + for (int j = 1; j < 3; j++) { + char ch = letters[j].trim().charAt(0); + assertTrue(ch >= 65 && ch <= 90); + } + } + + String lineOfLetters = getOutputLines()[2]; + lineOfLetters = lineOfLetters.replace("odd letters - ", ""); + String[] oddLetters = lineOfLetters.split(", "); + for (String oddLetter : oddLetters) { + char ch = oddLetter.charAt(0); + assertTrue(ch >= 65 && ch <= 90); + assertEquals(1, ch % 2); + } + } + + @Test + void givenTwoTwoEven_whenRun_thenPrintTableAndLetters() { + setInput("2 2 even"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + for (int i = 0; i < 2; i++) { + String[] letters = getOutputLines()[i].split("\\|"); + for (int j = 1; j < 3; j++) { + char ch = letters[j].trim().charAt(0); + assertTrue(ch >= 65 && ch <= 90); + } + } + + String lineOfLetters = getOutputLines()[2]; + lineOfLetters = lineOfLetters.replace("even letters - ", ""); + String[] evenLetters = lineOfLetters.split(", "); + for (String evenLetter : evenLetters) { + char ch = evenLetter.charAt(0); + assertTrue(ch >= 65 && ch <= 90); + assertEquals(0, ch % 2); + } + } + + @Test + void givenValidInputWithExtraSpaces_whenRun_thenPrintTableAndLetters() { + setInput(" 2 2 even "); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + for (int i = 0; i < 2; i++) { + String[] letters = getOutputLines()[i].split("\\|"); + for (int j = 1; j < 3; j++) { + char ch = letters[j].trim().charAt(0); + assertTrue(ch >= 65 && ch <= 90); + } + } + + String lineOfLetters = getOutputLines()[2]; + lineOfLetters = lineOfLetters.replace("even letters - ", ""); + String[] evenLetters = lineOfLetters.split(", "); + for (String evenLetter : evenLetters) { + char ch = evenLetter.charAt(0); + assertTrue(ch >= 65 && ch <= 90); + assertEquals(0, ch % 2); + } + } + + @Test + void givenZeroTwoOdd_whenRun_thenErrorMessage() { + setInput("0 2 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoZeroOdd_whenRun_thenErrorMessage() { + setInput("2 0 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenMinusOneTwoOdd_whenRun_thenErrorMessage() { + setInput("-1 2 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoMinusOneOdd_whenRun_thenErrorMessage() { + setInput("2 -1 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenThreeInts_whenRun_thenErrorMessage() { + setInput("2 2 2"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoTwoInvalidWord_whenRun_thenErrorMessage() { + setInput("2 2 cat"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenFloatingPointTwoOdd_whenRun_thenErrorMessage() { + setInput("2.0 2 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoOdd_whenRun_thenErrorMessage() { + setInput("2 odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenNoIntsOdd_whenRun_thenErrorMessage() { + setInput("odd"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoTwoNoWord_whenRun_thenErrorMessage() { + setInput("2 2"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoTwoOddExtraWord_whenRun_thenErrorMessage() { + setInput("2 2 odd cat"); + new RandomCharsTable().run(); + + removeFromOutput("Enter length, width of the table and choose even or odd letters: "); + + assertEquals(errorMsg, getOutput()); + } +} \ No newline at end of file diff --git a/src/test/java/homework_2_test/traffic_light/ExtraModeTrafficLightTest.java b/src/test/java/homework_2_test/traffic_light/ExtraModeTrafficLightTest.java new file mode 100644 index 00000000..67ebe535 --- /dev/null +++ b/src/test/java/homework_2_test/traffic_light/ExtraModeTrafficLightTest.java @@ -0,0 +1,179 @@ +package homework_2_test.traffic_light; + +import base.UnitBase; +import homework_2.traffic_light.ExtraModeTrafficLight; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ExtraModeTrafficLightTest extends UnitBase { + + private final String errorMsg = "Not a valid hh:mm:ss format"; + + @Test + void given0_whenRun_thenGreenLight() { + setInput("00:00:00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[32mGREEN\u001B[0m"; // getOutput() trims the first \u001B if it's at the beginning? + assertEquals(expected, getOutput()); + } + + @Test + void given5_whenRun_thenGreenLight() { + setInput("00:00:05"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[32mGREEN\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given35_whenRun_thenYellowLight() { + setInput("00:00:35"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[33mYELLOW\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given54_whenRun_thenRedLight() { + setInput("00:00:54"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[31mRED\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given121255_whenRun_thenYellowLight() { + setInput("12:12:55"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[33mYELLOW\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given5WithExtraSpaces_whenRun_thenGreenLight() { + setInput(" 00:00:05 "); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[32mGREEN\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void givenSecondsFieldOmitted_whenRun_thenGreenLight() { + setInput("12:55"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + String expected = "[32mGREEN\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void givenBiggerThenDay_whenRun_thenErrorMessage() { + setInput("24:00:00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenMinusOneDigitHours_whenRun_thenErrorMessage() { + setInput("0:00:00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenOneDigitMinutes_whenRun_thenErrorMessage() { + setInput("00:0:00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenOneDigitSeconds_whenRun_thenErrorMessage() { + setInput("00:00:0"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenNegativeFormat_whenRun_thenErrorMessage() { + setInput("-00:00:00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenColonOmitted_whenRun_thenErrorMessage() { + setInput("000000"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenColonReplacedWithSpaces_whenRun_thenErrorMessage() { + setInput("00 00 00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoTimeFieldsOmitted_whenRun_thenErrorMessage() { + setInput("00"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenWord_whenRun_thenErrorMessage() { + setInput("cat"); + new ExtraModeTrafficLight().run(); + + removeFromOutput("Enter time of the day in hh:mm:ss(hh:mm) format: "); + + assertEquals(errorMsg, getOutput()); + } +} \ No newline at end of file diff --git a/src/test/java/homework_2_test/traffic_light/TrafficLightTest.java b/src/test/java/homework_2_test/traffic_light/TrafficLightTest.java new file mode 100644 index 00000000..478be444 --- /dev/null +++ b/src/test/java/homework_2_test/traffic_light/TrafficLightTest.java @@ -0,0 +1,129 @@ +package homework_2_test.traffic_light; + +import base.UnitBase; +import homework_2.traffic_light.TrafficLight; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class TrafficLightTest extends UnitBase { + + private final String errorMsg = "Only 1 non-negative integer is allowed as passed parameter"; + + @Test + void given0_whenRun_thenGreenLight() { + setInput("0"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "[32mGREEN\u001B[0m"; // getOutput() trims the first \u001B if it's at the beginning? + assertEquals(expected, getOutput()); + } + + @Test + void given5_whenRun_thenGreenLight() { + setInput("5"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "[32mGREEN\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given35_whenRun_thenYellowLight() { + setInput("35"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "[33mYELLOW\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given54_whenRun_thenRedLight() { + setInput("54"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "[31mRED\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given3345_whenRun_thenRedLight() { + setInput("3345"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "[31mRED\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given54WithExtraSpaces_whenRun_thenRedLight() { + setInput(" 54 "); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "[31mRED\u001B[0m"; + assertEquals(expected, getOutput()); + } + + @Test + void given86400_whenRun_thenTheDayIsOver() { + setInput("86400"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + String expected = "The day is over"; + assertEquals(expected, getOutput()); + } + + @Test + void givenMinus1_whenRun_thenErrorMessage() { + setInput("-1"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenFloatingPoint_whenRun_thenErrorMessage() { + setInput("5.0"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenTwoInts_whenRun_thenErrorMessage() { + setInput("5 5"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + assertEquals(errorMsg, getOutput()); + } + + @Test + void givenWord_whenRun_thenErrorMessage() { + setInput("cat"); + new TrafficLight().run(); + + removeFromOutput("Enter time in seconds: "); + + assertEquals(errorMsg, getOutput()); + } +} \ No newline at end of file diff --git a/src/test/java/homework_4_test/custom_annotation/AnnotationTest.java b/src/test/java/homework_4_test/custom_annotation/AnnotationTest.java new file mode 100644 index 00000000..b936e34c --- /dev/null +++ b/src/test/java/homework_4_test/custom_annotation/AnnotationTest.java @@ -0,0 +1,38 @@ +package homework_4_test.custom_annotation; + +import homework_4.custom_annotation.DefaultUserInfo; +import homework_4.custom_annotation.Profile; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class AnnotationTest { + + @Test + void givenConstructorParameters_whenClassConstructor_thenParametersAssigned() { + String expectedName = "Obama"; + int expectedId = 44; + + Profile profile = new Profile("Obama", 44); + + assertEquals(expectedName, profile.getName()); + assertEquals(expectedId, profile.getId()); + } + + @Test + void givenCheckAnnotation_whenGetDeclaredAnnotation_thenNotNull() { + assertNotNull(Profile.class.getDeclaredAnnotation(DefaultUserInfo.class)); + } + + @Test + void givenNoConstructorParameters_whenClassConstructor_thenDefaultParametersAssigned() { + String expectedName = "Nikita"; + int expectedId = 1; + + Profile profile = new Profile(); + + assertEquals(expectedName, profile.getName()); + assertEquals(expectedId, profile.getId()); + } +} \ No newline at end of file diff --git a/src/test/java/homework_4_test/custom_file_reader/CustomFileReaderTest.java b/src/test/java/homework_4_test/custom_file_reader/CustomFileReaderTest.java new file mode 100644 index 00000000..fb141a80 --- /dev/null +++ b/src/test/java/homework_4_test/custom_file_reader/CustomFileReaderTest.java @@ -0,0 +1,89 @@ +package homework_4_test.custom_file_reader; + +import base.UnitBase; +import homework_4.custom_file_reader.CustomFileReader; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class CustomFileReaderTest extends UnitBase { + + @Test + void givenDefaultFile_whenRun_thenModifiedTextIsOutputted() { + String expected = "Hello there! I'm a test string\r\n" + + "Use me for demonstration please"; + + new CustomFileReader().run1(); + String actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader().run2(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader().run3(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader().run4(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader().run5(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader().run6(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader().run7(); + actual = getOutput(); + assertEquals(expected, actual); + } + + @Test + void givenNoFile_whenRun_thenNotFoundMessage() { + String expected = "File not found"; + + new CustomFileReader("nonExistentFile.txt").run1(); + String actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader("nonExistentFile.txt").run2(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader("nonExistentFile.txt").run3(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader("nonExistentFile.txt").run4(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader("nonExistentFile.txt").run5(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader("nonExistentFile.txt").run6(); + actual = getOutput(); + assertEquals(expected, actual); + removeFromOutput(actual); + + new CustomFileReader("nonExistentFile.txt").run7(); + actual = getOutput(); + assertEquals(expected, actual); + } +} diff --git a/src/test/java/homework_4_test/singleton/TheaterTest.java b/src/test/java/homework_4_test/singleton/TheaterTest.java new file mode 100644 index 00000000..d767a565 --- /dev/null +++ b/src/test/java/homework_4_test/singleton/TheaterTest.java @@ -0,0 +1,35 @@ +package homework_4_test.singleton; + +import homework_4.singleton.Theater; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +public class TheaterTest { + + @Test + void givenInstance_whenBookSeat_thenTrue() { + Theater theater = Theater.getInstance(); + assertTrue(theater.bookSeat(1, 1)); + } + + @Test + void givenSecondInstance_whenBookSeat_thenFalse() { + Theater theater = Theater.getInstance(); + Theater theater2 = Theater.getInstance(); + + theater.bookSeat(1, 1); + + assertFalse(theater2.bookSeat(1, 1)); + } + + @Test + void givenIllegalSeatValue_whenBookSeat_thenFalse() { + Theater theater = Theater.getInstance(); + + assertFalse(theater.bookSeat(0, 0)); + assertFalse(theater.bookSeat(-1, -1)); + assertFalse(theater.bookSeat(21, 11)); + } +} diff --git a/src/test/java/homework_5_test/custom_regex_matcher/CustomRegexMatcherTest.java b/src/test/java/homework_5_test/custom_regex_matcher/CustomRegexMatcherTest.java new file mode 100644 index 00000000..f4e9d1dc --- /dev/null +++ b/src/test/java/homework_5_test/custom_regex_matcher/CustomRegexMatcherTest.java @@ -0,0 +1,58 @@ +package homework_5_test.custom_regex_matcher; + +import base.UnitBase; +import homework_5.custom_regex_matcher.CustomRegexMatcher; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class CustomRegexMatcherTest extends UnitBase { + + @ParameterizedTest + @MethodSource("goodCases") + void testGoodCases(String expected, String input) { + setInput(input); + + new CustomRegexMatcher().run(); + removeFromOutput("Enter ip-address for validation: "); + + assertEquals(expected, getOutput()); + } + + @ParameterizedTest + @MethodSource("badCases") + void testBadCases(String expected, String input) { + setInput(input); + + new CustomRegexMatcher().run(); + removeFromOutput("Enter ip-address for validation: "); + + assertEquals(expected, getOutput()); + } + + static Stream goodCases() { + return Stream.of( + Arguments.of("true", "000.12.12.034"), + Arguments.of("true", "121.234.12.12"), + Arguments.of("true", "23.45.12.56"), + Arguments.of("true", "255.2.001.47"), + Arguments.of("true", "192.168.1.1") + ); + } + + static Stream badCases() { + return Stream.of( + Arguments.of("false", "000.12.234.23.23"), + Arguments.of("false", "666.666.23.23"), + Arguments.of("false", ".213.123.23.32"), + Arguments.of("false", "23.45.22.32."), + Arguments.of("false", "I.Am.not.an.ip"), + Arguments.of("false", "122.23"), + Arguments.of("false", "Hello.IP") + ); + } +} diff --git a/src/test/java/homework_5_test/power_of_number/PowerOfNumberTest.java b/src/test/java/homework_5_test/power_of_number/PowerOfNumberTest.java new file mode 100644 index 00000000..2debed23 --- /dev/null +++ b/src/test/java/homework_5_test/power_of_number/PowerOfNumberTest.java @@ -0,0 +1,57 @@ +package homework_5_test.power_of_number; + +import base.UnitBase; +import homework_5.power_of_number.PowerOfNumber; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class PowerOfNumberTest extends UnitBase { + + private static final String ERROR_MESSAGE = "Only 2 non-negative integers are allowed"; + + @ParameterizedTest + @MethodSource("validTestCases") + void testValidInput(String in, String expected) { + setInput(in); + new PowerOfNumber().run(); + + removeFromOutput("Enter number and power: "); + + assertEquals(expected, getOutput()); + } + + @ParameterizedTest + @MethodSource("invalidTestCases") + void testInvalidInput(String in) { + setInput(in); + new PowerOfNumber().run(); + + removeFromOutput("Enter number and power: "); + + assertEquals(ERROR_MESSAGE, getOutput()); + } + + static Stream validTestCases() { + return Stream.of( + Arguments.of("2 2", "4"), + Arguments.of("2 1", "2"), + Arguments.of("2 0", "1"), + Arguments.of("0 2", "0") + ); + } + + static Stream invalidTestCases() { + return Stream.of( + Arguments.of("2"), + Arguments.of("2 2 2"), + Arguments.of("2 a"), + Arguments.of("a 2 a"), + Arguments.of("Hello") + ); + } +} diff --git a/src/test/java/homework_6_test/MapProblemsGeneratorTest.java b/src/test/java/homework_6_test/MapProblemsGeneratorTest.java new file mode 100644 index 00000000..7d65ce2b --- /dev/null +++ b/src/test/java/homework_6_test/MapProblemsGeneratorTest.java @@ -0,0 +1,45 @@ +package homework_6_test; + +import homework_6.MapProblemsGenerator.MapCollisionKey; +import homework_6.MapProblemsGenerator.MutableKey; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class MapProblemsGeneratorTest { + + @Test + void givenMapCollisionKey_whenPutInHashMap_thenCollision() { + HashMap hMap = new HashMap<>(); + MapCollisionKey key1 = new MapCollisionKey("Seeta"); + MapCollisionKey key2 = new MapCollisionKey("Geeta"); + + hMap.put(key1, 1); + hMap.put(key2, 2); + assertEquals(1, key2.getEqualsCalls()); + + assertEquals(1, hMap.get(key1)); + assertEquals(2, hMap.get(key2)); + assertEquals(2, key2.getEqualsCalls()); + } + + @Test + void givenMutableKey_whenMutateAfterPut_thenHashMapReturnsNull() { + HashMap hMap = new HashMap<>(); + MutableKey mKey = new MutableKey("Hello"); + + MutableKey anotherKey = new MutableKey("Hello"); + assertEquals(mKey, anotherKey); + + hMap.put(mKey, 1); + assertEquals(1, hMap.get(mKey)); + + StringBuilder sb = mKey.getName(); + sb.append(" my friend"); + + assertNull(hMap.get(mKey)); + } +}