GameSparks: AroundValueLeaderboardRequest? (II)



Finally I got a preliminary version that loops to refine the search:

//Retrieve the input parameters
var lbShortCode     = Spark.getData().lbShortCode;  //leaderboard identifier
var fieldName       = Spark.getData().fieldName;    //name of the field we are posting to the leaderboard
var fieldValue      = Spark.getData().fieldValue;   //we are looking for a player with that value posted
var numIterations   = Spark.getData().numIterations;//number of iterations to try to improve the result

var request                     = new SparkRequests.AroundMeLeaderboardRequest();
request.entryCount              = 1; //This is the minimum: my preceding enemy, me and the next enemy
request.includeFirst            = 1; //To bound the search in the upper limit
request.includeLast             = 1; //Same for the lower limit
request.leaderboardShortCode    = lbShortCode;

var response            = request.Send();
var firstInLeaderboard  = response.first;
var lastInLeaderboard   = response.last;

var myScore     = 0;
var myRank      = 0;
var currentRank = 0;
var currentScore= 0;
var targetScore = fieldValue;
var bestScore   = firstInLeaderboard[0][fieldName]; //first is an array with a 'lonely' value
var worstScore  = lastInLeaderboard[0][fieldName];  //same than above
var worstRank   = lastInLeaderboard[0]["rank"];

//We will receive 3 values unless there aren't any people before or after me
//...or if the leaderboard is empty
if (response.data.length > 1)
{
    myScore = response.data[1][fieldName];
    myRank  = response.data[1]["rank"];
}
else
{
    myScore = response.data[0][fieldName];
    myRank  = response.data[0]["rank"];
}

var loops       = 0;
var topScore    = bestScore;
var bottomScore = myScore;
var topRank     = 1;
var bottomRank  = myRank;
var done        = false;
var response    = null;

while (loops < numIterations && !done)
{
    var rankDiff    = bottomRank - topRank;
    var scoreDiff   = topScore - bottomScore;
  
    if (rankDiff == 0 || scoreDiff == 0)
    {
        //there is no difference, our search has finished
        targetRank = topRank;
        done = true;
    }
    else
    {
        var scorePointsPerRankPosition = scoreDiff / rankDiff;
      
        if (scorePointsPerRankPosition <= 0) //I'm the best (or even better)
            scorePointsPerRankPosition = 1;
      
        var rankMovement = (topScore - targetScore) / scorePointsPerRankPosition;
        var targetRank = topRank;
      
        if (rankMovement < 1)
        {
            done = true;
        }
        else
        {
            targetRank = topRank + rankMovement;
        }
        
        if (targetRank > worstRank || targetScore < worstScore)
        {
            targetRank = worstRank;
            done = true;
        }
    }
  
    var request = new SparkRequests.LeaderboardDataRequest();
    request.entryCount = 1;
    request.leaderboardShortCode = lbShortCode;
    request.offset = targetRank - 1;
  
    response        = request.Send();
    currentRank     = response.data[0]["rank"];
    currentScore    = response.data[0][fieldName];
  
    if (currentScore < targetScore)
    {
        //as we didn't reach the desired score we will limit the search
        //raising the bottom limit
        bottomScore = currentScore;
        bottomRank  = currentRank;
    }
    else if (currentScore > targetScore)
    {
        //as we didn't reach the desired score we will limit the search
        //raising the bottom limit
        topScore    = currentScore;
        topRank     = currentRank;
    }
    else
    {
        done = true;
    }
  
    if (done)
        break;

    ++loops;
}

Spark.setScriptData("leaderboardData", response.data[0]);

I hope you will find it useful or, at least, interesting.

You can check for more stuff in my programming blog:

http://davidorejuela.blogspot.com.es/

Comentarios

Entradas populares