Author Topic: ordering a list from greatest to least  (Read 1942 times)

Im trying to make a rank system that shows the player what rank they are in the server (based on score)

i have a bunch of variables like $Pref::INF::playerData::score[%blid] = 1000; assigned to different values, and I want to order every variable from greatest to least by value, so that someone with the score 100000000000 will be rank 1, and someone with score 5 will be rank 409

a really dumb sorting trick is to use a guitextlistctrl and then use sortNumerical(column, increasing=false)

this ref uses alphabetical sort but the idea is the same
https://forum.blockland.us/index.php?topic=234486.msg6666280#msg6666280

if you need to store the BL_ID associated with the score, then you can add rows in a format like SCORE\tBL_ID and then do sortNumerical(0) so it's sorting by the first column

the only thing that might make this difficult for you is that you have to somehow index all the BL_IDs that actually have scores associated with them to do any kind of sorting, otherwise you can't really do this unless you were insane and just looped through every number from 0 to 999999 a bunch of times, which is a really bad idea.

For a rank list, the problem really isn't sorting it once, but keeping it sorted as scores change.

You'll need some kind of index of the blids, like $Pref::INF::bl_id[%i]
But now, if you need to add a score to the middle of this list, you have to shift all following ones up by one.

How big do you expect this rank list to get?

How big do you expect this rank list to get?
possibly 500 members

you may want to look into implementing quicksort then

edit: if you need to have a total list in order that is. zeblote's correction is accurate unless your list is randomly arranged initially on creation, but thats probably never the case if you save your vars as is
« Last Edit: August 18, 2016, 11:48:36 AM by Conan »

you may want to look into implementing quicksort then

You're likely not going to sort a rank list like this, it will instead stay sorted as ranks are added. Quick sort doesn't help with that.

Just write a quick external program to do the sorting for you. Torquescript is just..... yeah..

Just write a quick external program to do the sorting for you. Torquescript is just..... yeah..
and... how do I run this application automatically every time someone joins?

and... how do I run this application automatically every time someone joins?
i'm guessing elm is joking because it's a kinda silly suggestion for sorting, it's possible to do what he says but it's obviously not worth it to outsource simple rank sorting to an external program

what zeblote is suggesting is that you just make sure someone's rank is still correct when their score changes. if the person above them has a lower score, make them swap places, same with if the person below has a higher score. just repeat that until their rank is correct. that's a pretty good solution, you just need an index of all the bl_ids like he was saying

I believe due to the potentially high number of elements and possible high variation of them, you should implement Quicksort for this.


Edit: Since you will be re-ordering the list that is already potentially sorted, selecting first index will yield the worst-case-scenario of O(n^2) and it's inefficient to get the median of a very long list, you should use the 'median-of-three' method as described in the wikipedia article.
Quote
choosing the median of the first, middle and last element of the partition for the pivot
« Last Edit: August 19, 2016, 10:09:36 AM by Dannu »

Here's an example of sorting scores and client objects based on score.

Code: [Select]
//Makes an array of sorted scores and an array of clients sorted by score (the last element in the sorted array has the greatest score)

for( %i = $DefaultMinigame.numMembers; %i >= 0; %i-- )  
{  
for( %j = 1; %j <= %i; %j++ )  
{  
                %cl1 = $DefaultMinigame.member[%j-1];
                %cl2 = $DefaultMinigame.member[%j-2];

if( %cl2.score > %cl1.score )  
{    
%sortedScores[%j-1] = %cl1.score;
%sortedScores[%j] = %cl2.score;
                        
                       %sortedClientObj[%j-1] = %cl1;
                       %sortedClientObj[%j-1] = %cl2;
}  

}  
}
« Last Edit: August 21, 2016, 06:50:12 PM by Farad »

farad's sorting algorithim is bubble sort, which has a worst case sort time of n^2 where n is the length of the list. use only if the set is mostly ordered every time sorting is run

farad's sorting algorithim is bubble sort, which has a worst case sort time of n^2 where n is the length of the list. use only if the set is mostly ordered every time sorting is run
It's also the best sorting algorithm if it's already sorted :^)

It's also the best sorting algorithm if it's already sorted :^)
Not if
Since you will be re-ordering the list that is already potentially sorted, selecting first index will yield the worst-case-scenario of O(n^2) and it's inefficient to get the median of a very long list, you should use the 'median-of-three' method as described in the wikipedia article.

Not if
Wait, do you not know that Bubble Sort is the best sort for an already sorted list?
Or are you just spitting out random info that you have no idea about?