From 6afafbd6357b58577af28a8b05bbe81bbc5beaf8 Mon Sep 17 00:00:00 2001 From: Andres Cruz <1912548@stud.hs-mannheim.de> Date: Sun, 1 Dec 2024 22:59:06 +0100 Subject: [PATCH] Uebung 4 --- .../ExpressionChecker.java | 2 +- .../ExpressionCheckerV2.java | 2 +- .../Stack.java | 2 +- src/main/java/Uebung_04_Andres/Board.java | 55 +++++++++++++++++++ .../java/Uebung_04_Andres/ComputerPlayer.java | 26 +++++++++ src/main/java/Uebung_04_Andres/Game.java | 54 ++++++++++++++++++ .../java/Uebung_04_Andres/HumanPlayer.java | 21 +++++++ src/main/java/Uebung_04_Andres/Player.java | 16 ++++++ src/main/java/Uebung_04_Andres/TicTacToe.java | 23 ++++++++ 9 files changed, 198 insertions(+), 3 deletions(-) rename src/main/java/{Uebung3_Andres => Uebung_03_Andres}/ExpressionChecker.java (94%) rename src/main/java/{Uebung3_Andres => Uebung_03_Andres}/ExpressionCheckerV2.java (94%) rename src/main/java/{Uebung3_Andres => Uebung_03_Andres}/Stack.java (85%) create mode 100644 src/main/java/Uebung_04_Andres/Board.java create mode 100644 src/main/java/Uebung_04_Andres/ComputerPlayer.java create mode 100644 src/main/java/Uebung_04_Andres/Game.java create mode 100644 src/main/java/Uebung_04_Andres/HumanPlayer.java create mode 100644 src/main/java/Uebung_04_Andres/Player.java create mode 100644 src/main/java/Uebung_04_Andres/TicTacToe.java diff --git a/src/main/java/Uebung3_Andres/ExpressionChecker.java b/src/main/java/Uebung_03_Andres/ExpressionChecker.java similarity index 94% rename from src/main/java/Uebung3_Andres/ExpressionChecker.java rename to src/main/java/Uebung_03_Andres/ExpressionChecker.java index 305573c..60a70fe 100644 --- a/src/main/java/Uebung3_Andres/ExpressionChecker.java +++ b/src/main/java/Uebung_03_Andres/ExpressionChecker.java @@ -1,4 +1,4 @@ -package Uebung3_Andres; +package Uebung_03_Andres; import java.util.Scanner; diff --git a/src/main/java/Uebung3_Andres/ExpressionCheckerV2.java b/src/main/java/Uebung_03_Andres/ExpressionCheckerV2.java similarity index 94% rename from src/main/java/Uebung3_Andres/ExpressionCheckerV2.java rename to src/main/java/Uebung_03_Andres/ExpressionCheckerV2.java index 3315ae3..d940cdb 100644 --- a/src/main/java/Uebung3_Andres/ExpressionCheckerV2.java +++ b/src/main/java/Uebung_03_Andres/ExpressionCheckerV2.java @@ -1,4 +1,4 @@ -package Uebung3_Andres; +package Uebung_03_Andres; import java.util.Scanner; diff --git a/src/main/java/Uebung3_Andres/Stack.java b/src/main/java/Uebung_03_Andres/Stack.java similarity index 85% rename from src/main/java/Uebung3_Andres/Stack.java rename to src/main/java/Uebung_03_Andres/Stack.java index 10c0079..d041a8c 100644 --- a/src/main/java/Uebung3_Andres/Stack.java +++ b/src/main/java/Uebung_03_Andres/Stack.java @@ -1,4 +1,4 @@ -package Uebung3_Andres; +package Uebung_03_Andres; public class Stack { diff --git a/src/main/java/Uebung_04_Andres/Board.java b/src/main/java/Uebung_04_Andres/Board.java new file mode 100644 index 0000000..fc082a1 --- /dev/null +++ b/src/main/java/Uebung_04_Andres/Board.java @@ -0,0 +1,55 @@ +package Uebung_04_Andres; + +import java.util.Arrays; + +public class Board { + + private final String EMPTYFIELD = " "; + private String[] boardFields = new String[9]; + + public Board() { + Arrays.fill(boardFields, EMPTYFIELD); + } + + public String[] getBoard() { + return this.boardFields; + } + + public void setBoardMove(int index, String playerSign) { + this.boardFields[index] = playerSign; + } + + public boolean isFull() { + for (String s: boardFields) { + if (s.equals(EMPTYFIELD)) return false; + } + System.out.println("\nUnentschieden!"); + return true; + } + + public boolean isFieldChoosable(int index) { + return boardFields[index].equals(EMPTYFIELD); + } + + //Below is section for helper methods - Strings and outputs// + public void printBoard() { + System.out.println("______________________________________________________________________"); + String grid = ""; + for (int i = 0; i < 9; i++) { + if (i % 3 == 0) grid += "\n"; + grid += "[" + boardFields[i] + "]"; + } + System.out.println(grid); + } + + public void printOptionsMenu() { + System.out.println("\n\nDu hast die folgende leeren Felder: "); + String grid = ""; + for (int i = 0; i < 9; i++) { + if (i % 3 == 0) grid += "\n"; + grid += isFieldChoosable(i) ? (i + 1)+" " : " "; + } + System.out.println(grid+"\nGib die Zahl ein, wo du deinen Kreis setzen willst: "); + } + +} diff --git a/src/main/java/Uebung_04_Andres/ComputerPlayer.java b/src/main/java/Uebung_04_Andres/ComputerPlayer.java new file mode 100644 index 0000000..2ebf38b --- /dev/null +++ b/src/main/java/Uebung_04_Andres/ComputerPlayer.java @@ -0,0 +1,26 @@ +package Uebung_04_Andres; + +import java.util.Random; + +public class ComputerPlayer extends Player { + + public ComputerPlayer(String playerSign) { + super(playerSign); + } + + @Override + public void move(Board board) { + int randomNumber; + + do { + randomNumber = generateNumber(); + } while (!board.isFieldChoosable(randomNumber)); + + board.setBoardMove(randomNumber, playerSign); + } + + private int generateNumber() { + Random random = new Random(); + return random.nextInt(9); + } +} diff --git a/src/main/java/Uebung_04_Andres/Game.java b/src/main/java/Uebung_04_Andres/Game.java new file mode 100644 index 0000000..468c0df --- /dev/null +++ b/src/main/java/Uebung_04_Andres/Game.java @@ -0,0 +1,54 @@ +package Uebung_04_Andres; + +public class Game { + + private static Board board = new Board(); //just to avoid adding more parameters to game-won logic functions + private static ComputerPlayer computer; + private static HumanPlayer human; + + public void startGame(boolean isHumanFirstToPlay) { + computer = new ComputerPlayer(isHumanFirstToPlay ? "O" : "X"); + human = new HumanPlayer(isHumanFirstToPlay ? "X" : "O"); + + while (!board.isFull()) { + this.playerMove(isHumanFirstToPlay); + board.printBoard(); + if (gameWasWon()) { + System.out.println(isHumanFirstToPlay ? "\nDu hast gewonnen!" : "Der Roboter hat gewonnen!"); + break; + } + isHumanFirstToPlay = !isHumanFirstToPlay; //Invert to have the other player play + } + } + + private void playerMove(boolean isHumanFirstToPlay) { + if (isHumanFirstToPlay) { + human.move(board); + } else { + computer.move(board); + } + } + + private boolean gameWasWon() { + return isDiagonalWin() || isHorizontalWin() || isVerticalWin(); + } + + private boolean isDiagonalWin() { + return isLineComplete(0,4,8) || isLineComplete(2,4,6); + } + + private boolean isHorizontalWin() { + return isLineComplete(0,1,2) || isLineComplete(3,4,5) || isLineComplete(6,7,8); + } + + private boolean isVerticalWin() { + return isLineComplete(0,3,6) || isLineComplete(1,4,7) || isLineComplete(2,5,8); + } + + private boolean isLineComplete(int first, int second, int third) { + final String[] boardFields = board.getBoard(); + return !boardFields[first].equals(" ") && + boardFields[first].equals(boardFields[second]) && + boardFields[first].equals(boardFields[third]); + } +} diff --git a/src/main/java/Uebung_04_Andres/HumanPlayer.java b/src/main/java/Uebung_04_Andres/HumanPlayer.java new file mode 100644 index 0000000..2066591 --- /dev/null +++ b/src/main/java/Uebung_04_Andres/HumanPlayer.java @@ -0,0 +1,21 @@ +package Uebung_04_Andres; + +public class HumanPlayer extends Player { + + public HumanPlayer(String playerSign) { + super(playerSign); + } + + @Override + public void move(Board board) { + board.printOptionsMenu(); + int choice; + + do { + choice = TicTacToe.scanner.nextInt(); //-1 to transform from position to index in array + } while (!board.isFieldChoosable(choice-1)); + + board.setBoardMove(choice-1, playerSign); + } + +} diff --git a/src/main/java/Uebung_04_Andres/Player.java b/src/main/java/Uebung_04_Andres/Player.java new file mode 100644 index 0000000..39a9cd4 --- /dev/null +++ b/src/main/java/Uebung_04_Andres/Player.java @@ -0,0 +1,16 @@ +package Uebung_04_Andres; + +public abstract class Player { + + protected String playerSign; + + /** + * Constructor to force inheriting classes to initialise the playerSign + * @param playerSign: "X" or "O" + */ + public Player(String playerSign) { + this.playerSign = playerSign; + } + + public abstract void move(Board board); +} diff --git a/src/main/java/Uebung_04_Andres/TicTacToe.java b/src/main/java/Uebung_04_Andres/TicTacToe.java new file mode 100644 index 0000000..fdca108 --- /dev/null +++ b/src/main/java/Uebung_04_Andres/TicTacToe.java @@ -0,0 +1,23 @@ +package Uebung_04_Andres; + +import java.util.Scanner; + +public class TicTacToe { + + public static Scanner scanner; //Global variable for global scanner usage + + public static void main(String[] args) { + scanner = new Scanner(System.in); + Game game = new Game(); + + System.out.println("Der Mensch wird den ersten Zug machen.\n" + + "Drücken Sie die Eingabetaste, um\n" + + "fortzufahren, oder geben Sie 1 ein,\n" + + "damit der Computer den ersten Zug macht:"); + String choice = scanner.nextLine(); + System.out.println("######################################################################"); + game.startGame(!choice.trim().equals("1")); //If anything but a 1 is entered, human starts the game + scanner.close(); + } + +}