Merge pull request #112 from flixcoo/bug/108-two-players-on-the-same-rank

Two players on the same rank
This commit is contained in:
2025-07-14 11:42:20 +02:00
committed by GitHub
2 changed files with 43 additions and 26 deletions

View File

@@ -20,6 +20,8 @@ class ActiveGameView extends StatefulWidget {
class _ActiveGameViewState extends State<ActiveGameView> { class _ActiveGameViewState extends State<ActiveGameView> {
late final GameSession gameSession; late final GameSession gameSession;
late List<int> denseRanks;
late List<int> sortedPlayerIndices;
@override @override
void initState() { void initState() {
@@ -32,7 +34,9 @@ class _ActiveGameViewState extends State<ActiveGameView> {
return ListenableBuilder( return ListenableBuilder(
listenable: gameSession, listenable: gameSession,
builder: (context, _) { builder: (context, _) {
List<int> sortedPlayerIndices = _getSortedPlayerIndices(); sortedPlayerIndices = _getSortedPlayerIndices();
denseRanks = _calculateDenseRank(
gameSession.playerScores, sortedPlayerIndices);
return CupertinoPageScaffold( return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar( navigationBar: CupertinoNavigationBar(
middle: Text(gameSession.gameTitle), middle: Text(gameSession.gameTitle),
@@ -58,7 +62,7 @@ class _ActiveGameViewState extends State<ActiveGameView> {
return CupertinoListTile( return CupertinoListTile(
title: Row( title: Row(
children: [ children: [
_getPlacementPrefix(index), _getPlacementTextWidget(index),
const SizedBox(width: 5), const SizedBox(width: 5),
Text( Text(
gameSession.players[playerIndex], gameSession.players[playerIndex],
@@ -266,39 +270,50 @@ class _ActiveGameViewState extends State<ActiveGameView> {
playerIndices.sort((a, b) { playerIndices.sort((a, b) {
int scoreA = gameSession.playerScores[a]; int scoreA = gameSession.playerScores[a];
int scoreB = gameSession.playerScores[b]; int scoreB = gameSession.playerScores[b];
return scoreA.compareTo(scoreB); if (scoreA != scoreB) {
return scoreA.compareTo(scoreB);
}
return a.compareTo(b);
}); });
return playerIndices; return playerIndices;
} }
/// Returns a widget that displays the placement prefix based on the index. /// Calculates the dense rank for a player based on their index in the sorted list of players.
/// First three places are represented by medals, and the rest are numbered. List<int> _calculateDenseRank(
/// [index] is the index of the player in the descending sorted list. List<int> playerScores, List<int> sortedIndices) {
Widget _getPlacementPrefix(int index) { List<int> denseRanks = [];
switch (index) { int rank = 1;
case 0: for (int i = 0; i < sortedIndices.length; i++) {
return const Text( if (i > 0) {
'\u{1F947}', int prevScore = playerScores[sortedIndices[i - 1]];
style: TextStyle(fontSize: 22), 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: case 1:
return const Text( return const Text('\u{1F947}', style: TextStyle(fontSize: 22)); // 🥇
'\u{1F948}',
style: TextStyle(fontSize: 22),
);
case 2: case 2:
return const Text( return const Text('\u{1F948}', style: TextStyle(fontSize: 22)); // 🥈
'\u{1F949}', case 3:
style: TextStyle(fontSize: 22), return const Text('\u{1F949}', style: TextStyle(fontSize: 22)); // 🥉
);
default: default:
return Text( return Text(' $placement.',
' ${index + 1}.', style: const TextStyle(fontWeight: FontWeight.bold));
style: const TextStyle(fontWeight: FontWeight.bold),
);
} }
} }
/// Shows a dialog to confirm deleting the game session.
Future<bool> _showDeleteGameDialog() async { Future<bool> _showDeleteGameDialog() async {
return await showCupertinoDialog<bool>( return await showCupertinoDialog<bool>(
context: context, context: context,
@@ -331,6 +346,8 @@ class _ActiveGameViewState extends State<ActiveGameView> {
false; 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<void> _removeGameSession(GameSession gameSession) async { Future<void> _removeGameSession(GameSession gameSession) async {
if (gameManager.gameExistsInGameList(gameSession.id)) { if (gameManager.gameExistsInGameList(gameSession.id)) {
Navigator.pop(context); Navigator.pop(context);

View File

@@ -2,7 +2,7 @@ name: cabo_counter
description: "Mobile app for the card game Cabo" description: "Mobile app for the card game Cabo"
publish_to: 'none' publish_to: 'none'
version: 0.4.5+494 version: 0.4.6+504
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4