Sorting Variables - Ranked System/Leaderboard

● ARCHIVED · READ-ONLY
Started by burntable 17 posts View original ↗
  1. I'm having a hard time with a ranking system. Basically I'm trying to create a dynamically updated leaderboard. The problem is to give everyones team its proper rank.


    Every team has a variable for the current score and a second variable for the rank. How can I set the rankvariable based on the highest score each team has?


    For better understanding:


    Team 1 has a score of 10 (variable 1 = 10)


    Team 2 has a score of 5 (variable 2 = 5)


    Team 3 has a score of 15 (variable 3 = 15)


    Team 4 has a score of 2 (variable 4 = 2)



    #edit thanks SumRndmDde


    Team 1 is Rank 2 (variable 5 = 2)


    Team 2 is Rank 3 (variable 6 = 3)


    Team 3 is Rank 1 (variable 7 = 1)


    Team 4 is Rank 4 (variable 8 = 4)


    Result:


    Rank   Team      Score


    1         Team 3   15


    2         Team 1   10


    3         Team 2    5


    4         Team 4    2


    I've seen some array sort chenigans in other forums, but can't translate it to be used in MV. Any help would be greatly appreciated!
  2. burntable said:
    Rank 1 is given to Team 3 (variable 5 = 1)


    Rank 2 is given to Team 1 (variable 6 = 2)


    Rank 3 is given to Team 2 (variable 7 = 3)


    Rank 4 is given to Team 4 (variable 8 = 4)



    I'm a little confused about this; I don't see the pattern.


    Shouldn't var 5 have the ID of the team in first place (Team 3)?


    Var 6 has second place, var 7 has third, etc....


    So something like:


    Rank 1 is given to Team 3 (variable 5 = 3)


    Rank 2 is given to Team 1 (variable 6 = 1)


    Rank 3 is given to Team 2 (variable 7 = 2)


    Rank 4 is given to Team 4 (variable 8 = 4)


    or am I just insane?
  3. That's the problem, the game doesn't know the rank yet, only the score. I'm trying to set the variables for the ranks based on the current score.


    Variable 5-8 are the ones for each teams rank.


    variable 5 = Team 1 rank


    variable 6 = Team 2 rank


    etc.


    So the higher the score, the lower the value of these variables (highest score = 1st place)
  4. burntable said:
    That's the problem, the game doesn't know the rank yet, only the score. I'm trying to set the variables for the ranks based on the current score.


    Variable 5-8 are the ones for each teams rank.


    variable 5 = Team 1 rank


    variable 6 = Team 2 rank


    etc.


    So the higher the score, the lower the value of these variables (highest score = 1st place)



    All right, but in your example, variable 5 was set to 1, but team 1's rank was 2.


    So shouldn't it be:


    Rank 1 is given to Team 3 (variable 7 = 1)


    Rank 2 is given to Team 1 (variable 5 = 2)


    Rank 3 is given to Team 2 (variable 6 = 3)


    Rank 4 is given to Team 4 (variable 8 = 4)


    EDIT:


    A better way to put it:


    Team 1 is Rank 2 (variable 5 = 2)


    Team 2 is Rank 3 (variable 6 = 3)


    Team 3 is Rank 1 (variable 7 = 1)


    Team 4 is Rank 4 (variable 8 = 4)
  5. Well you could do this with a single array holding just the scores. The id of each element plus 1 equates to the teams number (because array id's start at 0 or you could start the teams at 0).


    Then the code for sorting the array (courtesy of the Mozilla JavaScript docs) then reverse the array:

    Code:
    var scores = [4, 2, 5, 1, 3];
    scores = scores.sort(function(a, b) {
      return a - b;
    });
    scores = scores.reverse();
    console.log(scores);
    // [5, 4, 3, 2, 1]
  6. SumRndmDde said:
    All right, but in your example, variable 5 was set to 1, but team 1's rank was 2.


    So shouldn't it be:


    Rank 1 is given to Team 3 (variable 7 = 1)


    Rank 2 is given to Team 1 (variable 5 = 2)


    Rank 3 is given to Team 2 (variable 6 = 3)


    Rank 4 is given to Team 4 (variable 8 = 4)


    EDIT:


    A better way to put it:


    Team 1 is Rank 2 (variable 5 = 2)


    Team 2 is Rank 3 (variable 6 = 3)


    Team 3 is Rank 1 (variable 7 = 1)


    Team 4 is Rank 4 (variable 8 = 4)



    Oh yes, you are right. The way you put it is the right one.
  7. Sarlecc said:
    Well you could do this with a single array holding just the scores. The id of each element plus 1 equates to the teams number (because array id's start at 0 or you could start the teams at 0).


    Then the code for sorting the array (courtesy of the Mozilla JavaScript docs) then reverse the array:



    var scores = [4, 2, 5, 1, 3];
    scores = scores.sort(function(a, b) {
    return a - b;
    });
    scores = scores.reverse();
    console.log(scores);
    // [5, 4, 3, 2, 1]

    Sounds great. Thank you ;)


    Is it possible to exchange the elements inside the array with gamevariables?
  8. Awesome, now to solve the problem.


    What I would do:


    function refreshStuff() {

    var v = $gameVariables._data;
    var max, maxId;
    //Var IDs that have already had their value set will be stored here
    var banned = [];

    //Cycles 4 times for each rank.
    for(var i = 1; i <= 4; i++) {
    max = -1; //Assuming there are no scores that are negative
    maxId = 0; //Resets ID of Max Value
    for(var j = 1; j <= 4; j++) {
    //If value is already set, continue through for-loop
    if(banned.indexOf(j) > -1) continue;
    //If the value of the variable is greater than the max, set max value and ID of variable
    if(v[j] > max) {
    max = v[j];
    maxId = j;
    }
    }
    //Set "rank" based on the current loop of the entire for loop
    v[maxId + 4] = i;
    //Ban the ID
    banned.push(maxId);
    }

    }




    I haven't tested it, and it may not be the cleanest way, but this is what I would do. :0
  9. SumRndmDde said:
    Awesome, now to solve the problem.


    What I would do:



    function refreshStuff() {

    var v = $gameVariables._data;
    var max, maxId;
    //Var IDs that have already had their value set will be stored here
    var banned = [];

    //Cycles 4 times for each rank.
    for(var i = 1; i <= 4; i++) {
    max = -1; //Assuming there are no scores that are negative
    maxId = 0; //Resets ID of Max Value
    for(var j = 1; j <= 4; j++) {
    //If value is already set, continue through for-loop
    if(banned.indexOf(j) > -1) continue;
    //If the value of the variable is greater than the max, set max value and ID of variable
    if(v[j] > max) {
    max = v[j];
    maxId = j;
    }
    }
    //Set "rank" based on the current loop of the entire for loop
    v[maxId + 4] = ii;
    //Ban the ID
    banned.push(maxId);
    }

    }




    I haven't tested it, and it may not be the cleanest way, but this is what I would do. :0

     Wow, thank you. That was fast!


    The comments in the code really helps me to understand what's going on!


    I have to test this in my project tomorrow! It's getting really late here! :D
  10. Not sure what you mean by exchange elements. But given a $gameVariable.setValue(1, []) would start an array at the $gameVariable id 1. You can push new elements into the array by $gameVariables.value(1).push(value).


    Edit: oh think I understand now (long day :p)
  11. Sarlecc said:
    Not sure what you mean by exchange elements. But given a $gameVariable.setValue(1, []) would start an array at the $gameVariable id 1. You can push new elements into the array by $gameVariables.value(1).push(value).


    Edit: oh think I understand now (long day :p)



    Haha :D


    I mean using gamevariables instead of the values.


    var scores = [4, 2, 5, 1, 3];




    In my example:


    var scores = [$gameVariable.Value(1), $gameVariable.Value(2), $gameVariable.Value(3), $gameVariable.Value(4)];


    Would that be the proper syntax to store the values of gamevariables 1-4 into the array?


    That push thingy sound great, too. I have to fiddle around with the solution both of you gave me, tomorrow. It's already way too late to wrap my head around it. :o
  12. Well that would be one way of doing it. Then whenever you want to update your values you can just do: scores = [$gameVariable.value(1), $gameVariable.value(2), $gameVariable.value(3), $gameVariable.value(4)];


    And only the values that have changed will then. It may actually keep things fairly simply (as you can make this quite complex hehe). By complex I was preparing a 2D array solution until you posted which would have worked but might be a bit over the top for what you are doing.
  13. Ok. So I tried to use the short suggestion from Scarlecc.


    var scores = [4, 2, 5, 1, 3];
    scores = scores.sort(function(a, b) {
    return a - b;
    });
    scores = scores.reverse();
    console.log(scores);
    // [5, 4, 3, 2, 1]


    Using it in a scriptcall, works. But if I try to put the game variables inside the array....


    var scores = [$gameVariables.Value(19), $gameVariables.Value(39), $gameVariables.Value(59), $gameVariables.Value(79), $gameVariables.Value(99), $gameVariables.Value(119)];
    scores = scores.sort(function(a, b) {
    return a - b;
    });
    scores = scores.reverse();


    ....I get an error: "undefined is not a function". :(


    I haven't tried the script from SumRndmDde, mainly because I don't quite understand how to let the script know, which variables (ID's) I'm using. lol


    In Vx Ace, I used a similar ranking system and got it to work, thanks to this forum and some helpfull people.


    The code I used was:


    @ranking = [$game_variables[7],
    $game_variables[148],
    $game_variables[149],
    $game_variables[150],
    $game_variables[151]]
    @ranking.sort!.reverse!
    $game_variables[154] = @ranking[0]
    $game_variables[155] = @ranking[1]
    $game_variables[156] = @ranking[2]
    $game_variables[157] = @ranking[3]
    $game_variables[158] = @ranking[4]




    Obviously the variable ID's are different, but this worked great, when using it with a scriptcall.


    I'm sorry for being so noobish. :D
  14. You are using .Value() need to use .value(). ;) Very easy mistake to make (its one I even make on occasion).


    Edit and after reading my previous post looks like I made it yesterday too lol. XD
  15. Sarlecc said:
    You are using .Value() need to use .value(). ;) Very easy mistake to make (its one I even make on occasion).


    Edit and after reading my previous post looks like I made it yesterday too lol. XD



    Haha. We also wrote $gameVariable instead of $gameVariables. lol


    It seems to work now.


    But honestly I can't figure out now, how to set the value of the ranking variables.


    They should get the value of the index inside the array we just sorted.


    Team 1 is Rank 2 (variable 5 = 2)


    Team 2 is Rank 3 (variable 6 = 3)


    Team 3 is Rank 1 (variable 7 = 1)


    Team 4 is Rank 4 (variable 8 = 4)


    Do you know, how to do that? :)
  16. Haha yea see how easy it is to miss single characters and think you are still doing it right. :D


    Do you want the value of the index or the index number?


    To get the value of the index:


    $gameVariables.setValue(1, scores[0]) // value of the first index in the scores array


    To get the index value:


    $gameVariables.setValue(1, scores.indexOf($gameVariables.value(19))) // index of the game variable 19 value.


    Example: lets say you had the array:


    [5, 6, 7]


    and you wanted to know the index of the value 6:


    [5, 6, 7].indexOf(6)


    //returns 1
  17. Sarlecc said:
    Haha yea see how easy it is to miss single characters and think you are still doing it right. :D


    Do you want the value of the index or the index number?


    To get the value of the index:


    $gameVariables.setValue(1, scores[0]) // value of the first index in the scores array


    To get the index value:


    $gameVariables.setValue(1, scores.indexOf($gameVariables.value(19))) // index of the game variable 19 value.


    Example: lets say you had the array:


    [5, 6, 7]


    and you wanted to know the index of the value 6:


    [5, 6, 7].indexOf(6)


    //returns 1

    Perfect! Thank you so much!


    I needed the index value (I guess). The script call looks like this now:


    var scores = [$gameVariables.value(19), $gameVariables.value(39), $gameVariables.value(59), $gameVariables.value(79), $gameVariables.value(99), $gameVariables.value(119)];
    scores = scores.sort(function(a, b) {
    return a - b;
    });
    scores = scores.reverse();
    $gameVariables.setValue(9, scores.indexOf($gameVariables.value(19))+1)
    $gameVariables.setValue(29, scores.indexOf($gameVariables.value(39))+1)
    $gameVariables.setValue(49, scores.indexOf($gameVariables.value(59))+1)
    $gameVariables.setValue(69, scores.indexOf($gameVariables.value(79))+1)
    $gameVariables.setValue(89, scores.indexOf($gameVariables.value(119))+1)


    And it works flawlessly!