# GMS 2 [SOLVED]Looping through combinations of four booleans

Discussion in 'Programming' started by brinycann0nade, May 15, 2019 at 10:13 AM.

Tags:

Joined:
Nov 12, 2016
Posts:
14
I'm making a top down, tile-based city builder/rts where buildings have a power resource from power lines like SimCity 2000. They need power to work.

Each powerline tile looks at the surrounding tiles (25x25 pixels) and saves the id of the surrounding instances. You end up with the id's of the tile above, below, and to the left and right of the powerline. Diagonals don't count.
Code:
```//obj_humanPowerline STEP event

up = place_meeting(x, y-20, all);
right = place_meeting(x+20, y, all);
down = place_meeting(x, y+20, all);
left = place_meeting(x-20, y, all);```
(I'm aware using "all" will get anything near it but that's a problem for another day)

Here is my problem: There are so many combinations of up right down left (at least 11), that I think I have to write at least 11 if statements. This feels wrong, but I don't know a better way. A switch seems like it wouldn't work because there is more than one thing to check. My gut is telling me to use an array or data structure in some way, plus a for loop, but I'm not sure how.
Code:
```obj_humanPowerline DRAW event

if up and !right and down and !left
{
image_index = 0;
}
else if !up and right and !down and left
{
image_index = 1;
}
if up and right and down and left
{
image_index = 2;
}
//etc etc
```
In summary, I would like to be able to loop through the combinations of up right down left, without so many if statements because it feels wrong.

2. ### TimothyMember

Joined:
Aug 7, 2016
Posts:
59
Code:
```enum PowerDirectionFlags
{
None  = 0x0,
Left  = 0x1,
Up    = 0x2,
Right = 0x4,
Down  = 0x8,
All   = Left | Up | Right | Down
}```
So you would order your sub images as so:
0 none
1 left
2 up
3 left and up
4 right
5 right and left
6 right and up
7 right and left and up
8 down
9 down and left
10 down and up
11 down and up and left
12 down and right
13 down and right and left
14 down and right and up
15 down and right and up and left

On phone getting ready for work. But this is your set up, I'll post back later with how to use it... If someone doesn't already before then.

3. ### FrostyCatMember

Joined:
Jun 26, 2016
Posts:
3,960
Under Timothy's scheme, this is all it takes to set the correct frame:
Code:
```image_speed = 0;
image_index = left + (up << 1) + (right << 2) + (down << 3);
```
Though given the way directions work by default on GM, I would much rather order things right-up-left-down than left-up-right-down.

4. ### TimothyMember

Joined:
Aug 7, 2016
Posts:
59
This, except I had a bit of a different idea. I had more of this in mind
Code:
```//obj_humanPowerline STEP event
up = PowerDirectionFlags.Up * place_meeting(x, y-20, all);
right = PowerDirectionFlags.Right * place_meeting(x+20, y, all);
down = PowerDirectionFlags.Down * place_meeting(x, y+20, all);
left = PowerDirectionFlags.Left * place_meeting(x-20, y, all);
```
Then to set the image index
Code:
```image_speed = 0;
Image_index = left | up | right | down;
```
Ps. @FrostyCat I don't know why I started at left and went clockwise lol... it was early.

Joined:
Nov 12, 2016
Posts:
14
Thanks you two, it works now though I had to comment out "All = Left | Up | Right | Down" (line 8) for it to compile. It says it has a compile error when it's not commented out that says "Object: obj_humanPowerline Event: Create at line 8 : enum assignment must be an integer constant" Today is the first time even hearing about bitmasks so I don't really know what the issue was. I've tested the game and haven't had an issue yet. It works like it's supposed to now. Here's the full code:

Create
Code:
```enum PowerDirectionFlags
{
None  = 0x0,
Left  = 0x1,
Up    = 0x2,
Right = 0x4,
Down  = 0x8,
//All   = Left | Up | Right | Down
}

powered = false;

up = noone;
right = noone;
down = noone;
left = noone;
```
Step
Code:
```up = PowerDirectionFlags.Up * place_meeting(x, y-20, all);
right = PowerDirectionFlags.Right * place_meeting(x+20, y, all);
down = PowerDirectionFlags.Down * place_meeting(x, y+20, all);
left = PowerDirectionFlags.Left * place_meeting(x-20, y, all);```
Draw
Code:
```if obj_playerController.target = self.id
{
draw_sprite(spr_cursor25,0,self.x,self.y);
}

image_speed = 0;
image_index = left | up | right | down;```

6. ### TimothyMember

Joined:
Aug 7, 2016
Posts:
59
Oh sorry, I thought that was possible in GML. You can change it to either do:
Code:
```All = 0x1 | 0x2 | 0x4 | 0x8
// or
All = 0xF
//  its the value of 15 all the same
```
You could use this flag to test if the building has power from all sides

Joined:
Jun 21, 2016
Posts:
72
You're not accessing the enum properly. Should be
PowerDirectionFlags.Left |
PowerDirectionFlags.Up etc. Since you didn't access the values in the enum, it was looking for *variables* called Left and Up etc.

8. ### TimothyMember

Joined:
Aug 7, 2016
Posts:
59
Those are instance variables he defined.
Edit: unless you mean the stuff to the right of All... in that case, it isn't a scoping issue because the expression is in the enum. The problem was that GML doesn't consider that a constant expression.