如何在不超过最大值的情况下递增变量?

我工作在一个简单的视频游戏程序为学校,我已经创建了一个方法,其中的球员得到15健康点,如果该方法被称为。我必须保持健康在100的最大限度,以我有限的编程能力在这一点上,我正在做这样的事情。

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

我知道我的语法并不完美,但我的问题是,什么可能是一个更好的方式来做到这一点,因为我也必须做一个类似的事情,伤害点不低于0。

这就是 饱和度算法

21626 次浏览

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);
}
}

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;

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;
}

Maybe this?

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

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 :)

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.

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!

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.

   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;
}

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.

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

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 );

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));
}

Most simple way using the modulus operator.

health = (health + 50) % 100;

health will never equal or exceed 100.