diff --git a/lib/presentation/views/active_game_view.dart b/lib/presentation/views/active_game_view.dart index 704952a..ab07804 100644 --- a/lib/presentation/views/active_game_view.dart +++ b/lib/presentation/views/active_game_view.dart @@ -20,6 +20,8 @@ class ActiveGameView extends StatefulWidget { class _ActiveGameViewState extends State { late final GameSession gameSession; + late List denseRanks; + late List sortedPlayerIndices; @override void initState() { @@ -32,7 +34,9 @@ class _ActiveGameViewState extends State { return ListenableBuilder( listenable: gameSession, builder: (context, _) { - List sortedPlayerIndices = _getSortedPlayerIndices(); + sortedPlayerIndices = _getSortedPlayerIndices(); + denseRanks = _calculateDenseRank( + gameSession.playerScores, sortedPlayerIndices); return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text(gameSession.gameTitle), @@ -58,7 +62,7 @@ class _ActiveGameViewState extends State { return CupertinoListTile( title: Row( children: [ - _getPlacementPrefix(index), + _getPlacementTextWidget(index), const SizedBox(width: 5), Text( gameSession.players[playerIndex], @@ -266,39 +270,50 @@ class _ActiveGameViewState extends State { playerIndices.sort((a, b) { int scoreA = gameSession.playerScores[a]; int scoreB = gameSession.playerScores[b]; - return scoreA.compareTo(scoreB); + if (scoreA != scoreB) { + return scoreA.compareTo(scoreB); + } + return a.compareTo(b); }); return playerIndices; } - /// Returns a widget that displays the placement prefix based on the index. - /// First three places are represented by medals, and the rest are numbered. - /// [index] is the index of the player in the descending sorted list. - Widget _getPlacementPrefix(int index) { - switch (index) { - case 0: - return const Text( - '\u{1F947}', - style: TextStyle(fontSize: 22), - ); + /// Calculates the dense rank for a player based on their index in the sorted list of players. + List _calculateDenseRank( + List playerScores, List sortedIndices) { + List denseRanks = []; + int rank = 1; + for (int i = 0; i < sortedIndices.length; i++) { + if (i > 0) { + int prevScore = playerScores[sortedIndices[i - 1]]; + int currScore = playerScores[sortedIndices[i]]; + if (currScore != prevScore) { + rank++; + } + } + denseRanks.add(rank); + } + return denseRanks; + } + + /// Returns a text widget representing the placement text based on the given placement number. + /// [index] is the index of the player in [players] list, + Text _getPlacementTextWidget(int index) { + int placement = denseRanks[index]; + switch (placement) { case 1: - return const Text( - '\u{1F948}', - style: TextStyle(fontSize: 22), - ); + return const Text('\u{1F947}', style: TextStyle(fontSize: 22)); // 🥇 case 2: - return const Text( - '\u{1F949}', - style: TextStyle(fontSize: 22), - ); + return const Text('\u{1F948}', style: TextStyle(fontSize: 22)); // 🥈 + case 3: + return const Text('\u{1F949}', style: TextStyle(fontSize: 22)); // 🥉 default: - return Text( - ' ${index + 1}.', - style: const TextStyle(fontWeight: FontWeight.bold), - ); + return Text(' $placement.', + style: const TextStyle(fontWeight: FontWeight.bold)); } } + /// Shows a dialog to confirm deleting the game session. Future _showDeleteGameDialog() async { return await showCupertinoDialog( context: context, @@ -331,6 +346,8 @@ class _ActiveGameViewState extends State { false; } + /// Removes the game session in the game manager and navigates back to the previous screen. + /// If the game session does not exist in the game list, it shows an error dialog. Future _removeGameSession(GameSession gameSession) async { if (gameManager.gameExistsInGameList(gameSession.id)) { Navigator.pop(context); diff --git a/pubspec.yaml b/pubspec.yaml index 9db5d4b..95fea1d 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.5+494 +version: 0.4.6+504 environment: sdk: ^3.5.4