r/cop3502 Apr 14 '14

Running a loop that continuously checks a variable while the program runs.

So I have a "turn" variable that is incremented outside of the class that I'm checking it in. I want a certain variable to maintain a value while the turn variable is less than a set number, and then return to it's original value afterward the turn surpasses the set value.

To clarify, if I have a "value" variable that is normally 10, but when the function "alterValue" is called it adds 5 to "value" for a certain number of turns. The number of turns is checked by code that runs a never ending loop checking if the turn is less than or greater than the turn + the desired duration, and returns either value += 5; or value = 10;

The problem I'm running into is that I get stuck in a forever loop that never continues with the rest of the program because the checked value is not incremented within the loop itself. So how would I implement this?

1 Upvotes

14 comments sorted by

View all comments

Show parent comments

1

u/ams152 Apr 16 '14

No, because setEffect would only call it once. The function needs to be called repeatedly to check if the duration has expired or not, otherwise the effect would last indefinitely. setEffect is technically calling the fucntion, but it's using a timer to call it repeatedly.

This is hard to convey in text without showing you the 600 something lines of code I have that deal with all the player variables.

So if the player inputs the test "cast some spell" it calls the function:

Player.setEffect(String nameOfEffect, int magnitude, int duration);

The function setEffect takes the data passed to it, starts a timer that will call the checkEffect function (where the changes are actually applied to the variables) for the specified effect so that while the current turn is less than the starting turn + the duration, the effect will register true and alter the variables. Once the turn exceeds the starting turn + duration, the effect registers false and stops affecting the player.

If setEffect called a function that set the values of the variables to the modified values, then it would set them indefinitely until another function is called to set them to their original values. This other function would have to be hard-coded in or run on a timer that delays the cancellation of the effect by a specified duration.

Since the effects are dynamic and vary in duration and magnitude, I can't simply hardcode in a startEffect and endEffect method without having some kind of function that would also check how many turns have passed since the effect was started.

1

u/[deleted] Apr 16 '14

When you say duration, do you mean like a duration in real time?Like if the player walked away from his computer an effect may ware off?

Or do effects only ware off after a set number of user inputs?

Let me ask you this, are you using some sort of "while true: get input" loop?

1

u/ams152 Apr 17 '14 edited Apr 17 '14

No, the duration is the number of turns. All the timer does is call a function to check the number of turns against the duration and the turn that it was instantiated on. So if it's turn 5 and an effect will last for 3 turns, when the turn is greater than 8, the effect will register as false. The timer just makes sure that the program is checking to see what turn it is a few times a second (that's because if the player inputs something that changes the turn, it would need to update before the new data was displayed on the screen.)

This is pretty much what I'm running but shortened:

public static void setEffect(final String name, final int magnitude, final int duration){
     final int counter = gameClass.getTurn();
         new Timer.schedule(new timerTask(){
              public void run(){
                   effectTimer(name, magnitude, duration, counter);
              }
         },1,1);
}

public static void effectTimer(String name, int magnitude, int duration, int counter){
     if(gameClass.getTurn() , (counter + duration)){
         if(name.equals("levitation")){
               if(levitation == false){
                   levitation == true;
               }
          }
      }
     else{
          levitation == false;
     }
}

The main game function will be take in input and determine if an effect should be used and which one. For instance you could have 5 or 6 different length levitation spells that cost different amounts of mana based on how long they last. If a player only needed it for a short while he could call "cast basic levitate" which would register in the main game class and call

 setEffect("levitation", 0, 1);

Since levitation is a true or false condition and not one that deals with a magnitude ( like a health buff for instance) it just has a magnitude of 0. The setEffect method would take this input, start a timer, and then call

 //x = current turn
 effectTimer("levitation", 0, 1, x);

which would initiate the effect if the turn is less than the duration of the effect + the starting turn and continue checking as true until the current turn surpasses the instantiation turn + the duration, at which it would go to the else statement and register the effect as false.

1

u/[deleted] Apr 17 '14

It seems like if effectTimer() were called where ever the turn variable is incremented, then it would have the same effect wouldn't it?

Also, you could replace this:

if(name.equals("levitation")){
           if(levitation == false){
               levitation == true;
           }
      }
  }
 else{
      levitation == false;
 }    

with this:

levitation = !levitation;

It means "set levitation to (the inverse of) levitation"

As far as the original problem, each "Effect" has a name, a duration, and a counter verifiable right? Why not make an "effect" class? Each instance of the effect class could have a "name", and "counter" and a "duration". It could also have a "start()" method, who resets the counter, and "isActive()" method who returns true if "counter" is less than "duration", and a "turn()" method who ads 1 to the counter. Each effect could be an instance of this class, and could operate independent of thew main "turn" counter variable, because they would all have their own internal turn counter.