How to get the rank of a score you just posted to GameCenter? - game-center

is there a way to get the player's score rank he's just posted even if the score is not his best?
[GKScore reportScoreWithCompletionHandler:] is used to post score to GameCenter, but its 'rank' is always zero. the 'rank' value only valid when calling [GKLeaderboard loadScoresWithCompletionHandler:], but its the rank of player's best score today/week/alltime.
the best place would be [GKScore reportScoreWithCompletionHandler:], make the 'rank' value valid when it returns from gamecenter.
thank you.

AFIK there's no such solutions.
GameCenter stores player's best score only.
Read this
So, if you really want to do that, you have to rank the player by your self.
Retrieve all scores from the leader board.
Check the rank of the current score.
-Sample codes below
-(void) findRankWithScore: (int64_t)score
{
GKLeaderboard *leaderboard = [[GKLeaderboard alloc] init];
if (leaderboard != nil) {
leaderboard.category = #"YourCategory";
leaderboard.timeScope = GKLeaderboardTimeScopeWeek; //or all time, day... pick one.
[leaderboard loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) {
int rank = 0;
if (error == nil && scores != nil) {
for (GKScore* refScore in scores) {
//NOTE: Retrieved score array is sorted already.
if (refScore.value <= score) {
rank = refScore.rank - 1;
if (rank < 1) {
rank = 1;
}
break;
}
}
//show the rank to player. using delegate, notification, popups etc...
}else {
//handle errors
}
}];
}
}
In addition, it cost a lot to retrieving all the scores from GameCenter for each rank findings.
So, I recommend you to store the score array and reuse it, even though it make a bit of sacrifice of your ranking accuracy.
(And refresh the score array in some time interval or something like that)

Related

Actionscript 3 error 1176 : Comparison between a value with static type Function and a possibly unrelated type int

I want to make coding about the final score display. If someone has done 10 multiple choice questions and he clicks on the final score button, then his final score will appear along with the description. The score will be made in a range according to the category, namely 1-59 = Under Average, 60-79 = Average, and 80-100 = Above Average.
I've tried coding it but I found error 1176 on line 7 and 11.
Can you help me fix it?
finalscorebutton.addEventListener(MouseEvent.CLICK, finalscore);
function finalscore(event:MouseEvent):void
{
multiplechoicefinalscore.text = sumofscores;
var finalscore:String = finalscore.toString;
finalscore = multiplechoicefinalscore..text;
if(finalscore.toString < 60){
description.text =
"UNDER AVERAGE.";
}
else if(finalscore.toString >= 60 && finalscore.toString <=79){
description.text =
"AVERAGE.";
}
else{
description.text =
"ABOVE AVERAGE.";
}
}
There are multiple syntax and logic errors.
Something.toString is a reference to a method, you probably mean Something.toString() which calls the said method and returns a text representation of whatever Something is.
You don't need a text representation because you want to compare numbers, you need a numeric representation (which is either int, uint or Number).
There are 2 dots in multiplechoicefinalscore..text, what does it even mean?
There is function finalscore and then you define var finalscore, defining things with the same names is a bad idea in general.
You should keep your script formatted properly, otherwise reading it and understanding would be a pain.
So, I assume you have the user's result is in sumofscores. I'm not sure if the script below will actually work as is, but at least it is logically and syntactically correct:
finalscorebutton.addEventListener(MouseEvent.CLICK, onFinal);
function onFinal(e:MouseEvent):void
{
// Ok, let's keep this one, I think you are putting
// the score result into some kind of TextField.
multiplechoicefinalscore.text = sumofscores;
// Get a definitely numeric representation of the score.
var aScore:int = int(sumofscores);
// In terms of logic, putting the complicated condition case
// under the "else" statement will simplify the program.
if (aScore < 60)
{
description.text = "UNDER AVERAGE.";
}
else if (aScore > 79)
{
description.text = "ABOVE AVERAGE.";
}
else
{
description.text = "AVERAGE.";
}
}

I cannot find out why this code keeps skipping a loop

