Calculate Leaderboard Ranking in Flutter

Viewed 981

I'm creating a 2D game in flutter, Using firebase as a backend service. How I can calculate user's rank according to their score. Currently, I'm getting their rank by using the index, But if two or more users have an equal score then how I can show them the same ranking position. Here is the code:

StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance
            .collection('teams')
            .orderBy('points', descending: true)
            .snapshots(),
        builder: (context, snapshot) {
          return ListView.builder(
              itemCount: snapshot.data.docs.length,
              itemBuilder: (context, index) {
                return Container(
                  child:   Text('Rank ${index +1}'),
                );
              });
        },
      ),
1 Answers

This might work: just count number of elements with higher score. I also added _denseRank function, if you want to show it that way (e.g. ranks would go 1,2,2,3,3 etc.). This one just counts number of unique elements with higher score - toSet() is used to remove duplicates - i.e. get unique values.

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  }
}

class MyWidget extends StatelessWidget {
  
  final a=<int>[10,9,9,8,8,4,4];
  
    
  int _rank(int index) => a.where( (element) => element>a[index]).length+1;
  
  int _denseRank(int index) => a.where( (element) => element>a[index]).toSet().length+1;
  
  
  
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      for (var index=0; index<a.length;index++) Row(children: <Widget>[Text('Index $index'), Text('Rank ${_rank(index)}'), Text('Dense Rank ${_denseRank(index)}')])
    ]);
  }
}



Related