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!
Sorting Variables - Ranked System/Leaderboard
● ARCHIVED · READ-ONLY
-
-
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? -
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) -
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) -
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] -
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. -
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? -
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 -
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 -
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) -
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 -
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. -
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 -
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 -
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? :) -
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 -
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!