Reputation: 5375
I'm trying to create a leveling system for a text based RPG that I'm making. The problem I'm running into is that it seems ranges won't work with switch cases. Here is what I have:
int exp = 0, level = 1, hp = 10, hpmax = 10;
if (exp >= 262144) exp = 262144;
switch (exp)
{
case (4 - 15):
level = 2;
hp = 12;
hpmax = 12;
break;
case (16 - 63):
level = 3;
hp = 14;
hpmax = 14;
break;
case (64 - 255):
level = 4;
hp = 16;
hpmax = 16;
break;
case (256 - 1023):
level = 5;
hp = 18;
hpmax = 18;
break;
case (1024 - 4095):
level = 6;
hp = 20;
hpmax = 20;
break;
case (4096 - 16383):
level = 7;
hp = 20;
hpmax = 20;
break;
case (16384 - 65535):
level = 8;
hp = 22;
hpmax = 22;
break;
case (65536 - 262143):
level = 9;
hp = 24;
hpmax = 24;
break;
case (262144 - 999999999):
level = 10;
hp = 26;
hpmax = 26;
break;
Yes, I realize this doesn't do what I want it to do. I'm not quite satisfied with the alternatives that I've found. I'm looking for the simplest solution. I'm new to programming so any help would be appreciated.
Upvotes: 1
Views: 161
Reputation: 55619
Note if hpmax
is always = hp
, you can set that at the end, you don't need to have it in all the case
s.
Using if-else:
if (4 <= exp && exp <= 15)
{
level = 2;
hp = 12;
}
else if (16 <= exp && exp <= 63)
{
level = 3;
hp = 14;
}
else if ...
hpmax = hp; // set hpmax afterwards
Simplifying the above:
if (exp < 4) // 0-3
; // do nothing
else if (exp < 16) // 4-15
...
else if (exp < 64) // 16-63
...
Or simplifying with a function: (similar to utnapistim's suggestion)
bool in(int exp, int start, int end) { return start <= exp && exp <= end; };
if (in(exp, 4, 15)) // 4-15
...
else if (in(exp, 16, 63)) // 16-63
...
Using log-base-2:
switch((int)(Math.Log(exp)/Math.Log(2)))
{
case 2: case 3: // 4-15
level = 2;
hp = 12;
break;
case 4: case 5: // 16-63
...
default: // 262144-999999999
...
}
hpmax = hp;
A mathematical (way shorter) solution: (doesn't work for all cases, just something to derive a solution from)
int log = (int)(Math.Log(exp)/Math.Log(2));
level = 1+log/2;
hp = hpmax = 10+level*2;
Upvotes: 1
Reputation: 5375
This is what I ended up using:
static void LevelSystem()
{
if ((4 <= exp) && (exp <= 15))
{
level = 2;
hpmax = 12;
}
else if ((16 <= exp) && (exp <= 63))
{
level = 3;
hpmax = 14;
}
else if ((64 <= exp) && (exp <= 255))
{
level = 4;
hpmax = 16;
}
else if ((256 <= exp) && (exp <= 1023))
{
level = 5;
hpmax = 18;
}
else if ((1024 <= exp) && (exp <= 4095))
{
level = 6;
hpmax = 20;
}
else if ((4096 <= exp) && (exp <= 16383))
{
level = 7;
hpmax = 20;
}
else if ((16384 <= exp) && (exp <= 65535))
{
level = 8;
hpmax = 22;
}
else if ((65536 <= exp) && (exp <= 262143))
{
level = 9;
hpmax = 24;
}
else if ((262144 <= exp) && (exp <= 999999998))
{
level = 10;
hpmax = 26;
}
else if (exp >= 999999999)
{
exp = 999999999;
level = 99;
hp = 999999999;
hpmax = 999999999;
}
}
I made that ridiculous number for testing purposes for later, but I put it all in a method so I can call it whenever I need to check exp. I tested this out and it works exactly how I want it to.
Thanks for the help everyone!
Upvotes: 0
Reputation: 424
I think you should use a combination of definition array and consecutive if to find the right level for the character, I'll show you a sample with random (and fewer) values...
<?php
// Definition of experience needed per level, and hp given
$levelsData = array( 1 => array( "exp" => 0,
"hp" => 10),
2 => array( "exp" => 4,
"hp" => 12),
3 => array( "exp" => 15,
"hp" => 16),
4 => array( "exp" => 27,
"hp" => 34),
5 => array( "exp" => 500,
"hp" => 120));
// Finding user level, giving $exp as current exp
foreach ($levelsData as $level => $data) {
if ($exp < $data['exp']) {
break;
}
}
// Setting data, we already have $level as the actual level+1
$level--;
$data = $levelsData[$level];
$hp = $data['hp'];
$maxHp = $hp;
?>
Upvotes: 0
Reputation: 577
You're probably looking for if-then-else statements:
int exp = 0, level = 1, hp = 10, hpmax = 10;
if ((4 >= exp) && (exp <= 15)){
level = 2;
hp = 12;
hpmax = 12;
} elseif ((16 >= exp) && (exp <= 63)){
level = 3;
hp = 14;
hpmax = 14;
} elseif ((64 >= exp) && (exp <= 255)){
level = 4;
hp = 16;
hpmax = 16;
} elseif ((256 >= exp) && (exp <= 1023)){
level = 5;
hp = 18;
hpmax = 18;
} elseif ((256 >= exp) && (exp <= 1023)){
.... etc, you know what do paste here, etc ....
} elseif ((262144 >= exp) && (exp <= 999999999)){
level = 10;
hp = 26;
hpmax = 26;
} else {
... you probably don't need anything here ...
... you already set defaults in the init up top...
}
Upvotes: 0
Reputation: 27375
Conceptually, you could use a function for checking.
Example using c++:
inline bool in_range(int min, int max, int value)
{ return min <= value && value <= max; }
// ....
int exp = 0, level = 1, hp = 10, hpmax = 10;
if (exp >= 262144) exp = 262144;
if (in_range(0, 15, exp)) {
level = 2;
hp = 12;
hpmax = 12;
} else if (in_range(16, 63, exp)) {
level = 3;
hp = 14;
hpmax = 14;
} else if ...
Upvotes: 0