0

I was wondering if it is possible to reset the value of a variable from another class. For example I have this variable in a HillClimber (hc) class:

    public int ballWeight = 200;

What I want to do is run a simulation of a game with the ball weighting at this value. When it is finished I want to set the value to 201 from another class and begin the simulation again, and after that increase to 202 and start another and so on. My problem is that every time I restart the simulation the ballWeight variable is reset to 200. I have tried using a setter method in the HillClimber class:

    public int setBallWeight(int ballWeight) {
        return this.ballWeight = ballWeight;
    }

and called it from another class at the end of a simulation:

    hc.setBallWeight(hc.ballWeight+1);

but this does not seem to work as the variables stored value is not changed. Does anyone know how I can do this so the stored value of ballWeight will be increased by 1 each time a simulation ends? Or is this even possible? Thanks.

SAF
  • 101
  • 2
  • 2
  • 8
  • It is very possible, and the way that you describe will work; are you throwing the object away and creating a new instance by any chance? – Chris K Jun 26 '14 at 15:05
  • No I think I'm just trying to overwrite the variable, how would I go about throwing it away and creating a new one? – SAF Jun 26 '14 at 15:15
  • Where is your varibable is it in a class that is static or in a class where objects are created from? – Roan Jun 26 '14 at 15:20
  • Check the lines that write to the variable 'hc'. Perhaps place a log statement just before each one, or set a break line in a debugger. My hunch is that you have more than one instance of the object with the variable ballWeight in it. Another option would be to place a log line in the objects constructor. Failing that, then you are calling the setter more than once.. try a log line in there too. – Chris K Jun 26 '14 at 15:22
  • It is in a public class where it is initialised at 200 – SAF Jun 26 '14 at 15:23
  • Yeah there are a number of instances of the variable in other classes as it is used in the decision making system – SAF Jun 26 '14 at 15:24
  • Can you explain what you mean by *"restart the simulation"*? If you end the Java program and start it again (using `java` command or IDE's *Run* command) no variable will remember their state from the last run, for obvious reasons. You will need a mechanism to save the states persistently (into a file, registry or database) and reload them from the save on restart. – ADTC Jun 26 '14 at 15:27
  • Then double check that the instance that you are incrementing the value on is the same one each time. A good trick to verify this is to printout the identity hashcode of the object from within the setter method. eg System.out.println( System.identityHashCode(this) + "set to "+ballWeight ); Make sure that the hash code is the same each time that it is printed. – Chris K Jun 26 '14 at 15:27
  • When the simulation restarts the whole program starts again and therefore the ballWeight value is reset to 200. I was wondering if there was a way to change the hard coded value by 1 after every game ends without having to read and write the value to a file/database – SAF Jun 26 '14 at 15:37
  • That depends on how the JVM is being started. You could move the value to being fed into your program via the command line args, or even an environment variable (yuck). – Chris K Jun 26 '14 at 15:38
  • Ahright thanks, unfortunately I'm working with someone else's code so I do not know how the JVM is being started – SAF Jun 26 '14 at 15:41
  • Then I am sorry to say that you are running out of options. A file, or DB is your best bet. Depending on how much you are willing to tie yourself to an environment you could use the windows registry, or an environment variable but really a simple file would work well. – Chris K Jun 26 '14 at 15:43
  • If you do not need the number to be sequential, only growing then you could replace it with a timestamp... eg System.currentTimeMillis(). – Chris K Jun 26 '14 at 15:44
  • OK thanks a lot for your advice, I need it to be sequential and be able to record its value for each simulation so I'll go with the file, thanks again! – SAF Jun 26 '14 at 15:49

1 Answers1

3

Usually in a POJO you have what are called a getter and a setter method for every variable of the object. In your case:

public class HillClimber{
    private int ballWeight;

    public HillClimber(){
        this.ballWeight = 200;
    }

    public void setBallWeight(int ballWeight){
        this.ballWeight = ballWeight;
    }

    public int getBallWeight(){
        return this.ballWeight;
    }
}

In this way you can access the variable ballWeight via get and set method. You don't access it directly like in hc.ballWeight, which is possible but is a bad practice, and prevent this access type declaring your variable as private (meaning that only the class in which it is declared can directly access it).

To fullfill your request of adding one at every run of the game you can therefore call

hc.setBallWeight(++hc.getBallWeight()); //Equivalent to hc.setBallWeight(hc.getBallWeight() + 1);

I usually don't use this approach if the class isn't automatically generated (as in an Hibernate context), but instead declare another method in the HillClimber class

public void incrementBallWeight(int ballWeightToAdd){
    this.ballWeight += ballweiGhtToAdd; //Equivalent to this.ballWeight = this.ballWeight + ballweiGhtToAdd;
}

or if I always need to add only one to my variable

public void incrementBallWeight(){
    this.ballWeight++;
}

and then simply call incrementBallWeight after every game run.

NB: to have this working you will have to use always the same instance of HillClimber. In your main

public class Game{
    private HillClimber hc = new HillClimber(); //Create the instance and sets ballWeight to 200
    public static void main(String[] args){
         playGame();
         hc.incrementBallWeight(); //ballWeight == 201

         playAnotherGame()
         hc.incrementBallWeight(); //ballWeight == 202 -> Always the same instance of HillClimber (hc)
         .
         .
         . 

    }
}

EDIT

I think your problem is greater than that. You are asking to save the state of a variable ( meaning that this value should be available also if you turn off and on your pc) without using a permanent storage. This is simply unachievable.

You should rethink your program (and I mean java program, not a "game run") to not stop after every game run. You can do this in different ways: via Swing GUI, via user input from stdin and so on. If you want some help on this topic, we need to know more of your code (maybe putting the whole of it is best).

OR you can use a file to store your value, which is not as difficult as you think. (Also).

Community
  • 1
  • 1
Narmer
  • 1,414
  • 7
  • 16
  • Nice answer! You may want to further expand on `static` variables. For example, a `static` variable in `HillClimber` class could count how many `HillClimber`s were instantiated. Or one could keep some other data that pertains to all `HillClimber`s as opposed to any `HillClimber` in particular. – ADTC Jun 26 '14 at 15:33
  • Thanks for the answer, I tried it there but the variable still gets reset to 200 after every game ends. Is there a way to change the hard coded value without reading and writing the value to a file/database each time? – SAF Jun 26 '14 at 15:40
  • If you mean if there is a way to store a runtime volatile value of a variable outside the runtime and without a permanent storage the answer is no. And the question makes no sense because you want to store a variable without storing it. Every time you run a java program and set variables in your objects, when the java program ends those variables are wiped out. – Narmer Jun 26 '14 at 15:44
  • Yeah I was wondering if there was a way for the JVM to change the hard coded variable after each game but didn't think it was possible, thanks for your help. – SAF Jun 26 '14 at 15:51
  • I did try the file method but I am speeding up game play for quick statistics capture and when using the file option the game play cannot be sped up for some reason, thanks again for your advice. – SAF Jun 26 '14 at 17:34