-1

I am having an issue with a health counter in my battleship game. What I need is that when the method is called, it will take 1 off of health. So let's say that the health is at 3, the method is called when the players ship takes a hit. Then I need it to go health-1, and keep that value. Then when the health=0, the game will end.

Any questions and improvements to this code is welcome, as well as criticism.

UPDATED:

public static void enemyShoot (int row, int col)
{
    int shot1;
    int shot2;
    int health = 3;

    Random enemyshot = new Random();

    shot1 = enemyshot.nextInt(5)+1;
    shot2 = enemyshot.nextInt(5)+1;

    if (shot1 == row && shot2 == col)
    {
        System.out.println("You Have Been Hit");        
        health = Health(health);
    }               
}

public static int Health (int health)
{       
     if (health == 0){
        System.out.println("You dead");
        System.exit(0);
     }
     health = health-1;
     return health;
}
jww
  • 97,681
  • 90
  • 411
  • 885
John Smth
  • 31
  • 2
  • 11

5 Answers5

3

You are initializing health to 0

int health = 0;

Then when your shot hits the target you

Health(health);

Which subtracts 1 and then tests for 0

health = health-1;
 if (health == 0)

your health is now at -1 so it never == 0 You should set health to some positive value and or change your test to

if (health <= 0)
masond
  • 31
  • 4
2

When you pass health as a parameter to Health method, it makes a copy to use in this method. So, when you decrement and analyse it, the copy gets decremented to 2 (if you initially passed 3), but the original variable is still equal to 3. So, in fact, the health counter is never decremented.

It's called "passing argument by value", you can check out this question: What's the difference between passing by reference vs. passing by value?

The right thing to do is to decrement the value inside your method and then return the result. You should also call your method like this:

health = Health(health);

Also, arsendavtyan91 is right, you start with health = 0... you might want to pass the actual value to the method enemyShoot

Community
  • 1
  • 1
Igor Deruga
  • 1,504
  • 1
  • 10
  • 18
  • By decrement the value inside the method, wouldn't health = health-1 be good or not? – John Smth Dec 07 '16 at 19:52
  • Yep, that part is ok. But then you should return the value from the method and assign it to the variable health in the enemyShoot method. Change void to int in the Health method definition and add "return health;" in the end of the method. – Igor Deruga Dec 07 '16 at 19:55
  • I did that but the game still continues on even when I have been hit more than 3 times. Any ideas why? – John Smth Dec 07 '16 at 19:58
  • Can you update the code in your question with the new version? – Igor Deruga Dec 07 '16 at 20:00
  • Yes sir give me a minute – John Smth Dec 07 '16 at 20:05
  • Cool! It's closer to your goal. But now, think about calling the enemyShoot method. You call it, it initializes health to 3, if you are hit, it decrements it to 2. Now, you shoot, then you call enemyShoot again, but it initializes health to 3 again! Basically, you have to create a new parameter in enemyShoot, right after int col and pass the current value of health to this method. But again, you have to return the changed value from enemyShoot like you did with Health method! – Igor Deruga Dec 07 '16 at 20:24
  • I feel stupid, thank you for your patience and amazing advice! – John Smth Dec 07 '16 at 20:26
1
  1. You need not subtract if health is equal to zero.

  2. The game will continue since you always initialize health on the line int health = 3; in the enemyShoot() method, right before going to call the Health() method.

So I suggest you declare health inside the class (like a global variable) and initialise it by passing it to the a constructor like this:

int health;
public ClassName(int health){//this is a constructor with the `health` argument
    this.health = health;
}

public static void enemyShoot (int row, int col)
{
    int shot1;
    int shot2;

    Random enemyshot = new Random();

    shot1 = enemyshot.nextInt(5)+1;
    shot2 = enemyshot.nextInt(5)+1;

    if (shot1 == row && shot2 == col)
    {
        System.out.println("You Have Been Hit");


        health = Health(health);
    }


}


 public static int Health (int health)
{

     if (health == 0){
         System.out.println("You dead");
         System.exit(0);
     }
     health = health-1;
     return health;
}
Young Emil
  • 2,220
  • 2
  • 26
  • 37
1

First, you should really read more about the basics of object oriented programming. My answer is based on that little snippet of code you provided, so I'm not sure if there already is a proper implementation...

However, I think what you want is to create a Battleship Object, which has initial health as a member variable. You could define coordinates, orientation etc with parameters, but I'll leave them out from this example. After you have managed to create this object, use enemyShoot method to calculate if battleship has been hit and decrease health that is the case. Which comes out something like this:

public class Battleship {

    int m_health;

    public BattleShip() {
        m_health = 3;
    }

    public enemyShoot(int x, int y) {
        // TODO: calculate if hit
        if (hit == true) {
            m_health--;
            if (m_health == 0)
                System.out.println("You dead");
            System.exit(0);
        }
    }
}

So to use the code above I would put it in a file called Battleship.java and create a main method which would initialize the objects I wish to use

public static void main(String ... args) {
    Battleship bs = new Battleship(); // <-- Creates a new Battleship object
    bs.enemyShoot(0,0); // <-- shoot the battleship
    bs.enemyShoot(0,0);
    bs.enemyShoot(0,0); // <--At this point battleship would be destroyed, if hit
}

The problem with the Health method you provide is that is takes primitive data type int as parameter (initially set as 0) which gets assigned -1 every time Health is called. Callign this method does not have affect on health value inside enemyShoot method, since this is NOT an Object but a inner method variable of primitive data type.

Hope this helps you to get on with your assignment. :)

pnkkr
  • 337
  • 3
  • 15
  • Can you give me an example of making the object for this class? I'm not familiar as well as I should be with OOP. – John Smth Dec 07 '16 at 20:02
  • Well, to use the code i provided above I'd put it in a file called Battleship.java and provide a main method which would create the initial objects to – pnkkr Dec 07 '16 at 20:23
1

You were close with your Health method, what you would want is something like this:

public static void hit() {
    this.health--;
     if (health <= 0) {
         System.out.println("You died.");
         System.exit(0);
    }
}

Java is a pass-by-reference so you need to update the health of the object that just got hit. In this case I am assuming your Health() is inside of that object.

Otherwise you start with your health = 3; and every time it gets hit it will become health = 2; but the object that is being hit will always stay at 3 health. Again, without seeing any more of your code I can't tell exactly the best way to do this, so I had to assume a few things.

It should be noted that this will exit the program very quickly and you won't even see the You died message.

Matthew Brzezinski
  • 1,685
  • 4
  • 29
  • 53