diff --git a/lib/data/game_session.dart b/lib/data/game_session.dart index 66a00c4..5cf54e3 100644 --- a/lib/data/game_session.dart +++ b/lib/data/game_session.dart @@ -1,3 +1,5 @@ +import 'package:cabo_counter/data/round.dart'; + /// This class represents a game session for the Cabo game. /// [gameTitle] is the title of the game. /// [players] is a string list of player names. @@ -12,36 +14,27 @@ class GameSession { final String gameTitle; final bool gameHasPointLimit; final List players; - List> playerScores = List.generate(5, (_) => [0, 0]); + late List playerScores; + List roundList = []; int roundNumber = 1; bool isGameFinished = false; String winner = ''; GameSession({ required this.gameTitle, - required this.players, required this.gameHasPointLimit, - }); + required this.players, + }) { + playerScores = List.filled(players.length, 0); + } @override String toString() { return ('GameSession: [createdAt: $createdAt, gameTitle: $gameTitle, ' 'gameHasPointLimit: $gameHasPointLimit, players: $players, ' - 'playerScores: $playerScores, roundNumber: $roundNumber, ' - 'isGameFinished: $isGameFinished, winner: $winner]'); - } - - // FIXME Debug - /// Returns a string representation of the scores for a specific round. - /// The method takes a round number as a parameter and returns a string - /// containing the name of each player and their corressponding score in - /// the given round. - String printRoundScores(int round) { - String result = ''; - for (int i = 0; i < players.length; i++) { - result += '${players[i]}: ${playerScores[i][round]}\n'; - } - return result; + 'playerScores: $playerScores, roundList: $roundList, ' + 'roundNumber: $roundNumber, isGameFinished: $isGameFinished, ' + 'winner: $winner]'); } /// Returns the length of all player names combined. @@ -53,75 +46,200 @@ class GameSession { return length; } - /// Increases the round number by 1. - void increaseRound() { - roundNumber++; + /// Assigns 50 points to all players except the kamikaze player. + /// [kamikazePlayerIndex] is the index of the kamikaze player. + void applyKamikaze(int roundNum, int kamikazePlayerIndex) { + List roundScores = List.generate(players.length, (_) => 0); + List scoreUpdates = List.generate(players.length, (_) => 0); + for (int i = 0; i < roundScores.length; i++) { + if (i != kamikazePlayerIndex) { + scoreUpdates[i] += 50; + } + } + addRoundScoresToList( + roundNum, roundScores, scoreUpdates, kamikazePlayerIndex); } - /// Expands the player score lists by adding a new score of 0 for each player. - /// This method is called when a new round starts so the lists in the - /// active game view expands - void expandPlayerScoreLists() { - for (int i = 0; i < playerScores.length; i++) { - playerScores[i].add(0); + /// Checks the scores of the current round and assigns points to the players. + /// There are three possible outcomes of a round: + /// + /// **Case 1**
+ /// The player who said CABO has the lowest score. They receive 0 points. + /// Every other player gets their round score. + /// + /// **Case 2**
+ /// The player who said CABO does not have the lowest score. + /// They receive 5 extra points added to their round score. + /// Every player with the lowest score gets 0 points. + /// Every other player gets their round score. + void calculateScoredPoints( + int roundNum, List roundScores, int caboPlayerIndex) { + print('Spieler: $players'); + print('Punkte: $roundScores'); + print('${players[caboPlayerIndex]} hat mit ${roundScores[caboPlayerIndex]} ' + 'Punkten CABO gesagt'); + + /// List of the index of the player(s) with the lowest score + List lowestScoreIndex = _getLowestScoreIndex(roundScores); + print('Folgende Spieler haben die niedrigsten Punte:'); + for (int i in lowestScoreIndex) { + print('${players[i]} (${roundScores[i]} Punkte)'); } + // The player who said CABO is one of the players which have the + // fewest points. + if (lowestScoreIndex.contains(caboPlayerIndex)) { + print('${players[caboPlayerIndex]} hat CABO gesagt ' + 'und bekommt 0 Punkte'); + print('Alle anderen Spieler bekommen ihre Punkte'); + _assignPoints(roundNum, roundScores, [caboPlayerIndex]); + } else { + // A player other than the one who said CABO has the fewest points. + print('${players[caboPlayerIndex]} hat CABO gesagt, ' + 'jedoch nicht die wenigsten Punkte.'); + print('Folgende:r Spieler haben die wenigsten Punkte:'); + for (int i in lowestScoreIndex) { + print('${players[i]}: ${roundScores[i]} Punkte'); + } + _assignPoints(roundNum, roundScores, lowestScoreIndex, caboPlayerIndex); + } + } + + /// Returns the index of the player with the lowest score. If there are + /// multiple players with the same lowest score, all of them are returned. + /// [roundScores] is a list of the scores of all players in the current round. + List _getLowestScoreIndex(List roundScores) { + int lowestScore = roundScores[0]; + List lowestScoreIndex = [0]; + + for (int i = 1; i < roundScores.length; i++) { + if (roundScores[i] < lowestScore) { + lowestScore = roundScores[i]; + lowestScoreIndex = [i]; + } else if (roundScores[i] == lowestScore) { + lowestScoreIndex.add(i); + } + } + return lowestScoreIndex; + } + + /// Assigns points to the players based on the scores of the current round. + /// [roundNum] is the number of the current round. + /// [roundScores] is the raw list of the scores of all players in the current round. + /// [winnerIndex] is the index of the player who receives 5 extra points + void _assignPoints(int roundNum, List roundScores, List winnerIndex, + [int loserIndex = -1]) { + /// List of the updates for every player score + List scoreUpdates = [...roundScores]; + print('Folgende Punkte wurden aus der Runde übernommen:'); + for (int i = 0; i < scoreUpdates.length; i++) { + print('${players[i]}: ${scoreUpdates[i]}'); + } + for (int i in winnerIndex) { + print('${players[i]} hat gewonnen und bekommt 0 Punkte'); + scoreUpdates[i] = 0; + } + if (loserIndex != -1) { + print('${players[loserIndex]} bekommt 5 Fehlerpunkte'); + scoreUpdates[loserIndex] += 5; + } + print('Aktualisierte Punkte:'); + for (int i = 0; i < scoreUpdates.length; i++) { + print('${players[i]}: ${scoreUpdates[i]}'); + } + print('scoreUpdates: $scoreUpdates, roundScores: $roundScores'); + addRoundScoresToList(roundNum, roundScores, scoreUpdates); } /// Sets the scores of the players for a specific round. /// This method takes a list of round scores and a round number as parameters. - /// It then replaces the values for the given [roundNumber] in the + /// It then replaces the values for the given [roundNum] in the /// playerScores. Its important that each index of the [roundScores] list /// corresponds to the index of the player in the [playerScores] list. - void addRoundScoresToScoreList(List roundScores, int roundNumber) { - print('addRoundScoresToScoreList: $roundScores'); - for (int i = 0; i < roundScores.length; i++) { - playerScores[i][roundNumber] = (roundScores[i]); + void addRoundScoresToList( + int roundNum, List roundScores, List scoreUpdates, + [int? kamikazePlayerIndex]) { + Round newRound = Round( + roundNum: roundNum, + scores: roundScores, + scoreUpdates: scoreUpdates, + kamikaze: kamikazePlayerIndex, + ); + if (roundNum > roundList.length) { + roundList.add(newRound); + } else { + roundList[roundNum - 1] = newRound; } } + /// This method updates the points of each player after a round. + /// It first uses the _sumPoints() method to calculate the total points of each player. + /// Then, it checks if any player has reached 100 points. If so, it marks + /// that player as having reached 100 points in that corresponding [Round] object. + /// If the game has the point limit activated, it first applies the + /// _subtractPointsForReachingHundred() method to subtract 50 points + /// for every time a player reached 100 points in the game. + /// It then checks if any player has exceeded 100 points. If so, it sets + /// isGameFinished to true and calls the _setWinner() method to determine + /// the winner. + void updatePoints() { + _sumPoints(); + if (gameHasPointLimit) { + _checkHundredPointsReached(); + + for (int i = 0; i < playerScores.length; i++) { + if (playerScores[i] > 100) { + isGameFinished = true; + print('${players[i]} hat die 100 Punkte ueberschritten, ' + 'deswegen wurde das Spiel beendet'); + _setWinner(); + } + } + } + } + + /// Sums up the points of all players and stores the result in the + /// playerScores list. + void _sumPoints() { + print('_sumPoints()'); + for (int i = 0; i < players.length; i++) { + playerScores[i] = 0; + for (int j = 0; j < roundList.length; j++) { + playerScores[i] += roundList[j].scoreUpdates[i]; + } + } + } + + /// Checks if a player has reached 100 points in the current round. + /// If so, it updates the [scoreUpdate] List by subtracting 50 points from + /// the corresponding round update. + void _checkHundredPointsReached() { + for (int i = 0; i < players.length; i++) { + if (playerScores[i] == 100) { + print('${players[i]} hat genau 100 Punkte erreicht und bekommt ' + 'deswegen 50 Punkte abgezogen'); + roundList[roundNumber - 1].scoreUpdates[i] -= 50; + } + } + _sumPoints(); + } + /// Determines the winner of the game session. /// It iterates through the player scores and finds the player /// with the lowest score. - void _determineWinner() { - int score = playerScores[0][0]; + void _setWinner() { + int score = playerScores[0]; String lowestPlayer = players[0]; for (int i = 0; i < players.length; i++) { - if (playerScores[i][0] < score) { - score = playerScores[i][0]; + if (playerScores[i] < score) { + score = playerScores[i]; lowestPlayer = players[i]; } } winner = lowestPlayer; } - /// Summarizes the points of all players in the first index of their - /// score list. The method clears the first index of each player score - /// list and then sums up the points from the second index to the last - /// index. It then stores the result in the first index. This method is - /// used to update the total points of each player after a round. - /// If a player reaches the 101 points, - void sumPoints() { - for (int i = 0; i < playerScores.length; i++) { - playerScores[i][0] = 0; - for (int j = 1; j < playerScores[i].length; j++) { - playerScores[i][0] += playerScores[i][j]; - } - if (gameHasPointLimit) { - print('playerScores[i][0]: ${playerScores[i][0]}'); - if (playerScores[i][0] == 100) { - print('${players[i]} hat genau 100 Punkte erreicht, ' - 'seine Punkte werden auf 50 Punkte reduziert'); - playerScores[i][playerScores[i].length - 1] -= - 50; // Subtract 50 from this round - playerScores[i][0] -= 50; // Subtract 50 from the sum - } else if (playerScores[i][0] > 100) { - isGameFinished = true; - print('${players[i]} hat die 100 Punkte ueberschritten, ' - 'deswegen wurde das Spiel beendet'); - _determineWinner(); - } - } - } - print('GameSession: sumPoints: $playerScores'); + /// Increases the round number by 1. + void increaseRound() { + roundNumber++; } } diff --git a/lib/views/round_view.dart b/lib/views/round_view.dart index c3f39b6..331cb81 100644 --- a/lib/views/round_view.dart +++ b/lib/views/round_view.dart @@ -43,15 +43,17 @@ class _RoundViewState extends State { print('=== Runde ${widget.roundNumber} geöffnet ==='); if (widget.roundNumber < widget.gameSession.roundNumber || widget.gameSession.isGameFinished == true) { - print('Die Runde ${widget.roundNumber} wurde bereits gespielt, deshalb ' - 'werden die alten Punktestaende angezeigt'); + print( + 'Diese wurde bereits gespielt, deshalb werden die alten Punktestaende angezeigt'); // If the current round has already been played, the text fields // are filled with the scores from this round for (int i = 0; i < _scoreControllerList.length; i++) { _scoreControllerList[i].text = - gameSession.playerScores[i][widget.roundNumber].toString(); + gameSession.roundList[widget.roundNumber - 1].scores[i].toString(); } + _kamikazePlayerIndex = + gameSession.roundList[widget.roundNumber - 1].kamikaze; } super.initState(); } @@ -179,7 +181,7 @@ class _RoundViewState extends State { backgroundColor: CupertinoColors.secondaryLabel, title: Row(children: [Text(name)]), subtitle: Text( - '${widget.gameSession.playerScores[index][0]}' + '${widget.gameSession.playerScores[index]}' ' Punkte'), trailing: Row( children: [ @@ -343,7 +345,7 @@ class _RoundViewState extends State { } /// Finishes the current round. - /// Calls the [_calculateScoredPoints()] method to calculate the points for + /// It first determines, ifCalls the [_calculateScoredPoints()] method to calculate the points for /// every player. If the round is the highest round played in this game, /// it expands the player score lists. At the end it updates the score /// array for the game. @@ -351,150 +353,30 @@ class _RoundViewState extends State { print('===================================='); print('Runde ${widget.roundNumber} beendet'); // The shown round is smaller than the newest round - if (widget.gameSession.roundNumber < - widget.gameSession.playerScores[0].length) { + if (widget.roundNumber < widget.gameSession.roundNumber) { print('Da diese Runde bereits gespielt wurde, werden die alten ' 'Punktestaende ueberschrieben'); - print('Alte Punktestaende:'); - print(gameSession.printRoundScores(widget.roundNumber)); } - - _calculateScoredPoints(); - widget.gameSession.sumPoints(); - if (widget.gameSession.isGameFinished == true) { - print('Das Spiel ist beendet'); - } else { - if (widget.roundNumber >= widget.gameSession.playerScores[0].length - 1) { - gameSession.expandPlayerScoreLists(); - print('Das Punkte-Array wurde erweitert'); - } - widget.gameSession.increaseRound(); - } - - print('Die Punktesummen wurden aktualisiert'); - } - - /// Checks the scores of the current round and assigns points to the players. - /// There are three possible outcomes of a round: - /// - /// **Case 1**
- /// One player has Kamikaze. This player receives 0 points. Every other player - /// receives 50 points. - /// - /// **Case 2**
- /// The player who said CABO has the lowest score. They receive 0 points. - /// Every other player gets their round score. - /// - /// **Case 3**
- /// The player who said CABO does not have the lowest score. - /// They receive 5 extra points added to their round score. - /// Every player with the lowest score gets 0 points. - /// Every other player gets their round score. - void _calculateScoredPoints() { - print('Spieler: ${gameSession.players}'); - - // A player has Kamikaze if (_kamikazePlayerIndex != null) { print('${widget.gameSession.players[_kamikazePlayerIndex!]} hat Kamikaze ' 'und bekommt 0 Punkte'); print('Alle anderen Spieler bekommen 50 Punkte'); - _applyKamikaze(_kamikazePlayerIndex!, - List.generate(widget.gameSession.players.length, (index) => 0)); + widget.gameSession + .applyKamikaze(widget.roundNumber, _kamikazePlayerIndex!); } else { - // List of the scores of the current round List roundScores = []; for (TextEditingController c in _scoreControllerList) { if (c.text.isNotEmpty) roundScores.add(int.parse(c.text)); } - - print('Punkte: $roundScores'); - print('${gameSession.players[_caboPlayerIndex]} hat CABO gesagt'); - print('${gameSession.players[_caboPlayerIndex]} hat ' - '${roundScores[_caboPlayerIndex]} Punkte'); - - /// List of the index of the player(s) with the lowest score - List lowestScoreIndex = _getLowestScoreIndex(roundScores); - print('Folgende Spieler haben die niedrigsten Punte:'); - for (int i in lowestScoreIndex) { - print('${widget.gameSession.players[i]} (${roundScores[i]} Punkte)'); - } - // The player who said CABO is one of the players which have the - // fewest points. - if (lowestScoreIndex.contains(_caboPlayerIndex)) { - print('${widget.gameSession.players[_caboPlayerIndex]} hat CABO gesagt ' - 'und bekommt 0 Punkte'); - print('Alle anderen Spieler bekommen ihre Punkte'); - _assignPoints([_caboPlayerIndex], -1, roundScores); - } else { - // A player other than the one who said CABO has the fewest points. - print( - '${widget.gameSession.players[_caboPlayerIndex]} hat CABO gesagt, ' - 'jedoch nicht die wenigsten Punkte.'); - print('Folgende:r Spieler haben die wenigsten Punkte:'); - for (int i in lowestScoreIndex) { - print('${widget.gameSession.players[i]}: ${roundScores[i]} Punkte'); - } - _assignPoints(lowestScoreIndex, _caboPlayerIndex, roundScores); - } + widget.gameSession.calculateScoredPoints( + widget.roundNumber, roundScores, _caboPlayerIndex); } - } - - /// Returns the index of the player with the lowest score. If there are - /// multiple players with the same lowest score, all of them are returned. - /// [roundScores] is a list of the scores of all players in the current round. - List _getLowestScoreIndex(List roundScores) { - int lowestScore = roundScores[0]; - List lowestScoreIndex = [0]; - - for (int i = 1; i < roundScores.length; i++) { - if (roundScores[i] < lowestScore) { - lowestScore = roundScores[i]; - lowestScoreIndex = [i]; - } else if (roundScores[i] == lowestScore) { - lowestScoreIndex.add(i); - } + widget.gameSession.updatePoints(); + if (widget.gameSession.isGameFinished == true) { + print('Das Spiel ist beendet'); + } else if (widget.roundNumber == widget.gameSession.roundNumber) { + widget.gameSession.increaseRound(); } - return lowestScoreIndex; - } - - /// Assigns 50 points to all players except the kamikaze player. - /// [kamikazePlayerIndex] is the index of the kamikaze player. - /// [roundScores] is the list of the scores of all players in the - /// current round. - void _applyKamikaze(int kamikazePlayerIndex, List roundScores) { - for (int i = 0; i < widget.gameSession.players.length; i++) { - if (i != kamikazePlayerIndex) { - roundScores[i] += 50; - } - } - gameSession.addRoundScoresToScoreList(roundScores, widget.roundNumber); - } - - /// Assigns points to the players based on the scores of the current round. - /// [winnerIndex] is the index of the player(s) who receive 0 points - /// [loserIndex] is the index of the player who receives 5 extra points - /// [roundScores] is the raw list of the scores of all players in the - /// current round. - void _assignPoints( - List winnnerIndex, int loserIndex, List roundScores) { - print('Folgende Punkte wurden aus der Runde übernommen:'); - for (int i = 0; i < roundScores.length; i++) { - print('${widget.gameSession.players[i]}: ${roundScores[i]}'); - } - for (int i in winnnerIndex) { - print( - '${widget.gameSession.players[i]} hat gewonnen und bekommt 0 Punkte'); - roundScores[i] = 0; - } - if (loserIndex != -1) { - print('${widget.gameSession.players[loserIndex]} bekommt 5 Fehlerpunkte'); - roundScores[loserIndex] += 5; - } - print('Aktualisierte Punkte:'); - for (int i = 0; i < roundScores.length; i++) { - print('${widget.gameSession.players[i]}: ${roundScores[i]}'); - } - gameSession.addRoundScoresToScoreList(roundScores, widget.roundNumber); } @override