Thank you for any help you can provide on this.
If we have:
$level = floor((-1 + sqrt(1 + 4 * ($c_xp + 500) / 100 * 2)) / 2) - 1; //GET LEVEL
For instance if:
$c_xp = 1200
Then:
$level = 4
Then I am asking if:
$level = 4
How much xp to get to level 5?
How can I get the amount of xp required to achieve the next level?
The formula to get the minimum XP required to reach a level $level is given by:
$minXP = 12.5 * (pow((2 * $level + 3), 2) - 41);
So you can set $level = 5 and $level = 4 and find the difference between them.
Analyse:
I ran a script to view the XP needed for each level:
$current_level = 0;
for($c_xp = 1;$c_xp < 7000;$c_xp++){
$level = floor((-1 + sqrt(1 + 4 * ($c_xp + 500) / 100 * 2)) / 2) - 1; //GET LEVEL
if($level > $current_level){
$current_level++;
echo "c_xp $c_xp level $level<br>";
}
}
The output is:
c_xp 1 level 1
c_xp 100 level 2
c_xp 500 level 3
c_xp 1000 level 4
c_xp 1600 level 5
c_xp 2300 level 6
c_xp 3100 level 7
c_xp 4000 level 8
c_xp 5000 level 9
c_xp 6100 level 10
We can see that level 1 is an exception, then the difference of XP from level 2 to level 3 is 400, from level 3 to level 4: 500 and level 4 to level 5: 600 and so on...
The pattern is now clear,
Level 1 -> 1 XP
Level 2 -> Start a 100 XP
Level 3 -> Increase by 400 (500 XP)
Level 4 -> Increase by (400 + 100) 1000XP
Level 5 to Level X -> Keep increasing by 100
The code:
With the above analyse, I could come up with a loop in a function:
$c_xp = 1200;
$level = floor((-1 + sqrt(1 + 4 * ($c_xp + 500) / 100 * 2)) / 2) - 1;
echo 'Next level: '.current_level_xp($level+1).'<br>';
echo 'XP needed for next Level: '. (current_level_xp($level+1) - $c_xp);
function current_level_xp($current_level){
if($current_level <= 1){
return(1);
}else{
$increase = 400;
$needed = 100;
for($i=0;$i<$current_level-2;$i++){
$needed += $increase;
$increase += 100;
}
return $needed;
}
}
Output:
Next level: 1600
XP needed for next Level: 400
Use a math / formular plotting tool of your choosing to get an idea of the results of the used equation (which presumably isn't yours):
Now, there's probably even a way to reverse your formula for translating y into x. But I'm unsure if there's a floor reverse.
Related
I have good reviews, and I have bad reviews. I need calculate rating from this reviews for post.
Example:
Post 1 have 1 good reviews, and 2 bad reviews
Post 2 have 12 good reviews, and 5 bad reviews
Post 3 have 0 good reviews, and 0 bad reviews
How I can calculate rating? I need for post get 5 stars. I need score up to 5 stars or less. May be I need this formula?
$score = ($good_reviews * $bad_reviews) / 5; //get rating stars
But I don't get 5, or less number. How I can do it correctly?
Maybe you want this:
$rating = $good_reviews
? intval ( 5.4 * $good_reviews / ( $good_reviews + $bad_reviews))
: 0;
And now step by step:
SUM := $good_reviews + $bad_reviews is the sum of all reviews.
RATE := $good_reviews / SUM is the general rating of $good_reviews to the sum of reviews. The result is in the range 0.000 to 1.000 .
Multiplying it with 5.4 expands the range to 0.000 to 5.400. Its a little bit tricky to allow some bad votes for a 5 stars ranking. The factor can be every number between 5.000 and 5.9999999.
intval() reduces the number to an int from 0 to 5 (your stars).
The alternative by ?: avoids an division by zero error.
That formula will not give you what you need. It will only multiply good with bad and divide by 5. For example ((100 good * 20 bad) / 5) = 400. Way out of 5!
If you need score up to five stars you will need to use ranges.
Calculate percentage between good and bad and then do an if checks.
For example:
$percentage = (($good - $bad) / $good) * 100;
if($percentage => 100) {
//5 starts
} else if ($percentage < 100 && $percentage => 80) {
//4 stars
} else if ($percentage < 80 && $percentage => 60) {
//3 stars
} else if ($pecentage < 60 && $percentage => 40) {
//2 starts
} else {
//1 star
}
That's just a basic example. There are different ways to approach this. You need to adjust it to your needs and try if it works for you.
I did this really quick, so didn't test it. Please, check and see if it fits you. I just wanted to give you an idea.
Scenario of Web Game. We have two connected buildings. The second one is something like upgrade but not exactly, never mind this is not important.
Every building have experience level and this level its dependеnt of produced materials from the building. When we produce materials we have calculation between levels of the buildings.
Example: we produce 2000 gold, every building produce the gold like:
Building B level - Building A level x Produced Gold
notes:
Always Building B(Upgrade building) have bigger priority so its: level B - level A x Gold
Always the produced gold is the same on both buildings
$building_A = array(4=>2000);
$building_B = array(5=>2000);
Building A Level 4 -> 2000 Gold
Building B Level 5 -> 2000 Gold
Calculation is : 5 - 4 x 2000 gold = 1 x 2000
Variant 0.1:
Its possible Base building to Level UP and second building to be the same level:
Array:
$buildingA = array(4=>1000, 5=>1000);
$buildingB = array(5=>2000);
Building А
Level 4: 1000 gold
Level 5: 1000 gold
Building B:
level 5: 2000 gold
Calculation:
5 - 4 x 1000 = 1 x 1000
5 - 5 x 1000 = 0 x 1000
Variant 0.2:
Its possible and opposite situation:
Array:
$buildingA = array(4=>2000);
$buildingB = array(4=>700,5=>1300);
Building A:
Level 4 : 2000 Gold
Building B:
Level 5 : 700 Gold
Level 6 : 1300 Gold
Calculation:
5-4 x 700 = 1 x 700
6-4 x 1300 = 1 x 1300
Here is the code of variants 0.1 & 0.2
http://sandbox.onlinephpfunctions.com/code/ef0adce304554392266b8193b292051c0d98bae8
//v.01
$buildingA = array(4=>1000, 5=>1000);
$buildingB = array(5=>2000);
//v.02
//$buildingA = array(4=>2000);
//$buildingB = array(4=>700,5=>1300);
if(sizeof($buildingB) == 1)
{
foreach($buildingA as $level_a => $gold)
{
$level_b = array_keys($buildingB);
$level_b = $level_b[0];
$level_diff = $level_b - $level_a;
$tmp['calc'] = $level_b . ' - ' .$level_a.' = '.$level_diff . ' x ' . $gold;
$x[] = $tmp;
}
}
elseif(sizeof($buildingA) == 1)
{
foreach($buildingB as $level_b => $gold)
{
$level_a = array_keys($buildingA);
$level_a = $level_a[0];
$level_diff = $level_b - $level_a;
$tmp['calc'] = $level_b . ' - ' .$level_a.' = '.$level_diff . ' x ' . $gold;
$x[] = $tmp;
}
}
Everything is good to here, but have and turd variant when the both buildings increase his level. I make several code's for this variant but non of them looks and work good.
Can somebody with more clear mind give some suggestion how easy to calculate difference.
v.1
$buildingA = array(4=>500, 5=>1500);
$buildingB = array(4=>1000, 5=>1000);
Calculation: ()
4 - 4 x 500
4 - 5 x 500
5 - 5 x 1000
v.2
$buildingA = array(4=>1500, 5=>500);
$buildingB = array(4=>1000, 5=>1000);
Calculation: (B-A)
4 - 4 x 1000
5 - 4 x 500
5 - 5 x 500
v.3
$buildingA = array(4=>1000, 5=>1000);
$buildingB = array(4=>500, 5=>1500);
Calculation: (B-A)
4 - 4 x 500
5 - 4 x 500
5 - 5 x 1000
V.4
$buildingA = array(4=>1400, 5=>600);
$buildingB = array(5=>700, 6=>1300);
Calculation: (B-A)
5 - 4 x 700
6 - 4 x 700
6 - 5 x 600
V.5
$buildingA = array(1=>300, 2=>700, 3=>1000);
$buildingB = array(5=>500, 6=>1500);
Calculation: (B-A)
5 - 1 x 300
5 - 2 x 200
6 - 2 x 500
6 - 3 x 1500
Lets try explan with v.3:
$buildingA = array(4=>1000, 5=>1000);
$buildingB = array(4=>500, 5=>1500);
Building A will produce 1000 gold in level 4 then level up and the rest is on level 5
Building B will produce 500 gold in level 4 then will level up and the rest is on level 5
So how we calculate:
"B" - 500 gold is given by level 4, we have 4 - 4 x 500, until now we use 500 from 2000 gold
"B" now become level 5
"A" its lv4 and need 500 more
gold to level 5, so we give 5 - 4 x 500 (its 5 because "A" level up
before that), until now we use (500 + 500) from 2000 gold
"A" now its level 5
"B" its level 5 and "A" is level 5, so all other gold its 5 - 5 x 1000, (here is the rest of not used gold: 1000)
Here i make some test script, but the code not look very well and its not work with v.04:
http://sandbox.onlinephpfunctions.com/code/6f12fda4877ad781da52f908f3cba79aa0c69f33
I need to calculate how match gold will produce the buildings together when both level UP.
I not see easy way to calc this. Any suggestions ?
I am out of ideas how to make that. its hard to explain it good, but i hope its writen clear - please do not judge me about that :)
One a genius colleague provided me easy mathematical solution:
function f ($x1, $x2)
{
foreach ($x2 as $k2 => $v2)
{
if ($v2 == 0)
continue;
foreach ($x1 as $k1 => $v1)
{
if ($v2 == 0 || $v1 == 0)
continue;
$m = ($v2 >= $v1) ? $v1 : $v2;
$v2 -= $m;
$v1 -= $m;
$x2[$k2] = $v2;
$x1[$k1] = $v1;
echo '(' . $k2 . ' - ' . $k1 . ') = ' . ($m) . '<br />';
}
}
}
f($buildingA, $buildingB);
I have a value that i need to translate to a percentage given a certain set of rules.
VALUE=X
Where X can be anything starting from 0
If:
X > 200
the result of my function should be 100 (percent).
If:
X < 200 AND >= 100
the result should be between 100 and 50 (percent).
Example: X=150 would be 75%
If:
X < 100 AND >= 80
the result should be between 50 and 25 (percent).
Example: X=90 would be 37.5%
And if:
X < 80
the result should be between 25 and 0 (percent).
My approach in PHP would be something like
if($value > 200) return 100;
if($value > 100 && $value < 200) return ???;
... and so on.
Wherein ??? obviously stands for the formula i don't know how to set up.
Is there a way to do this in one single formula?
And even if not - what is the mathematical approach to this problem?
I know it is very basic but it seems i skipped too many maths lessons in primary school.
The function can be defined piecewisely:
Graphically, this is represented with four straight lines of different gradients. While there isn't a way to represent this function without separate pieces, implementing the above is quite easy.
In PHP, this function can be written as:
function f($x) {
if ($x >= 200)
return 100;
if ($x >= 100 && $x < 200)
return 50 + 50 * (($x - 100) / 100);
if ($x >= 80 && $x < 100)
return 25 + 25 * (($x - 80) / 20);
if ($x < 80)
return 25 * ($x / 80);
}
First, determine which range you should be in. Then:
Subtract the bottom of the range.
Divide by the length of the range.
Multiply by the number of points difference over the range.
Add the number of points at the bottom of the range.
So X from 100 to 200 gives a score from 100 to 50. The bottom of the range is 100; the size of the range is 100 (200 - 100), and the score goes from 100 at the beginning to 50 at the end, so the difference is -50. Therefore -50 * ($value - 100) / 100 + 100 would work, or simplifying, -0.5 * ($value - 100) + 100 or 150 - $value * 0.5.
Working another example, from 80 to 100: the bottom of the range is 80, the size of the range is 20, and the score goes from 25 to 50 (difference: -25). You get -25 * ($value - 80) / 20 + 25, which simplifies to -1.25 * ($value - 80) + 25 or 125 - $value * 1.25
I have a set of (floating point) numbers between x = 1 and y = 9:
$numbers = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
How can I compute a metric of the proximity, in the given interval, between number A and number B?
What I've Tried
If the amplitude (max - min) of the above set is 9 - 1 = 8 I am able to compute the relative value of any number using the formula (n - min) / (max - min), computing this for all values yields:
(1 - 1) / (9 - 1) = 0
(2 - 1) / (9 - 1) = 0.125
(3 - 1) / (9 - 1) = 0.25
(4 - 1) / (9 - 1) = 0.375
(5 - 1) / (9 - 1) = 0.5
(6 - 1) / (9 - 1) = 0.625
(7 - 1) / (9 - 1) = 0.75
(8 - 1) / (9 - 1) = 0.875
(9 - 1) / (9 - 1) = 1
Dividing the minimum relative value (between A and B) with the maximum relative value (also between A and B), seems to produce the kind of metric I'm looking for. Here are a few examples:
var_dump(min(0.875, 0.25) / max(0.875, 0.25)); // 0.286 between 8 and 3
var_dump(min(0.875, 0.375) / max(0.875, 0.375)); // 0.429 between 8 and 4
var_dump(min(0.875, 0.75) / max(0.875, 0.75)); // 0.857 between 8 and 7
var_dump(min(0.875, 0.875) / max(0.875, 0.875)); // 1 between 8 and 8
var_dump(min(0.25, 0.25) / max(0.25, 0.25)); // 1 between 3 and 3
The Problem
Whenever the minimum value of the set comes into play, the result will always be 0:
var_dump(min(0.875, 0) / max(0.875, 0)); // 0 between 8 and 1
var_dump(min(0.125, 0) / max(0.125, 0)); // 0 between 2 and 1
var_dump(min(0, 0) / max(0, 0)); // 0 between 1 and 1 (ERR!)
Any ideas on how to solve this?
I was suggesting something like this:
<?php
function prox($a,$b)
{
return(abs($a-$b) / abs(1-9));
}
printf("%f\n", prox(1,2)); // 0.125000
printf("%f\n", prox(2,3)); // 0.125000
printf("%f\n", prox(1,1)); // 0.000000
printf("%f\n", prox(1,9)); // 1.000000
The proximity between 1 and 2 is the same as 2 and 3. This seems to make sense.
The largest proximity you'll get is when the numbers you specify are the bounds of your predefined range.
The smallest proximity you'll get is when the numbers you specify are equal.
If you want the opposite to be true (which I suppose better reflects proximity, you could do:
<?php
function prox($a,$b)
{
return(1 - (abs($a-$b) / abs(1-9)));
}
printf("%f\n", prox(1,2));
printf("%f\n", prox(2,3));
printf("%f\n", prox(1,1));
printf("%f\n", prox(1,9));
Which would output:
0.875000
0.875000
1.000000
0.000000
Now, the same number produces 1 as you specified and the bounds produce 0 as they're the least-proximate pair of values. Combinations like (1,2), (2,3), (3,4), etc. all produce the same value, as do combinations like (2,4), (3,5), (4,6), etc, etc.
Im making a browser based PHP game and in my database for the players it has a record of that players total EXP or experience.
What i need is a formula to translate that exp into a level or rank, out of 100.
So they start off at level 1, and when they hit say, 50 exp, go to level 2, then when they hit maybe 125/150, level 2.
Basically a formula that steadily makes each level longer (more exp)
Can anyone help? I'm not very good at maths :P
Many formulas may suit your needs, depending on how fast you want the required exp to go up.
In fact, you really should make this configurable (or at least easily changed in one central location), so that you can balance the game later. In most games these (and other) formulas are determined only after playtesting and trying out several options.
Here's one formula: First level-up happens at 50 exp; second at 150exp; third at 300 exp; fourth at 500 exp; etc. In other words, first you have to gather 50 exp, then 100 exp, then 150exp, etc. It's an Arithmetic Progression.
For levelup X then you need 25*X*(1+X) exp.
Added: To get it the other way round you just use basic math. Like this:
y=25*X*(1+X)
0=25*X*X+25*X-y
That's a standard Quadratic equation, and you can solve for X with:
X = (-25±sqrt(625+100y))/50
Now, since we want both X and Y to be greater than 0, we can drop one of the answers and are left with:
X = (sqrt(625+100y)-25)/50
So, for example, if we have 300 exp, we see that:
(sqrt(625+100*300)-25)/50 = (sqrt(30625)-25)/50 = (175-25)/50 = 150/50 = 3
Now, this is the 3rd levelup, so that means level 4.
If you wanted the following:
Level 1 # 0 points
Level 2 # 50 points
Level 3 # 150 points
Level 4 # 300 points
Level 5 # 500 points etc.
An equation relating experience (X) with level (L) is:
X = 25 * L * L - 25 * L
To calculate the level for a given experience use the quadratic equation to get:
L = (25 + sqrt(25 * 25 - 4 * 25 * (-X) ))/ (2 * 25)
This simplifies to:
L = (25 + sqrt(625 + 100 * X)) / 50
Then round down using the floor function to get your final formula:
L = floor(25 + sqrt(625 + 100 * X)) / 50
Where L is the level, and X is the experience points
It really depends on how you want the exp to scale for each level.
Let's say
LvL1 : 50 Xp
Lvl2: LvL1*2=100Xp
LvL3: LvL2*2=200Xp
Lvl4: LvL3*2=400Xp
This means you have a geometric progression
The Xp required to complete level n would be
`XPn=base*Q^(n-1)`
In my example base is the inital 50 xp and Q is 2 (ratio).
Provided a player starts at lvl1 with no xp:
when he dings lvl2 he would have 50 total Xp
at lvl3 150xp
at lvl4 350xp
and so forth
The total xp a player has when he gets a new level up would be:
base*(Q^n-1)/(Q-1)
In your case you already know how much xp the player has. For a ratio of 2 the formula gets simpler:
base * (2^n-1)=total xp at level n
to find out the level for a given xp amount all you need to do is apply a simple formula
$playerLevel=floor(log($playerXp/50+1,2));
But with a geometric progression it will get harder and harder and harder for players to level.
To display the XP required for next level you can just calculate total XP for next level.
$totalXpNextLevel=50*(pow(2,$playerLevel+1)-1);
$reqXp=$totalXpNextLevel - $playerXp;
Check start of the post:
to get from lvl1 -> lvl2 you need 50 xp
lvl2 ->lvl3 100xp
to get from lvl x to lvl(x+1)
you would need
$totalXprequired=50*pow(2,$playerLevel-1);
Google gave me this:
function experience($L) {
$a=0;
for($x=1; $x<$L; $x++) {
$a += floor($x+300*pow(2, ($x/7)));
}
return floor($a/4);
}
for($L=1;$L<100;$L++) {
echo 'Level '.$L.': '.experience($L).'<br />';
}
It is supposed the be the formula that RuneScape uses, you might me able to modify it to your needs.
Example output:
Level 1: 0
Level 2: 55
Level 3: 116
Level 4: 184
Level 5: 259
Level 6: 343
Level 7: 435
Level 8: 536
Level 9: 649
Level 10: 773
Here is a fast solution I used for a similar problem. You will likely wanna change the math of course, but it will give you the level from a summed xp.
$n = -1;
$L = 0;
while($n < $xp){
$n += pow(($L+1),3)+30*pow(($L+1),2)+30*($L+1)-50;
$L++;
}
echo("Current XP: " .$xp);
echo("Current Level: ".$L);
echo("Next Level: " .$n);
I take it what you're looking for is the amount of experience to decide what level they are on? Such as:
Level 1: 50exp
Level 2: 100exp
Level 3: 150exp ?
if that's the case you could use a loop something like:
$currentExp = x;
$currentLevel;
$i; // initialLevel
for($i=1; $i < 100; $i *= 3)
{
if( ($i*50 > $currentExp) && ($i < ($i+1)*$currentExp)){
$currentLevel = $i/3;
break;
}
}
This is as simple as I can make an algorithm for levels, I haven't tested it so there could be errors.
Let me know if you do use this, cool to think an algorithm I wrote could be in a game!
The original was based upon a base of 50, thus the 25 scattered across the equation.
This is the answer as a real equation. Just supply your multiplier (base) and your in business.
$_level = floor( floor( ($_multipliter/2)
+ sqrt( ($_multipliter^2) + ( ($_multipliter*2) * $_score) )
)
/ $_multipliter
) ;