Some background on what is going on:
We are processing addresses into standardized forms, this is the code to take addresses scored by how many components found and then rescore them using a levenshtein algorithm across similar post codes
The scores are how many components were found in that address divided by the number missed, to return a ratio
The input data, scoreDict, is a dictionary containing arrays of arrays. The first set of arrays is the scores, so there are 12 arrays because there are 12 scores in this file (it adjusts by file). There are then however many addresses fit that score in their own separate arrays stored in that. Don't ask me why I'm doing it that way, my brain is dead
The code correctly goes through each score array and each one is properly filled with the unique elements that make it up. It is not short by any amount, nothing is duplicated, I have checked
When we hit the score that is -1 (this goes to any address where it doesn't fit in some rule so we can't use its post code to find components so no components are found) the loop specifically ONLY DOES EVERY OTHER ADDRESS IN THIS SCORE ARRAY
It doesn't do this to any other score array, I have checked
I have tried changing the number to something else like 99, same issue except one LESS address got rescored, and the rest stayed at the original failing score of 99
I am going insane, can anyone find where in this loop something may be going wrong to cause it to only do every other line. The index counter of line and sc come through in the correct order and do not skip over. I have checked
I am sorry this is not professional, I have been at this one loop for 5 hours
Rescore: function Rescore(scoreDict) {
let tempInc = 0;
//Loop through all scores stored in scoreDict
for (var line in scoreDict) {
let addUpdate = "";
//Loop through each line stored by score
for (var sc in scoreDict[line.toString()]) {
console.log(scoreDict[line.toString()].length);
let possCodes = new Array();
const curLine = scoreDict[line.toString()][sc];
console.log(sc);
const curScore = curLine[1].split(',')[curLine[1].split(',').length-1];
switch (true) {
case curScore == -1:
let postCode = (new RegExp('([A-PR-UWYZ][A-HK-Y]?[0-9][A-Z0-9]?[ ]?[0-9][ABD-HJLNP-UW-Z]{2})', 'i')).exec(curLine[1].replace(/\\n/g, ','));
let areaCode;
//if (curLine.split(',')[curLine.split(',').length-2].includes("REFERENCE")) {
if ((postCode = (new RegExp('(([A-Z][A-Z]?[0-9][A-Z0-9]?(?=[ ]?[0-9][A-Z]{2}))|[0-9]{5})', 'i').exec(postCode))) !== null) {
for (const code in Object.keys(addProper)) {
leven.LoadWords(postCode[0], Object.keys(addProper)[code]);
if (leven.distance < 2) {
//Weight will have adjustment algorithms based on other factors
let weight = 1;
//Add all codes that are close to the same to a temp array
possCodes.push(postCode.input.replace(postCode[0], Object.keys(addProper)[code]).split(',')[0] + "(|W|)" + (leven.distance/weight));
}
}
let highScore = 0;
let candidates = new Array();
//Use the component script from cityprocess to rescore
for (var i=0;i<possCodes.length;i++) {
postValid.add([curLine[1].split(',').slice(0,curLine[1].split(',').length-2) + '(|S|)' + possCodes[i].split("(|W|)")[0]]);
if (postValid.addChunk[0].split('(|S|)')[postValid.addChunk[0].split('(|S|)').length-1] > highScore) {
candidates = new Array();
highScore = postValid.addChunk[0].split('(|S|)')[postValid.addChunk[0].split('(|S|)').length-1];
candidates.push(postValid.addChunk[0]);
} else if (postValid.addChunk[0].split('(|S|)')[postValid.addChunk[0].split('(|S|)').length-1] == highScore) {
candidates.push(postValid.addChunk[0]);
}
}
score.Rescore(curLine, sc, candidates[0]);
}
//} else if (curLine.split(',')[curLine.split(',').length-2].contains("AREA")) {
// leven.LoadWords();
//}
break;
case curScore > 0:
//console.log("That's a pretty good score mate");
break;
}
//console.log(line + ": " + scoreDict[line].length);
}
}
console.log(tempInc)
score.ScoreWrite(score.scoreDict);
}
The issue was that I was calling the loop on the array I was editing, so as each element got removed from the array (rescored and moved into a separate array) it got shorter by that element, resulting in an issue that when the first element was rescored and removed, and then we moved onto the second index which was now the third element, because everything shifted up by 1 index
I fixed it by having it simply enter an empty array for each removed element, so everything kept its index and the array kept its length, and then clear the empty values at a later time in the code

Counting valleys question from hacker rank

