How can I increment a variable without exceeding a maximum value?

JavaIf StatementSwitch StatementSaturation Arithmetic

Java Problem Overview


I am working on a simple video game program for school and I have created a method where the player gets 15 health points if that method is called. I have to keep the health at a max of 100 and with my limited programming ability at this point I am doing something like this.

public void getHealed(){
    if(health <= 85)
        health += 15;
    else if(health == 86)
        health += 14;
    else if(health == 87)
    health += 13; 
}// this would continue so that I would never go over 100

I understand my syntax about isn't perfect but my question is, what may be a better way to do it, because I also have to do a similar thing with the damage points and not go below 0.

This is called saturation arithmetic.

Java Solutions


Solution 1 - Java

I would just do this. It basically takes the minimum between 100 (the max health) and what the health would be with 15 extra points. It ensures that the user's health does not exceed 100.

public void getHealed() {
    health = Math.min(health + 15, 100);
}

To ensure that hitpoints do not drop below zero, you can use a similar function: Math.max.

public void takeDamage(int damage) {
    if(damage > 0) {
        health = Math.max(health - damage, 0);
    }
}

Solution 2 - Java

just add 15 to the health, so:

health += 15;
if(health > 100){
    health = 100;
}

However, as bland has noted, sometimes with multi-threading (multiple blocks of code executing at once) having the health go over 100 at any point can cause problems, and changing the health property multiple times can also be bad. In that case, you could do this, as mentioned in other answers.

if(health + 15 > 100) {
    health = 100;
} else {
    health += 15;
}

Solution 3 - Java

You don't need a separate case for each int above 85. Just have one else, so that if the health is already 86 or higher, then just set it directly to 100.

if(health <= 85)
    health += 15;
else
    health = 100;

Solution 4 - Java

I think an idiomatic, object oriented way of doing this is to have a setHealth on the Character class. The implementation of that method will look like this:

public void setHealth(int newValue) {
    health = Math.max(0, Math.min(100, newValue))
}

This prevents the health from going below 0 or higher than 100, regardless of what you set it to.


Your getHealed() implementation can just be this:

public void getHealed() {
    setHealth(getHealth() + 15);
}

Whether it makes sense for the Character to have-a getHealed() method is an exercise left up to the reader :)

Solution 5 - Java

I am just going to offer a more reusable slice of code, its not the smallest but you can use it with any amount so its still worthy to be said

health += amountToHeal;
if (health >= 100) 
{ 
    health = 100;
}

You could also change the 100 to a maxHealth variable if you want to add stats to the game your making, so the whole method could be something like this

private int maxHealth = 100;
public void heal(int amountToHeal)
{
    health += amountToHeal;
    if (health >= maxHealth) 
    { 
        health = maxHealth;
    }
}

EDIT

For extra information

You could do the same for when the player gets damaged, but you wouldn't need a minHealth because that would be 0 anyways. Doing it this way you would be able to damage and heal any amounts with the same code.

Solution 6 - Java

health = health < 85 ? health + 15 : 100;

Solution 7 - Java

I would make a static method in a helper class. This way, rather than repeating code for every value which need to fit within some boundaries, you can have one all purpose method. It would accept two values defining the min and max, and a third value to be clamped within that range.

class HelperClass
{
    // Some other methods

    public static int clamp( int min, int max, int value )
    {
    	if( value > max )
	        return max;
	    else if( value < min )
	        return min;
	    else
	        return value;
    }
}

For your case, you would declare your minimum and maximum health somewhere.

final int HealthMin = 0;
final int HealthMax = 100;

Then call the function passing in your min, max, and adjusted health.

health = HelperClass.clamp( HealthMin, HealthMax, health + 15 );

Solution 8 - Java

I know this is a school project, but if you wanted to expand your game later on and be able to upgrade your healing power, write the function like so:

public void getHealed(healthPWR) {
    health = Math.min(health + healthPWR, 100);
}

and call out the function:

getHealed(15);
getHealed(25);

...etc...

Furthermore you can create your max HP by creating a variable that is not local to the function. Since I don't know what language you're using, I will not show an example because it might have the wrong syntax.

Solution 9 - Java

Maybe this?

public void getHealed()
{
  if (health <= 85)
  {
    health += 15;
  } else
  {
    health = 100;
  }
}

Solution 10 - Java

If you want to be cheeky and fit your code on one line, you could use a ternary operator:

health += (health <= 85) ? 15 : (100 - health);

Note that some people will frown upon this syntax due to (arguably) bad readability!

Solution 11 - Java

I believe this will do

if (health >= 85) health = 100;
else health += 15;

Explanation:

  • If the gap for healing is 15 or less, health will become 100.

  • Otherwise if the gap is bigger than 15, it will add 15 to the health.

So for example: if the health is 83, it will become 98 but not 100.

Solution 12 - Java

If I wanted to be thread safe I'd do it this way rather than using a synchronized block.

The atomic compareAndSet achieves the same outcome as synchronized without the overhead.

AtomicInteger health = new AtomicInteger();

public void addHealth(int value)
{
    int original = 0;
    int newValue = 0;
    do
    {
        original = health.get();
        newValue = Math.min(100, original + value);
    }
    while (!health.compareAndSet(original, newValue));
}

Solution 13 - Java

Most simple way using the modulus operator.

health = (health + 50) % 100;

health will never equal or exceed 100.

Solution 14 - Java

   private int health;
    public void Heal()
    {
        if (health > 85)
            health = 100;
        else
            health += 15;
    }
    public void Damage()
    {
        if (health < 15)
            health = 0;
        else
            health -= 15;
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2053184View Question on Stackoverflow
Solution 1 - JavaChris ForrenceView Answer on Stackoverflow
Solution 2 - JavaJordanView Answer on Stackoverflow
Solution 3 - JavargettmanView Answer on Stackoverflow
Solution 4 - JavaDaniel KaplanView Answer on Stackoverflow
Solution 5 - Java5tar-KasterView Answer on Stackoverflow
Solution 6 - JavaArooView Answer on Stackoverflow
Solution 7 - JavaMildWolfieView Answer on Stackoverflow
Solution 8 - JavaBlackBeltScriptingView Answer on Stackoverflow
Solution 9 - JavaJutoView Answer on Stackoverflow
Solution 10 - JavaOleksiyView Answer on Stackoverflow
Solution 11 - JavaMarmiKView Answer on Stackoverflow
Solution 12 - JavaRobert SuttonView Answer on Stackoverflow
Solution 13 - JavabondView Answer on Stackoverflow
Solution 14 - Javakiss my armpitView Answer on Stackoverflow