tags:

views:

117

answers:

4

A newbie question. I have the following piece of Java code:

 import acm.program.*;
 import java.awt.Color;
 import acm.graphics.*;

 public class ufo extends GraphicsProgram{

    private GRect ufo_ship;
    boolean hasNotLost;
    public void run (){
     setup(); //places ufo_ship to initial position
     hasNotLost = ufo_ship.getY() < 200; //checks if ufo_ship is 
                               //above the bottom edge of window
     while(hasNotLost){
      move_ufo(); //moves ufo_ship
     }
     showMessage(); //shows that program ended
    }
//remaining methods are here
}

When I run this code, the rectangle ufoship does not stop when it reaches the bottom of the window. I assume, that it's because it checks position of the ufoship only once, and not every time the rectangle moves.

Is there any way to correct it without writing simply while(ufo_ship.getY() < 200)?

+4  A: 

hasNotLost = ufo_ship.getY() < 200; <- Does not assign expression to the variable, but the value to which that expression is being computed, so it of course is computed only once. You can extract it to other method

boolean hasNotLost(GRect ufo_ship){ return ufo_ship.getY() < 200; }

while(hasNotLost(ufo_ship))
{
  ...
}

ufo could have own class and that method so you would just call while(ufoShip.hasNotLost())

Luno
+1 for intuiting that the questioner might be assigning the expression to the variable, which is exactly what I thought they might be doing.
Tony van der Peet
Factoring the condition out to a function removes the duplication and serves the same purpose as the variable, which is stating exactly what the condition means.
Carl Seleborg
Thanks for answer.Creating a new method hasNotLost is the best solution, because I'd like to add more conditions that end the program.
Nikita Barsukov
+1  A: 

There is a number of ways you could do this, one of which you have highlighted in your question:

while(ufo_ship.getY() < 200)

You could also do:

while(hasNotLost) { move_ufo(); hasNotLost = ufo_ship.getY() < 200; }

Or could pass hasNotLost by reference into move_ufo() and do the check at the end of move_ufo(), or you could even integrate the check into move_ufo, and return false from it, so you could simply say:

while(move_ufo()) {}
Tim
+1  A: 
while(hasNotLost){
    move_ufo(); //moves ufo_ship
    hasNotLost = ufo_ship.getY() < 200; //checks if ufo_ship is 
                                        //above the bottom edge of window
}
Piskvor
A: 

No, in your example code, you evaluate hasNotLost once and use that (now static) value in the while statement. It will always be true (as evaluate initially)

The proper solution is indeed

while(ufo_ship.getY() < 200) {
  move_ufi();
}

or extract a method an do something like

while(ufoStillOnScreen(ufo)) {
  move_ufi();
}

and evaluate the position in that extracted method.

Andreas_D