Gary is an avid hiker. He tracks his hikes meticulously, paying close attention to small details like topography. During his last hike he took exactly steps. For every step he took, he noted if it was an uphill, , or a downhill, step. Gary's hikes start and end at sea level and each step up or down represents a unit change in altitude. We define the following terms:
A mountain is a sequence of consecutive steps above sea level, starting with a step up from sea level and ending with a step down to sea level.
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
Given Gary's sequence of up and down steps during his last hike, find and print the number of valleys he walked through.
For example, if Gary's path is , he first enters a valley units deep. Then he climbs out an up onto a mountain units high. Finally, he returns to sea level and ends his hike.
Function Description
Complete the countingValleys function in the editor below. It must return an integer that denotes the number of valleys Gary traversed.
I have tried writing this code in python and it runs well but cannot figure out a code logically
#n is the number of steps and s is the sequence of steps taken
def countingValleys(n, s):
level=valley=0
for i in range(n):
if(s[i]=='U'):
level+=1
if(level==0):
valley+=1
else:
level-=1
return valley
Results are fine
Questions: Can someone explain me the logic starting from if(level==0). If we increase the level by one unit when the person moves uphill, shouldn't we increase valley by 1 then. Why should valley increase by one when level is zero. Confused about the logic- can someone please help me understand this
If the step is uphill if(s[i]=='U')
And the level is 0 if(level==0)
Then it is a valley valley+=1
The function works by counting the valleys when you come out of them, and it tells that you come out of them because you reach the sea level giving an uphill step.
Its simple,
What the code means is, if you have encountered an up symbol it means you have climbed. Now if you have climbed from plane or mountain your level would be greater than 0. But if you have climbed from a valley to level then only your level would become 0.
basically if level<0 it means you are still in valley, level>0 means you are in mountain, level 0 means you are in sea level.
So if you have encountered a up symbol denoting climb action and then your level is 0 that means you have climbed up a valley that's all.
We can assign values to uphill and downhill as uphill=1, downhill=-1 and sea level=0 and as valley can be defined as when we reached the sea level from downhill, i.e from a negative value to zero
so if we are at a negative level and moving to sea level by adding the next step we can increment the valley.
Find the code snippet below
def returnCode(step):
if step=='U':
return 1;
return -1;
def countingValleys(steps, path):
# Write your code here
level=valley=0
for element in path:
code = returnCode(element)
if level< 0 and level+code == 0:
valley=valley+1
level = level+code
return valley
Does
level=0 valley=0
make any difference, they both are similar level=valley=0
The logic is simple you just have to count if the no if "U"-uphill assigned as '1' and number of 'D'-Downhills assigned as '-1' and on adding the both count one should get '0' as in [DDDUUU] which will increment valley by '1'.
When level=0 Gary has reached sea level meaning he has covered a valley
In Javascript
function countingValleys(steps, path){
let altitude = 0;
let valleys = 0;
for(let i = 0; i < steps; i++){
altitude = (path[i] == 'U') ? altitude + 1 : altitude - 1;
if(altitude == 0 && path[i] == 'U'){
valleys++;
}
}
return valleys;
}
console.log(countingValleys(8, "UDDDUDUU"));
in php
function countingValleys($steps, $path) {
// Write your code here
$valley = 0;
$altitude = 0;
for($i=0; $i < $steps; $i++){
$altitude = ($path[$i] == "U") ? $altitude + 1 : $altitude -1;
if($altitude == 0 && $path[$i] == "U"){
$valley += 1;
}
}
return $valley;
}
countingValleys(8, "UDDDUDUU")
Solution in Golang
The function is expected to return an INTEGER.
The function accepts following parameters:
INTEGER steps
STRING path
*/
func countingValleys(steps int32, path string) int32 {
// Write your code here
//level 0 is sea
//level>0 is mountain
//level< 0 valley
// check the steps if its U do level+1
//if step is D do a level-1
level :=0
valley :=0
step := []rune(path)
for i:=0; i< int(steps);i++{
if string(step[i]) =="U"{
level= level+1
}else if string(step[i])=="D"{
level= level-1
}
if string(step[i])=="U" && level == 0{
valley++
}
}
return int32(valley)
}
Counting valley hacker solution in php
function countingValleys($steps, $path) {
$valley = 0;
$sealevel = 0;
$newPath = str_split($path);
$c = count($newPath);
if ($steps == $c && $c >= 2) {
for($i = 0; $i < $c; $i++) {
if ($newPath[$i] == "D") {
$sealevel -= 1;
} else {
$sealevel += 1;
}
if ($sealevel == 0 && $newPath[$i] == "U") {
$valley += 1;
}
}
return $valley;
}
}
Track the altitude. Any time you return back to sea-level and you came from below, you know you've found a valley. Keep count of these finding.
Time-complexity: O(steps)
Space-complexity: O(steps)
Java 8
public static int countingValleys(int steps, String path)
{
int altitude = 0; // 0 = sea-level
int countedValleys = 0;
//Loop through path evaluating each change in altitude
for(char altChange: path.toCharArray())
{
//'U' increases altitude. Otherwise, decrease altitude ('D')
altitude = altChange == 'U' ? altitude + 1 : altitude - 1;
//If you've reached sea-level and you came from below, you've found a valley
if(altitude == 0 && altChange == 'U')
countedValleys++;
}
//Return count of found valleys
return countedValleys;
}
Javascript Solution:
function countingValleys(steps, path) {
var altitude = 0;
var numberOfValleys = 0;
path.split('').forEach(step => {
if(step === 'U'){
altitude ++;
if(altitude === 0){
numberOfValleys++;
}
}else{
altitude--
}
})
return numberOfValleys;
}
#JavaScript(Nodejs) solution
function countingValleys(steps, path) {
// Write your code here
let a = Array.from(path);
let valleys=0;
let pos=0;
let prevpos=0;
for(let i=0;i<a.length;i++){
if(a[i]==='U'){
prevpos=pos++;
if(pos===0){
valleys++;
}
}
else
{
prevpos = pos--;
}
}
return valleys;
}
you can try this code with go
func countingValleys(steps int32, path string) int32 {
// Write your code here
var lv int;
var count int32;
var lembah bool;
for i := 0; i< int(steps); i++{
if path[i]== 'U' {lv ++;}else if path[i]== 'D'{lv--}
if lv<0 {lembah = true}
if lembah {
if(lv>=0){
count ++;
lembah = false;
}
}
}
return count;
}

