commit d9cd9f2c21814c2ba5605fd2f39ae5aa10bc1ea4 Author: Dominik Stahl Date: Thu Mar 20 11:00:44 2025 +0100 Probeklausur diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b9f17b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +highscores.txt \ No newline at end of file diff --git a/17_ProbePE_Sem1_DartsCounter.pdf b/17_ProbePE_Sem1_DartsCounter.pdf new file mode 100644 index 0000000..08c4f7b Binary files /dev/null and b/17_ProbePE_Sem1_DartsCounter.pdf differ diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/Board.java b/src/de/dhbw_ka/probe_pe/darts_counter/Board.java new file mode 100644 index 0000000..14c2307 --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/Board.java @@ -0,0 +1,45 @@ +package src.de.dhbw_ka.probe_pe.darts_counter; + +/** + * Class representing the Game Board + */ +public class Board { + /** + * All fields a player can hit with a throw + * + * @see Field + */ + private Field[] fields = new Field[63]; + + /** + * Initiates the board with all fields + */ + public Board() { + for (int i = 1; i <= 20; i++) { + fields[(i - 1) * 3] = new Field("" + i, i, false); + fields[(i - 1) * 3 + 1] = new Field("D" + i, i * 2, true); + fields[(i - 1) * 3 + 2] = new Field("T" + i, i * 3, false); + } + fields[60] = new Field("25", 25, false); + fields[61] = new Field("BULL", 50, true); + fields[62] = new Field("x", 0, false); + } + + /** + * Get the matching field for a (user input) string or null + * + * @param label + * @return the field with the matching label + * @see Field + */ + public Field parseField(String label) { + for (Field f : fields) { + if (f == null) + continue; + if (f.getLabel().equalsIgnoreCase(label)) + return f; + } + + return null; + } +} diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/DartsCounter.java b/src/de/dhbw_ka/probe_pe/darts_counter/DartsCounter.java new file mode 100644 index 0000000..d320fa9 --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/DartsCounter.java @@ -0,0 +1,26 @@ +package src.de.dhbw_ka.probe_pe.darts_counter; + +/** + * Darts counter application + */ +public class DartsCounter { + + /** + * Application entry point + * + * @param args + * command line arguments + */ + public static void main(String[] args) { + + final Board b = new Board(); + + final Player[] players = new Player[] { new Player("Luke Humphries"), new Player("Luke Littler") + }; + + final Game g = new Game(b, players); + g.start(); + + } + +} diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/Field.java b/src/de/dhbw_ka/probe_pe/darts_counter/Field.java new file mode 100644 index 0000000..bc8e74f --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/Field.java @@ -0,0 +1,61 @@ +package src.de.dhbw_ka.probe_pe.darts_counter; + +/** + * Class representing a dart board field + */ +public class Field { + /** + * Label of the Field + */ + private String label; + /** + * Value of the Field + */ + private int value; + /** + * If the field is a double value field + */ + private boolean doubleField; + + /** + * Initiates a new Field + * + * @param label + * @param value + * @param doubleField + */ + public Field(String label, int value, boolean doubleField) { + this.label = label; + this.value = value; + this.doubleField = doubleField; + } + + /** + * + * @return Label of the field + */ + public String getLabel() { + return label; + } + + /** + * + * @return value of the field + */ + public int getValue() { + return value; + } + + /** + * + * @return true if the field is a double value field + */ + public boolean getDoubleField() { + return doubleField; + } + + @Override + public String toString() { + return this.label; + } +} diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/Game.java b/src/de/dhbw_ka/probe_pe/darts_counter/Game.java new file mode 100644 index 0000000..0b37096 --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/Game.java @@ -0,0 +1,169 @@ +package src.de.dhbw_ka.probe_pe.darts_counter; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Scanner; + +/** + * Class representing the darts game + */ +public class Game { + /** + * Instance of the Board + * + * @see Board + */ + private Board board; + /** + * Array of the players playing + * + * @see Player + */ + private Player[] players; + /** + * Index of the player who has the next turn + */ + private int nextTurnPlayerIndex = 0; + + /** + * Initiates a new game + * The game has to be started with `game.start();` + * + * @param board + * @param players + */ + public Game(Board board, Player[] players) { + this.board = board; + this.players = players; + } + + /** + * Checks if the game is ended. + * + * @return true if the game is ended + */ + private boolean gameEnd() { + Boolean ended = false; + for (Player p : players) { + if (p.getRemainingPoints() == 0) + ended = true; + } + if (players[nextTurnPlayerIndex].getVisitsCount() == 10) + ended = true; + return ended; + } + + /** + * Gets the player who has won. + * + * @return Winner + * @see Player + */ + private Player getWinner() { + for (Player p : players) { + if (p.getRemainingPoints() == 0) + return p; + } + return null; + } + + /** + * Parses a user input string to a visit + * + * @param input + * @return visit matching the input string + * @see Visit + */ + private Visit inputToVisit(String input) { + String[] parts = input.split(" "); + Field[] fields = new Field[parts.length]; + for (int i = 0; i < fields.length; i++) + fields[i] = board.parseField(parts[i]); + return new Visit(fields); + } + + /** + * Check if a checkout for the remaining points is possible + * + * @param points + * @return null or a string of fields + */ + private String checkout(int points) { + if (points > 170) + return null; + + Path checkoutsFile = Path.of("src/de/dhbw_ka/probe_pe/darts_counter/checkouts.txt"); + try { + BufferedReader reader = Files.newBufferedReader(checkoutsFile, StandardCharsets.UTF_8); + for (int i = 0; i < (points - 1); i++) + reader.readLine(); + String checkout = reader.readLine(); + reader.close(); + if (!checkout.equals("-")) + return checkout; + } catch (IOException e) { + System.err.println("Failed to load checkouts file."); + e.printStackTrace(); + } + return null; + } + + /** + * Starts the game + */ + public void start() { + Scanner in = new Scanner(System.in); + while (!gameEnd()) { + Player currentTurnPlayer = this.players[this.nextTurnPlayerIndex]; + nextTurnPlayerIndex = (nextTurnPlayerIndex + 1) % this.players.length; + System.out.println("Player: " + currentTurnPlayer); + if (this.checkout(currentTurnPlayer.getRemainingPoints()) != null) { + System.out.println("Checkout possible with: " + this.checkout(currentTurnPlayer.getRemainingPoints())); + } + System.out.print("Enter visit: "); + String inputString = in.nextLine(); + Visit visit = this.inputToVisit(inputString); + Boolean success = currentTurnPlayer.addVisit(visit); + if (success) { + System.out.println("Scored: " + visit.getValue()); + } else { + System.out.println("Invalid visit"); + } + System.out.println("============================="); + } + in.close(); + + Player winner = this.getWinner(); + if (winner == null) { + System.out.println("You're too bad for this game"); + } else { + System.out.println("Game shot and the leg, " + winner.getName()); + this.writeWinnerToFile(winner); + } + } + + /** + * Writes the winner into the highscores.txt file + * + * @param winner + * @see Player + */ + private void writeWinnerToFile(Player winner) { + Path winnerFile = Paths.get("highscores.txt"); + + try { + BufferedWriter writer = Files.newBufferedWriter(winnerFile, StandardCharsets.UTF_8, StandardOpenOption.APPEND); + writer.write(winner.getName() + " won with " + winner.getCountDartsThrown() + " darts.\n"); + writer.close(); + } catch (IOException e) { + System.err.println("Failed to write highscore file."); + e.printStackTrace(); + } + } +} diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/Player.java b/src/de/dhbw_ka/probe_pe/darts_counter/Player.java new file mode 100644 index 0000000..37b56ca --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/Player.java @@ -0,0 +1,135 @@ +package src.de.dhbw_ka.probe_pe.darts_counter; + +/** + * Class representing a player in the darts game + */ +public class Player { + /** + * Name of the player + */ + private String name; + /** + * Amount of darts the player has already thrown + */ + private int countDartsThrown = 0; + /** + * Array of visits the player has already done (max 10) + * + * @see Visit + */ + private Visit[] visits = new Visit[10]; + + /** + * Initiates a new player + * + * @param name Name of the player + */ + public Player(String name) { + this.name = name; + } + + /** + * Gets the players name + * + * @return name + */ + public String getName() { + return name; + } + + /** + * Sets the players name + * + * @param name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Get the amount of darts this player has thrown + * + * @return amount of darts + */ + public int getCountDartsThrown() { + return countDartsThrown; + } + + /** + * Gets the amount of visits the player has already done + * + * @return already done visits + */ + public int getVisitsCount() { + int visitCount = 0; + for (Visit v : visits) { + if (v == null) + continue; + visitCount++; + } + return visitCount; + } + + /** + * Gets the remaining points of this player + * + * @return remaining points + */ + public int getRemainingPoints() { + int pointsRemaining = 501; + for (Visit v : visits) { + if (v == null) + continue; + pointsRemaining -= v.getValue(); + } + return pointsRemaining; + } + + /** + * Attempts to add a visit + * + * @param visit The visit to add + * @return success of the visit + * @see Visit + */ + public boolean addVisit(Visit visit) { + /** + * Count up the darts thrown + */ + this.countDartsThrown += visit.getFields().length; + + /** + * Don't allow visits to have a higher value than the remaining points + */ + if (visit.getValue() > this.getRemainingPoints()) + return false; + + /** + * Only allow finishing the game with a double field + */ + if (visit.getValue() == this.getRemainingPoints() && !visit.getLastField().getDoubleField()) + return false; + + /** + * Don't allow a player to get exactly 1 point + */ + if (this.getRemainingPoints() - visit.getValue() == 1) + return false; + + /** + * Add visit to array + */ + int currentVisitCount = this.getVisitsCount(); + if (currentVisitCount >= 10) + return false; + + this.visits[currentVisitCount] = visit; + + return true; + } + + @Override + public String toString() { + return this.name + ", " + this.getRemainingPoints() + " points remaining."; + } +} diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/Visit.java b/src/de/dhbw_ka/probe_pe/darts_counter/Visit.java new file mode 100644 index 0000000..d8c76a3 --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/Visit.java @@ -0,0 +1,63 @@ +package src.de.dhbw_ka.probe_pe.darts_counter; + +/** + * Class representing a dart visit + */ +public class Visit { + /** + * Array of all the fields hit in this visit + * + * @see Field + */ + private Field[] fields; + + /** + * Create a new Visit instance for the hit fields + * + * @param fields array of fields hit (must be less or eqal to 3) + * @see Field + */ + public Visit(Field[] fields) { + if (fields.length > 3) + throw new IllegalArgumentException("Thrown too many darts for one visit!"); + + this.fields = fields; + } + + /** + * + * @return All the fields hit in this visit + * @see Field + */ + public Field[] getFields() { + return fields; + } + + /** + * Calculate the value of this visit + * + * @return value of the visit + */ + public int getValue() { + int value = 0; + for (Field f : fields) { + if (f == null) + continue; + value += f.getValue(); + } + return value; + } + + /** + * Returns the last field for checking if the player finished with a double + * field + * + * @return last field of the visit + * @see Field + */ + public Field getLastField() { + if (fields.length == 0) + return null; + return fields[fields.length - 1]; + } +} diff --git a/src/de/dhbw_ka/probe_pe/darts_counter/checkouts.txt b/src/de/dhbw_ka/probe_pe/darts_counter/checkouts.txt new file mode 100644 index 0000000..ac800d3 --- /dev/null +++ b/src/de/dhbw_ka/probe_pe/darts_counter/checkouts.txt @@ -0,0 +1,170 @@ +- +D1 +1 D1 +D2 +1 D2 +D3 +1 D3 +D4 +1 D4 +D5 +1 D5 +D6 +1 D6 +D7 +1 D7 +D8 +1 D8 +D9 +1 D9 +D10 +1 D10 +D11 +3 D10 +D12 +5 D10 +6 D10 +7 D10 +D14 +9 D10 +D15 +1 D15 +D16 +1 D16 +D17 +3 D16 +D18 +5 D16 +6 D16 +7 D16 +D20 +1 D20 +2 D20 +3 D20 +4 D20 +5 D20 +6 D20 +7 D20 +16 D16 +9 D20 +10 D20 +11 D20 +12 D20 +13 D20 +14 D20 +15 D20 +16 D20 +17 D20 +18 D20 +19 D20 +20 D20 +25 D18 +T10 D16 +T13 D12 +T16 D8 +25 D20 +T10 D18 +T17 D8 +T20 D4 +T13 D15 +T10 D20 +T17 D10 +T12 D18 +T19 D8 +T18 D10 +T17 D12 +T20 D8 +T19 D10 +T18 D12 +T13 D20 +T20 D10 +T15 D18 +T14 D20 +T17 D16 +T20 D12 +T15 D20 +T18 D16 +T17 D18 +T16 D20 +T19 D16 +T18 D18 +T17 D20 +T20 D16 +T19 D18 +T18 D20 +T19 D19 +T20 D18 +T19 D20 +T20 D19 +T20 7 D16 +T20 D20 +T17 BULL +T20 10 D16 +T20 3 D20 +T18 BULL +T20 13 D16 +T20 10 D18 +T19 BULL +T20 16 D16 +T20 17 D16 +T20 18 D16 +T20 19 D16 +T20 20 D16 +T20 13 D20 +T20 14 D20 +T20 15 D20 +T20 16 D20 +T20 17 D20 +T20 18 D20 +T20 19 D20 +T20 20 D20 +T20 T7 D20 +T18 T12 D16 +T19 T10 D18 +T20 14 BULL +25 T20 D20 +T19 19 BULL +T20 T17 D8 +T18 T14 D16 +T19 T12 D18 +T20 20 BULL +T20 T17 D10 +T20 T12 D18 +T20 T11 D20 +T20 T14 D16 +T17 T20 D12 +T20 T20 D8 +T19 T20 D10 +T20 T18 D12 +T19 T14 D20 +T20 T20 D10 +T20 T19 D12 +T20 T14 D20 +T20 T17 D16 +T20 T20 D12 +T20 T15 D20 +T20 T18 D16 +T19 T18 D18 +T20 T16 D20 +T20 T19 D16 +T20 T18 D18 +T20 T17 D20 +T20 T20 D16 +T20 T19 D18 +T20 T18 D20 +T20 T19 D19 +T20 T20 D18 +T20 T19 D20 +T20 T20 D19 +- +T20 T20 D20 +T20 T17 BULL +- +- +T20 T18 BULL +- +- +T20 T19 BULL +- +- +T20 T20 BULL \ No newline at end of file