diff --git a/KniffelSpiel/src/domain/Spiel.java b/KniffelSpiel/src/domain/Spiel.java new file mode 100644 index 0000000..dce36d5 --- /dev/null +++ b/KniffelSpiel/src/domain/Spiel.java @@ -0,0 +1,342 @@ +package domain; + +import java.util.ArrayList; +import java.util.List; + +public class Spiel { + + public static final int BONUS = 50; + private List spieler; // List of players in the game + private Kategorie[] kategorie; // Array of categories in the game + private int currentPlayerIndex; + private Würfel würfel; // The dice object used in the game + private int[] scores; // Array to store the scores for each category + private List highscores; + + + // Constructor to initialize the game with the given number of players and dice sides + public Spiel(int numPlayers, int numSides) { + this.spieler = new ArrayList<>(); // Initialize the list of players + // Add the specified number of players to the list + for (int i = 0; i < numPlayers; i++) { + this.spieler.add(new Spieler(i)); + } + + // Initialize the dice object with the specified number of sides + this.würfel = new Würfel(numSides); + + // Initialize the array of categories with all possible categories + this.kategorie = Kategorie.values(); + + // Initialize the array to store the scores for each category + this.scores = new int[kategorie.length]; + this.currentPlayerIndex = 0; + this.highscores = new ArrayList<>(); + } + + // Getter method to return the list of players + public List getSpieler() { + return spieler; + } + + // Method to roll the dice + public void rollWürfel() { + würfel.rollWürfel(); // Call the rollWürfel method on the dice object + } + + public void rerollWürfel() { + würfel.rerollDice(); // Call the rollWürfel method on the dice object + } + + // Method to get the current values of the dice + public int[] getWürfelValues() { + return würfel.getValues(); + } + + // Method to set the score for a specific category + public void setKategorieScore(int categoryIndex, int score) { + // Set the value of the category at the specified index + kategorie[categoryIndex] = kategorie[categoryIndex]; + kategorie[categoryIndex].setValue(score); // Set the value of the category + scores[categoryIndex] = score; // Store the score in the scores array + } + + + public int getCurrentPlayerIndex() { + return currentPlayerIndex; + } + + public void nextPlayer() { + currentPlayerIndex = (currentPlayerIndex + 1) % spieler.size(); + } + + public void setCurrentPlayerIndex(int currentPlayerIndex) { + this.currentPlayerIndex = currentPlayerIndex; + } + + public void setScoreForCategory(int categoryIndex, int score) { + Spieler currentPlayer = spieler.get(currentPlayerIndex); + currentPlayer.setScoreForCategory(categoryIndex, score); + } + + + + // Method to calculate the score for a specific category + public int calculateKategorieScore(int categoryIndex, Würfel würfel) { + + int score = 0; + int[] diceValues = getWürfelValues(); + + switch (categoryIndex) { + case 1: // Einser (Ones) + score = countDiceValue(diceValues, 1); + break; + case 2: // Zweier (Twos) + score = countDiceValue(diceValues, 2); + break; + case 3: // Drei (Threes) + score = countDiceValue(diceValues, 3); + break; + case 4: // Vierer (Fours) + score = countDiceValue(diceValues, 4); + break; + case 5: // Fünfer (Fives) + score = countDiceValue(diceValues, 5); + break; + case 6: // Sechser (Sixes) + score = countDiceValue(diceValues, 6); + break; + case 7: // Dreierpasch (Three of a kind) + score = hasThreeOfAKind(diceValues)? sumDiceValues(diceValues) : 0; + break; + case 8: // Viererpasch (Four of a kind) + score = hasFourOfAKind(diceValues)? sumDiceValues(diceValues) : 0; + break; + case 9: // Full House (Full House) + score = hasFullHouse(diceValues)? 25 : 0; + break; + case 10: // Kleine Straße (Small Straight) + score = hasSmallStraight(diceValues)? 30 : 0; + break; + case 11: // Große Straße (Large Straight) + score = hasLargeStraight(diceValues)? 40 : 0; + break; + case 12: // Kniffel (Yahtzee) + score = hasYahtzee(diceValues)? 50 : 0; + break; + case 13: // Chance (Chance) + score = sumDiceValues(diceValues); + break; + case 14: // Star Wars Day + score = countDiceValue(diceValues, 4) * 4 + countDiceValue(diceValues, 5) * 5; + break; + case 15: // R2D2 + if (hasR2D2Combination(diceValues, 8)) { + score = 42; + } + break; + case 16: // Siebener (Sevens) + score = countDiceValue(diceValues, 7); + break; + case 17: // Achter (Eights) + score = countDiceValue(diceValues, 8); + break; + } + + return score; + + } + + + private int countDiceValue(int[] diceValues, int value) { + int count = 0; + for (int diceValue : diceValues) { + if (diceValue == value) { + count++; + } + } + return count; + } + + + private int sumDiceValues(int[] diceValues) { + int sum = 0; + for (int diceValue : diceValues) { + sum += diceValue; + } + return sum; + } + + + private boolean hasThreeOfAKind(int[] diceValues) { + for (int i = 0; i < würfel.numSides; i++) { + int count = 0; + for (int diceValue : diceValues) { + if (diceValue == i + 1) { + count++; + } + } + if (count >= 3) { + return true; + } + } + return false; + } + + + + private boolean hasFourOfAKind(int[] diceValues) { + for (int i = 0; i < würfel.numSides; i++) { + int count = 0; + for (int diceValue : diceValues) { + if (diceValue == i + 1) { + count++; + } + } + if (count >= 4) { + return true; + } + } + return false; + } + + + private boolean hasFullHouse(int[] diceValues) { + int count1 = 0; + int count2 = 0; + int value1 = 0; + int value2 = 0; + for (int i = 0; i < würfel.numSides; i++) { + int count = 0; + for (int diceValue : diceValues) { + if (diceValue == i + 1) { + count++; + } + } + if (count >= 2) { + count1 = count; + value1 = i + 1; + } else if (count >= 3) { + count2 = count; + value2 = i + 1; + } + } + return count1 >= 2 && count2 >= 3; + } + + private boolean hasSmallStraight(int[] diceValues) { + int[] values = new int[würfel.numSides]; + for (int diceValue : diceValues) { + values[diceValue - 1]++; + } + for (int i = 0; i < 3; i++) { + if (values[i] > 0 && values[i + 1] > 0 && values[i + 2] > 0 && values[i + 3] > 0) { + return true; + } + } + return false; + } + + + private boolean hasLargeStraight(int[] diceValues) { + int[] values = new int[würfel.numSides]; + for (int diceValue : diceValues) { + values[diceValue - 1]++; + } + for (int i = 0; i < 2; i++) { + if (values[i] > 0 && values[i + 1] > 0 && values[i + 2] > 0 && values[i + 3] > 0 && values[i + 4] > 0) { + return true; + } + } + return false; + } + + + private boolean hasYahtzee(int[] diceValues) { + int value = diceValues[0]; + for (int diceValue : diceValues) { + if (diceValue!= value) { + return false; + } + } + return true; + } + + + + + + private boolean hasR2D2Combination(int[] diceValues, int numSides) { + if (numSides != 8) { + return false; // Р2Д2-комбинация доступна только для кубика с 8 гранями + } + + int[] values = new int[8]; // Размер массива должен быть 8 для кубика с 8 гранями + for (int diceValue : diceValues) { + if (diceValue >= 1 && diceValue <= 8) { + values[diceValue - 1]++; + } + } + return values[0] >= 1 && values[7] >= 1 && values[1] >= 2 && values[3] >= 2; + } + + + + public int calculateTotalScore(Würfel würfel) { + int totalScore = 0; + // Вычисляем сумму всех категорий + for (int categoryIndex = 1; categoryIndex <= 17; categoryIndex++) { + totalScore += calculateKategorieScore(categoryIndex, würfel); + } + // Проверяем, достигла ли сумма бонусного порога + if (totalScore >= 108) { + totalScore += BONUS; + } + return totalScore; + } + + + + + // Method to check if a category has been used + public boolean hasCategoryBeenUsed(int kategorieIndex) { + return kategorie[kategorieIndex]!= null; + } + + + public String getCategoryName(int categoryIndex) { + switch (categoryIndex) { + case 1: return "EINSER"; + case 2: return "ZWEIER"; + case 3: return "DREIER"; + case 4: return "VIERER"; + case 5: return "FÜNFER"; + case 6: return "SECHSER"; + case 7: return "DREIERPASCH"; + case 8: return "VIERPASCH"; + case 9: return "FULL_HOUSE"; + case 10: return "KLEIN_STRASSE"; + case 11: return "GROSSE_STRASSE"; + case 12: return "KNIFFEL"; + case 13: return "CHANCE"; + case 14: return "STAR_WARS_DAY"; + case 15: return "R2D2"; + case 16: return "SIEBENER"; + case 17: return "ACHTER"; + default: return "Invalid category"; + } + } + + + // Метод для добавления нового рекорда + public void addHighscore(String highscore) { + highscores.add(highscore); + } + + + // Метод для получения списка рекордов + public List getHighscores() { + return highscores; + } + +}