From 68477158e5768519f59a58788c7e2e54f1931b2f Mon Sep 17 00:00:00 2001 From: Felix Kirchner Date: Sun, 13 Jul 2025 23:57:15 +0200 Subject: [PATCH] Implemented bonus popup --- lib/data/game_session.dart | 11 +++-- lib/presentation/views/round_view.dart | 65 +++++++++++++++++++++++--- pubspec.yaml | 2 +- test/data/game_session_test.dart | 12 ++--- 4 files changed, 74 insertions(+), 16 deletions(-) diff --git a/lib/data/game_session.dart b/lib/data/game_session.dart index d40e105..54c095b 100644 --- a/lib/data/game_session.dart +++ b/lib/data/game_session.dart @@ -243,10 +243,11 @@ class GameSession extends ChangeNotifier { /// 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. - Future updatePoints() async { + List updatePoints() { + List bonusPlayers = []; _sumPoints(); if (isPointsLimitEnabled) { - _checkHundredPointsReached(); + bonusPlayers = _checkHundredPointsReached(); for (int i = 0; i < playerScores.length; i++) { if (playerScores[i] > pointLimit) { @@ -258,6 +259,7 @@ class GameSession extends ChangeNotifier { } } notifyListeners(); + return bonusPlayers; } @visibleForTesting @@ -278,15 +280,18 @@ class GameSession extends ChangeNotifier { /// 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() { + List _checkHundredPointsReached() { + List bonusPlayers = []; for (int i = 0; i < players.length; i++) { if (playerScores[i] == pointLimit) { + bonusPlayers.add(i); print('${players[i]} hat genau 100 Punkte erreicht und bekommt ' 'deswegen ${(pointLimit / 2).round()} Punkte abgezogen'); roundList[roundNumber - 1].scoreUpdates[i] -= (pointLimit / 2).round(); } } _sumPoints(); + return bonusPlayers; } /// Determines the winner of the game session. diff --git a/lib/presentation/views/round_view.dart b/lib/presentation/views/round_view.dart index 39e5cc8..602c702 100644 --- a/lib/presentation/views/round_view.dart +++ b/lib/presentation/views/round_view.dart @@ -287,8 +287,11 @@ class _RoundViewState extends State { children: [ CupertinoButton( onPressed: _areRoundInputsValid() - ? () { - _finishRound(); + ? () async { + List boni = _finishRound(); + if (boni.isNotEmpty) { + await _showBonusPopup(context, boni); + } LocalStorageService.saveGameSessions(); Navigator.pop(context); } @@ -298,8 +301,11 @@ class _RoundViewState extends State { if (!widget.gameSession.isGameFinished) CupertinoButton( onPressed: _areRoundInputsValid() - ? () { - _finishRound(); + ? () async { + List boni = _finishRound(); + if (boni.isNotEmpty) { + await _showBonusPopup(context, boni); + } LocalStorageService.saveGameSessions(); if (widget.gameSession.isGameFinished) { Navigator.pop(context); @@ -359,7 +365,7 @@ class _RoundViewState extends State { /// 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. - void _finishRound() { + List _finishRound() { print('===================================='); print('Runde ${widget.roundNumber} beendet'); // The shown round is smaller than the newest round @@ -381,12 +387,59 @@ class _RoundViewState extends State { widget.gameSession.calculateScoredPoints( widget.roundNumber, roundScores, _caboPlayerIndex); } - widget.gameSession.updatePoints(); + List bonusPlayers = widget.gameSession.updatePoints(); if (widget.gameSession.isGameFinished == true) { print('Das Spiel ist beendet'); } else if (widget.roundNumber == widget.gameSession.roundNumber) { widget.gameSession.increaseRound(); } + return bonusPlayers; + } + + /// Shows a popup dialog with the bonus information. + Future _showBonusPopup( + BuildContext context, List bonusPlayers) async { + print('Bonus Popup wird angezeigt'); + int pointLimit = widget.gameSession.pointLimit; + int bonusPoints = (pointLimit / 2).round(); + + String resultText = _getPopupString(pointLimit, bonusPoints, bonusPlayers); + + await showCupertinoDialog( + context: context, + builder: (context) => CupertinoAlertDialog( + title: const Text('Bonus!'), + content: Text(resultText), + actions: [ + CupertinoDialogAction( + child: const Text('OK'), + onPressed: () => Navigator.of(context).pop(true), + ), + ], + ), + ); + return true; + } + + /// Generates the string for the bonus popup. + /// It takes the [pointLimit], [bonusPoints] and the list of [bonusPlayers] + /// and returns a formatted string. + String _getPopupString( + int pointLimit, int bonusPoints, List bonusPlayers) { + List nameList = + bonusPlayers.map((i) => widget.gameSession.players[i]).toList(); + String resultText = ''; + if (nameList.length == 1) { + resultText = + '${nameList.first} hat exakt das Punktelimit von $pointLimit Punkten erreicht und bekommt deshalb $bonusPoints Punkte abgezogen!'; + } else { + resultText = nameList.length == 2 + ? '${nameList[0]} & ${nameList[1]}' + : '${nameList.sublist(0, nameList.length - 1).join(', ')} & ${nameList.last}'; + resultText += + ' haben exakt das Punktelimit von $pointLimit Punkten erreicht und bekommen deshalb $bonusPoints Punkte abgezogen!'; + } + return resultText; } @override diff --git a/pubspec.yaml b/pubspec.yaml index 7946bbb..f2b4949 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: cabo_counter description: "Mobile app for the card game Cabo" publish_to: 'none' -version: 0.4.4+486 +version: 0.4.4+488 environment: sdk: ^3.5.4 diff --git a/test/data/game_session_test.dart b/test/data/game_session_test.dart index de4e284..4ca2158 100644 --- a/test/data/game_session_test.dart +++ b/test/data/game_session_test.dart @@ -114,15 +114,15 @@ void main() { expect(session.roundList[0].caboPlayerIndex, 0); }); - test('updatePoints - game not finished', () async { + test('updatePoints - game not finished', () { session.addRoundScoresToList(1, [10, 20, 30], [10, 20, 30], 0); - await session.updatePoints(); + session.updatePoints(); expect(session.isGameFinished, isFalse); }); - test('updatePoints - game finished', () async { + test('updatePoints - game finished', () { session.addRoundScoresToList(1, [101, 20, 30], [101, 20, 30], 0); - await session.updatePoints(); + session.updatePoints(); expect(session.isGameFinished, isTrue); }); @@ -154,9 +154,9 @@ void main() { expect(session.playerScores, equals([50, 0, 30])); }); - test('_setWinner via updatePoints', () async { + test('_setWinner via updatePoints', () { session.addRoundScoresToList(1, [101, 20, 30], [101, 0, 30], 1); - await session.updatePoints(); + session.updatePoints(); expect(session.winner, 'Bob'); // Bob has lowest score (20) }); });