Bayes' formula for updating probabilistic map

I'm trying to get a mobile robot to map an arena based on what it can see from a camera. I've created a map, and managed to get the robot to identify items placed in the arena and give an estimated location, however, as I'm only using an RGB camera the resulting numbers can vary slightly ever frame due to noise, or change in lighting, etc. What am now trying to do is create a probability map using Bayes' formula to give a better map of the arena.
Bayes' Formula
P(i | x) = (p(i)p(x|i))/(sum(p(j)(p(x|j))
This is what I've got so far. All points on the map are initialised to 0.5.
// Gets the Likely hood of the event being correct
// Para 1 = Is the object likely to be at that location
// Para 2 = is the sensor saying it's at that location
private double getProbabilityNum(bool world, bool sensor)
{
if (world && sensor)
{
// number to test the function works
return 0.6;
}
else if (world && !sensor)
{
// number to test the function works
return 0.4;
}
else if (!world && sensor)
{
// number to test the function works
return 0.2;
}
else //if (!world && !sensor)
{
// number to test the function works
return 0.8;
}
}
// A function to update the map's probability of an object being at location (x,y)
// Para 3 = does the sensor pick up the an object at (x,y)
public double probabilisticMap(int x,int y,bool sensor)
{
// gets the current likelihood from the map (prior Probability)
double mapProb = get(x,y);
//decide if object is at location (x,y)
bool world = (mapProb < threshold);
//Bayes' formula to update the probability
double newProb =
(getProbabilityNum(world, sensor) * mapProb) / ((getProbabilityNum(world, sensor) * mapProb) + (getProbabilityNum(!world, sensor) * (1 - mapProb)));
// update the location on the map
set(x,y,newProb);
// return the probability as well
return newProb;
}
It does work, but the numbers seem to jump rapidly, and then flicker when they are at the top, it also errors if the numbers drop too near to zero. Anyone have any idea why this might be happening? I think it's something to do with the way the equations is coded, but I'm not too sure. (I found this, but I don't quite understand it, so I'm not sure of it's relevents, but it seems to be talking about the same thing
Thanks in Advance.
Use log-likelihoods when doing numerical computations involving probabilities.
Consider
P(i | x) = (p(i)p(x|i))/(sum(p(j)(p(x|j)).
Because x is fixed, the denominator, p(x), is a constant. Thus
P(i | x) ~ p(i)p(x|i)
where ~ denotes "is proportional to."
The log-likelihood function is just the log of this. That is,
L(i | x) = log(p(i)) + log(p(x|i)).

Iterative deepening search : Is it recursive?

I've searched the internet about the IDS algorithm and I keep finding some example but they are all with recursion, and as I understood iterative is not recursive..
So can you please give me some examples for IDS algorithm ?(implementation would be great and without recursion)
Thanks in advance! you will be a life saver!
The iterative part is not recursive: at the top it is more or less:
int limit = 0;
Solution sol;
do {
limit++;
sol = search(problem,limit);
} while(sol == null);
//do something with the solution.
This said, in most cases searching for a solution is indeed implemented recursively:
Solution search(Problem problem, int limit) {
return search(problem,0,limit);
}
Solution search (Problem problem, int price, int limit) {
if(problem.solved) {
return problem.getSolution();
}
for(int value = 0; value < valuerange; value++) {
problem.assignVariable(value);
int newprice = price + problem.price();
if(price < limit) {
Solution solution = search(problem,newprice,limit);
if(s != null) {
return solution;
}
}
problem.backtrackVariable();
}
return null;
}
But there exists an automatic procedure to turn any recursive program into a non-recursive one.
If you are thinking in algorithm terms (not just implementation), this would mean applying iteration at all nodes of the search tree, instead of just at the root node.
In the case of chess programs, this does have some bennefits. It improves move ordering, even in the case where a branch that was previously pruned by alpha-beta is later included. The cost of the extra search is kept low by using a transposition table.
https://www.chessprogramming.org/Internal_Iterative_Deepening

Resources