I have 5 different variables that I need to calculate. Right now these work, but what I want to do is have the price recalculate every 50 increase. Now, I can code into the form to only allow a maximum purchase of 50 at a time, but I want to allow for as many of each as the person has money for (that is what the numbers are). So I think what I need is a parabola style formula that auto increases every 50, but I don't know exactly what I'm looking for or how to implement it.
$resprice = 20000+($cityFetch['residential']*502)+($cityNum*1000);
$comprice = 18000+($cityFetch['commercial']*506)+($cityNum*1000);
$indprice = 23000+($cityFetch['industrial']*508)+($cityNum*1000);
$landprice = 600+($cityFetch['land']*.008);
$milprice = 25000+($cityFetch['military']*512)+($cityNum*1000);
EDIT: I was indicated that a loop will work for this.
EDIT3: Finally landed on this, Havvy helped me out on IRC
$cityCheck = mysql_query("SELECT * FROM cities WHERE nation='$nation'");
$cityNum = mysql_num_rows($cityCheck);
function determinePrice($baseCost, $scalar, $current, $bought) {
$min = $baseCost + $scalar * ($current + 1) + ($cityNum * 1000);
$max = $baseCost + $scalar * ($current + $bought) + ($cityNum * 1000);
$average = ($min + $max) / 2;
return $average * $bought;
}
$resprice = determinePrice(20000, 502, $cityFetch['residential'], $cityFetch['residential']);
$comprice = determinePrice(18000, 506, $cityFetch['commercial'], $cityFetch['commercial']);
$indprice = determinePrice(23000, 508, $cityFetch['industrial'], $cityFetch['industrial']);
$milprice = determinePrice(25000, 502, $cityFetch['residential'], $cityFetch['military']);
$landprice = 600+($cityFetch['land']*.008);
I use a step size of 1, instead of 50. It's more logical (one less magic number) to not give discounts based on how much you buy at a time, and it would be confusing to new players having a stepwise-linear function.
The reasoning behind this function can be found at http://betterexplained.com/articles/techniques-for-adding-the-numbers-1-to-100/.
function determinePrice($baseCost, $scalar, $current, $bought) {
$min = $scalar * ($current + 1) + ($cityNum * 1000);
$max = $scalar * ($current + $bought) + ($cityNum * 1000);
$average = ($min + $max) / 2;
return $average * $bought;
}
Using it would look something like this:
$resprice = determinePrice(20000, 502, $cityFetch['residential'], $resBought);
It won't work for land though, because land doesn't include the city price in it. For land, you can copy the function and remove the $cityNum * 1000 portions. You could also add in a $isLand parameter to the signature, and use a ternary operator to add 0 instead.
If you don't like that $cityNum has to already be declared with the proper value before declaring this function, you can always add it to the function signature, making it a pure function.
$count=1
if($count==50)
{
You increase the prices then
$count=1;
}
$resprice = 20000+($cityFetch['residential']*502)+($cityNum*1000);
$comprice = 18000+($cityFetch['commercial']*506)+($cityNum*1000);
$indprice = 23000+($cityFetch['industrial']*508)+($cityNum*1000);
$landprice = 600+($cityFetch['land']*.008);
$milprice = 25000+($cityFetch['military']*512)+($cityNum*1000);
$count++;
Related
I wanted to know how I present a percentage, here is the code
//The number taken from the database
$minos = $ud['bnk']['gold'];
The number that is supposed to be in percent through the database (the database has a number and not a percentage for example 2)
$plus= $ud['bnk']['ent_level'];
And here is a simple calculation of X + 2% = Y
$sava = $minos + $plus;
I tried to do this, according to an internet guide, but it doesn't work for me, I want the number to be a percentage and not successful
function get_percentage($total, $number)
{
if ( $total > 0 ) {
return round($number / ($total / 100),$ud['bnk']['ent_level']);
} else {
return 0;
}
}
$minos = $ud['bnk']['gold'];
$plus = get_percentage(100,$ud['bnk']['ent_level']).'%';
$sava = $minos + $plus;
I solved the equation with what you gave me, thank you very much, the way is:
$minos = $ud['bnk']['gold'];
$plus = ($minos / 100) * $ud['bnk']['ent_level'];
$sava = $plus;
Thanks so much to everyone who helped
I couldn't find any answers, so I am asking here.
How can I calculate whether an event should be triggered or not based on percent?
Let me explain.
Let say an event has a 30% probability of occurring.
When I run the script (call a function) how can I know if that event falls into that 30% or not?
Basically, in the end, I have to return true or false from a function.
Hopefully, you understand what I mean.
I have my own solution, but I believe it isn't correct:
$evasion_percent = 30;
$did_evasion = false;
$my_evasion_number = mt_rand(0,100);
if ($my_evasion_number <= $evasion_percent) {
$did_evasion = true;
}
return $did_evasion;
Thanks.
Your solution is fine.
$evasion_percent will be greater than or equal to a random integer 30% of the time as there are 30/100 numbers (excluding 0) that will make your function return true.
ie. (30 desirable outcomes that make this function return true / sample space of 100) ~ 30%.
You need to get random from 1 to 100, not from 0 to 100, the rest looks fine.
<?php
function trigger_event($percent) {
$did_evasion = false;
$my_evasion_number = mt_rand(1, 100);
if ($my_evasion_number <= $percent) {
$did_evasion = true;
}
return $did_evasion;
}
You can also try it with large number of calls (1000, 100000 or even more) and see how part of triggered events is closed to your percentage:
$evasion_percent = 30;
$m = 0;
for($n = 1; $n <= 1000; $n++) {
$m += trigger_event($evasion_percent) ? 1 : 0;
}
echo $m / $n * 100;
I wrote a simple code to calculate a math equation, but I would like to iterate through numbers from $start to $end. I am making a game, and this page will calculate the amount of experience it takes to reach the next level and insert it into the database. What would be the best way to iterate from $start to $end and calculate the amount of exp needed for that level?
Code:
<?php
$start = 1;
$end = 100;
$level = $start++;
$l = $level - 1;
$exp = ((40*($l * $l)) + (360 * $l));
?>
As it sits right now it calculates the first level but i cannot for the life of me figure out how to make it go through til it reaches $end.
$exp = 0;
for($level = $start; $level <= $end; $level++){
$exp += 40 * $l ** 2 + 360 * $l;
}
Actually, we can use mathematics to make this faster by generalizing the experience level required. Since your experience function is the summation of a quadratic function:
f(n)
= S[1 100] 40n^2 + 360n
= 40n (n + 1) (2n + 1) / 6 + 360n (n + 1) / 2
In PHP:
40 * $level * ($level + 1) * (2 * $level + 1) / 6 + 360 * $level * ($level + 1) / 2
Or simplify it further if you like.
This is definitely faster than calculating a loop 100 times.
If $start is not 1, simply use f(end) - f(start - 1).
You have to calculate the needed xp for every single level, so you should put the calculation code inside a loop that starts at your lowest level and proceeds until it hits the top limit / end level. You can choose from two different loop types in PHP, the for-loop and the while-loop.
Personally, I would choose the while-loop for this specific "problem", but that is a thing everyone has to decide on his own. The code for your calculator would look like this:
// Create an extra variable to store the level for which you are currently calculating the needed xp
$i = $start;
// The while-loop (do this code until the current level hits the max level as specified)
while($i <= end) {
// use $i to calculate your exp, its the current level
// Insert code here...
// then add 1 to $i and do the same again (repeat the code inside loop)
$i++;
}
Here are some links to the documentation of php:
while-loop
for-loop
I am using this algorithm based of Reddit and want to change it so it shows rising posts rather than hot. Which number do I change so that the time between posting and now have a greater influence on the returned score? I have tried changing a few numbers but still am not getting anywhere
Thanks heaps
function calculate_rank_sum($score, $created_at) {
$order = log10(max(abs($score), 1));
if ( $score > 0 ) {
$sign = 1;
} elseif ( $score < 0 ) {
$sign = -1;
} else {
$sign = 0;
}
$seconds = intval(($created_at - mktime(0, 0, 0, 1, 1, 1970))/86400);
$long_number = ($order + $sign) * ($seconds / 45000);
return round($long_number, 7);
}
This is the line which essentially calculates the score.
$long_number = ($order + $sign) * ($seconds / 45000);
If you wanted the time created to have a larger impact, I'd suggest reducing 45000, and/or offsetting ($order + $sign). This is a forumla which will require a lot of fine tuning to get it exactly the way you want it, so the best thing I'd suggest is to perform a lot of unit tests, and perform a lot of tweaks.
Your formula is wrong:
($order + $sign) * ($seconds / 45000)
You've added parentheses that should not be there. If you look at https://gist.github.com/zeuxisoo/882820, it should be:
$order + $sign * $seconds / 45000
But even that was based on the old reddit algorithm which was later fixed to:
sign * order + seconds / 45000
You can decrease 45000 to give the time component more weight.
I've been attempting to implement Vincenty's formulae with the following:
/* Implemented using Vincenty's formulae from http://en.wikipedia.org/wiki/Vincenty%27s_formulae,
* answers "Direct Problem".
* $latlng is a ('lat'=>x1, 'lng'=>y1) array
* $distance is in miles
* $angle is in degrees
*/
function addDistance($latlng, $distance, $bearing) {
//variables
$bearing = deg2rad($bearing);
$iterations = 20; //avoid too-early termination while avoiding the non-convergant case
//knowns
$f = EARTH_SPHEROID_FLATTENING; //1/298.257223563
$a = EARTH_RADIUS_EQUATOR_MILES; //3963.185 mi
$phi1 = deg2rad($latlng['lat']);
$l1 = deg2rad($latlng['lng']);
$b = (1 - $f) * $a;
//first block
$tanU1 = (1-$f)*tan($phi1);
$U1 = atan($tanU1);
$sigma1 = atan($tanU1 / cos($bearing));
$sinalpha = cos($U1)*sin($bearing);
$cos2alpha = (1 - $sinalpha) * (1 + $sinalpha);
$usquared = $cos2alpha * (($a*$a - $b*$b) / 2);
$A = 1 + ($usquared)/16384 * (4096+$usquared*(-768+$usquared*(320 - 175*$usquared)));
$B = ($usquared / 1024)*(256*$usquared*(-128 + $usquared * (74 - 47*$usquared)));
//the loop - determining our value
$sigma = $distance / ($b * $A);
for($i = 0; $i < $iterations; ++$i) {
$twosigmam = 2*$sigma1 + $sigma;
$delta_sigma = $B * sin($sigma) * (cos($twosigmam)+(1/4)*$B*(cos(-1 + 2*cos(cos($twosigmam))) - (1/6)*$B*cos($twosigmam)*(-3+4*sin(sin($sigma)))*(-3+4*cos(cos($twosigmam)))));
$sigma = $distance / ($b * $A) + $delta_sigma;
}
//second block
$phi2 = atan((sin($U1)*cos($sigma)+cos($U1)*sin($sigma)*cos($bearing)) / ((1-$f) * sqrt(sin($sinalpha) + pow(sin($U1)*sin($sigma) - cos($U1)*cos($sigma)*cos($bearing), 2))));
$lambda = atan((sin($sigma) * sin($bearing)) / (cos($U1)*cos($sigma) - sin($U1)*sin($sigma)*cos($bearing)));
$C = ($f / 16)* $cos2alpha * (4+$f*(4-3*$cos2alpha));
$L = $lambda - (1 - $C) * $f * $sinalpha * ($sigma + $C*sin($sigma)*(cos($twosigmam)+$C*cos($sigma)*(-1+2*cos(cos($twosigmam)))));
$alpha2 = atan($sinalpha / (-sin($U1)*sin($sigma) + cos($U1)*cos($sigma)*cos($bearing)));
//and return our results
return array('lat' => rad2deg($phi2), 'lng' => rad2deg($lambda));
}
var_dump(addDistance(array('lat' => 93.129, 'lng' => -43.221), 20, 135);
The issue is that the results are not reasonable - I'm getting variances of up to 20 latitude and longitude keeping the distance at 20. Is it not in units of elliptical distance on the sphere? Am I misunderstanding something, or is my implementation flawed?
There are a number of errors in transcription from the wikipedia page Direct Problem section:
Your u2 expression has 2 in the denominator where it should have b2;
Your A and B expressions are inconsistent about whether the initial fraction factor needs to be parenthesised to correctly express a / b * c as (a/b) * c - what happens without parentheses is a php syntax issue which I don't know the answer to, but you should favour clarity;
You should be iterating "until there is no significant change in sigma", which may or may not happen in your fixed number of iterations;
There are errors in your DELTA_sigma formula:
on the wikipedia page, the first term inside the square bracket [ is cos sigma (-1 etc, whereas you have cos (-1 etc, which is very different;
in the same formula and also later, note that cos2 x means (cos x)(cos x), not cos cos x!
Your phi_2 formula has a sin($sinalpha) where it should have a sin($sinalpha)*sin($sinalpha);
I think that's all.
Have you tried this:
https://github.com/treffynnon/Geographic-Calculations-in-PHP