randomuser wrote ...

2019/9/17

## Checking arrangements of actors

randomuser

2019/9/17

Hi! I'm making a water pipe style game and I'm struggling to figure out how to check whether the pipes are arranged correctly. I've got booleans for checking if the pipe faces a direction, eg:
```public boolean hasTop()
{
if(image == 0 || image == 3 || image == 4 || image == 7){return true;}
else{return false;}
}```
(image is a variable to change the appearance of the pipe) However, I dunno how to check whether the surrounding pipes align (as in if a pipe has a top, check that for the one above hasBottom = true), and how to use this in a loop to check whether there's a full path between the start and end points
danpost

2019/9/18

If the cells in your world have a size equal to your images, then a boolean array of length 4 might be helpful -- one that stores the open paths of the given pipes. From any location, the indices of the array, multiplied by 90, will "point" in each of the 4 directions. Each index can then be broke down into its graph offsets, dx and dy:
```// using the following array for a pipe
private boolean[] openPath = { false, false, true, true }; // top to left "L" pipe

// to check a pipe's connections
for (int i=0; i<4; i++)
{
if (openPath[i] != true) continue; // pipe does not go in current direction
// get offsets where a fitted pipe should be
int dx = (1-i)%2;
int dy = (2-i)%2;
// get pipe (if there)
Pipe pipe = (Pipe)getOneObjectAtOffset(dx, dy, Pipe.class);
// check existence of pipe and its conectivity
if (pipe != null && pipe.openPath[(i+2)%4] == true) continue; // no problems
// problem
System.out.println("Missing or mismatched pipe at ("+(getX()+dx)+", "+(getY()+dy)+")");
break;
}```
Here, a message is displayed to the terminal if the given pipe is not matched up properly
randomuser

2019/9/19

I tried using that, but it popped up with a null pointer exception for line 7 of your code I literally just called on it in the act() method, no on mouse click or anything (yet) Only difference is I made if statements for each type of pipe for the boolean
danpost

2019/9/19

randomuser wrote...
I tried using that, but it popped up with a null pointer exception for line 7 of your code I literally just called on it in the act() method, no on mouse click or anything (yet) Only difference is I made if statements for each type of pipe for the boolean
You will need to show your current class codes. I cannot see how you would get a null pointer exception, unless it has something to do with the mentioned if statements. However, "private", on my line 2, should be "public" (for line 14 to work).
randomuser

2019/9/20

This is my current code for the class it's in:
```public class pipes extends pipe
{
public boolean[] openPath;
public pipes(String img)
{
setImage(img);
}
/**
* Act - do whatever the pipes wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
public void act()
{
if (Greenfoot.mouseClicked(this)){
Rotate(this); //a method from the class this extends
}
Test();

}
public void Test()
{
if(image == 0){
boolean[] openPath = {false, false, true, true};
}
if(image == 1){
boolean[] openPath = {false, true, true, false};
}
if(image == 2){
boolean[] openPath = {true, true, false, false};
}
if(image == 3){
boolean[] openPath = {true, false, false, true};
}

for (int i = 0; i < 4; i++){
if(openPath[i] != true) {continue;}
int dx = (1-i)%2;
int dy = (2-i)%2;
pipe pipe = (pipe)getOneObjectAtOffset(dx, dy, pipe.class);
if (pipe != null && openPath[(i+2)%4] == true){
if (image > 3){
image = image - 4;
}
setImage(new GreenfootImage(checked[image]));
continue;
}
}

}
}
```
The error is at line 44 (if openPath != true)
danpost

2019/9/20

The scope of your boolean arrays is limited to having basically NO scope. You declare them within if blocks and have no scope outside those blocks. For example, you declare one on line 23 above and it is no longer attainable beyond line 24 (the following line which closes the block of code the array was declared in). Actually, what you are doing is creating local arrays within the if blocks by declaring them there. They do not do anything for the array declared on line 3.because you are creating new local arrays using the same name. If you did not declare new arrays within the if block and just referred to the previously named array field, it should work. For example, line 23 should be:
`openPath[i] = new boolean[] { false, false, true, true };`
I can see there is a lot to be improved upon. Having the Test method assign array values to openPath every act cycle is wasteful. If you set it initially, when created, plus once anytime it is rotated, it would save a lot of processing. You could move line 3 to the pipe class so you can work with it when being rotated.
randomuser

2019/9/20

with that, my code pops up with an error saying 'incompatible types: boolean cannot be converted to boolean' (I'm sorry about this code never quite seeming to work)
danpost

2019/9/20

randomuser wrote...
with that, my code pops up with an error saying 'incompatible types: boolean cannot be converted to boolean' (I'm sorry about this code never quite seeming to work)
Sorry -- my bad. It was supposed to be:
`openPath = new boolean[] { false, false, true, true };`