How to design an algorithm for leadboard system?

Issue

I’m developing a basic android app with Kotlin and Firebase. It’s like flappy bird. I upload all the player data to firebase(firestore). And now I need to find an algorithm for creating a leadboard system. Basically I have highscore values made by different users at different diffuculties. I upload these values to firestore and retrieve them after in TopPlayersActivity And this is how layout looks, I have 3 different recyclerViews:

enter image description here

I made everything about adapters etc. And now I need to show the datas from Firebase. For example :

enter image description here

I could show highscores made in easy difficulty in a descending order but don’t know how to show usernames with them. I’ve tried to do it with hashMap like this:

val userScoreMap =  hashMapOf<String,Int>()
userScoreMap.put(username,easyScore)

But couldn’t show it with score.

Here is my full code of retrieving data and processing it:

 db.collection("gamevalues")
        .get()
        .addOnSuccessListener { result ->
            for (document in result) {   
                userIdfromFB = document.id
                username = document.get("username").toString()
                easyScore = document.get("easyScore").toString().toInt()
                mediumScore = document.get("mediumScore").toString().toInt()
                hardScore = document.get("hardScore").toString().toInt()
                easyArrayList.add(easyScore)
                mediumArrayList.add(mediumScore)
                hardArrayList.add(hardScore)
                easyArrayList.sortDescending()
                //val userScoreMap =  hashMapOf<String,Int>()
                //userScoreMap.put(username,easyScore) //this is what I tried to do.
        
                topEasyPlayersAdapter = TopEasyPlayersAdapter(easyArrayList) //I'm sending only scores.
                binding.easyRecyclerView.adapter = topEasyPlayersAdapter     

Here is code of TopEasyPlayersAdapter:

class TopEasyPlayersAdapter(val scoreList : ArrayList<Int>) : RecyclerView.Adapter<TopEasyPlayersAdapter.TopEasyPlayerHolder>() {

private lateinit var auth : FirebaseAuth
val db = Firebase.firestore

class TopEasyPlayerHolder(val binding : TopEasyPlayersRecyclerRowBinding):RecyclerView.ViewHolder(binding.root)

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopEasyPlayerHolder {
    val binding = TopEasyPlayersRecyclerRowBinding.inflate(LayoutInflater.from(parent.context),parent,false)
    return TopEasyPlayerHolder(binding)
}

override fun onBindViewHolder(holder: TopEasyPlayerHolder, position: Int) {
    holder.binding.playerNameText.text = "${scoreList.get(position)}"
}

override fun getItemCount(): Int {
    return scoreList.size
}

}

How can I show usernames with scores belong to them?

Here is the database structure from firestore:

enter image description here

Edit: Added database structure.

Solution

easyArrayList.add(easyScore)
mediumArrayList.add(easyScore)
...

You’re using an int array to keep track of all scores. Instead, use an array of pairs to hold the usernames as well.

easyArrayList.add(Pair(easyScore, username))
mediumArrayList.add(Pair(easyScore, username))
...

After sorting the array, when you access each element, you can simply do element.first to get the score and element.second to get the username.

Edit:

Simple way to sort an array of pairs:

fun main() {
    val list = listOf<Pair<Int, String>>(
             Pair<Int, String>(1, "ABC"),
             Pair<Int, String>(2, "DEF"),
             Pair<Int, String>(3, "GHI"),
         )
    var pairList = list.sortedWith(compareBy({ it.first })).asReversed()
    println(pairList) // prints [(3, GHI), (2, DEF), (1, ABC)]
}

Answered By – Abhinav Mathur

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published