Jared Price
Jared Price

Reputation: 5375

Ranges not usable with switch cases, need good alternative

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

Answers (5)

Bernhard Barker
Bernhard Barker

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 cases.

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

Jared Price
Jared Price

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

Frhay
Frhay

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

KevinM
KevinM

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

utnapistim
utnapistim

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

Related Questions