There's a better way to do this, right?

Godot Version

4.2

Question

The purpose of this code is so that if any of the listed bools are true, then the “master bool” will become true. There can only be one true bool at any given time.

With my smooth brain, I came up with this:

var bool_0: bool = false
var bool_1: bool = false
var bool_2: bool = false

master_bool: bool = false

func _process(delta):
  
  if bool_0 == true or bool_1 == true or bool_2 == true:
    master_bool = true
  else:
    master_bool = false

It defiantly does the , but I plan to use more than just 3 bools and putting “if _ is true or” all in a line is not only inefficient, but just messy and ugly.
I feel there’s got to be a more efficient way to do this. Maybe involving a for loop?

Here’s one solution I worked out for myself just now, not sure if it will work though.

var bool_0: bool = false
var bool_1: bool = false
var bool_2: bool = false

var values = [bool_0, bool_1, bool_2]

master_bool: bool = false

func _process(delta):

  func bool_active():
    for value in values:
      if value == true:
        return true
      else:
        return false

  if values.bool_active() == true:
    master_bool = true
  else:
    master_bool = false

Am I on the right track on this? Feel free to correct me on this.

1 Like

I’m using C# but I’m sure there’s a GDscript equivalent. I put all my bools into an array and check to see if they all have a true or false value.

		if (values.All(item => item == true))
		{
			planetImage.SetPixel(x,y,colorMaxima);
		}
		else if (values.All(item => item == false))
		{
			planetImage.SetPixel(x,y,colorMinima);
		}
	}
2 Likes

You could simplify the code by doing the assignment without branching like this:

master_bool = bool_0 or bool_1 or bool_2

or you could use the bool_0 or bool_1 or bool_2 directly without master_bool.

However, the most elegant solution is probably bit flags. An integer in GDscript has 64 bits, so you can store 64 boolean values in a single integer. There are plenty of tutorials for bit flags and bitwise operations, but here are the most important things to know.

Checking if any of the bits are 1:

if flags != 0:

Reading a single bit:

# bit_index is a value from 0 to 63 inclusive
if flags & (1 << bit_index):

Flipping a bit:

flags ^= 1 << bit_index

Setting a bit to 1 or 0:

# value is either 1 or 0, and the bit needs to be 0 before setting its value
flags |= value << bit_index

Setting a bit to 1:

# In this case the bit doesn't need to be 0 before setting its value
flags |= 1 << bit_index

Setting a bit to 0:

flags &= ~(1 << bit_index)
1 Like

Bit flags could be helpful, some things I recently found about it:

The above statement means we can take a shortcut: instead of having a lot of bools, you could instead have one var which stores an index of which “bool” is the true one (or none at all). The bool indexes can be assigned via an enum where each value corresponds to a bool, (plus an all-bools-false option, which we’ll designate as value 0 so it will evaluate to false).

enum State{ NONE_TRUE=0, BOOL1_TRUE, BOOL2_TRUE, BOOL3_TRUE}
var current_state = State.NONE_TRUE

func _process(delta):
	# set bool1 true
	current_state = State.BOOL1_TRUE
	if current_state: # checking the "master bool"
		print('1: one of the bools is true')
	else:
		print('1: none true')
	if current_state == State.BOOL1_TRUE: # checking bool1
		print('1: bool 1 true')

	# set all bools false
	current_state = State.NONE_TRUE
	if current_state: # checking the "master bool"
		print('0: one of the bools is true')
	else:
		print('0: none true')

This will output:

1: one of the bools is true
1: bool 1 true
0: none true

This solution also has the nice benefit of guaranteeing that max 1 bool will ever be true at any time, since changing the current_state’s value will automatically “unset” whichever other bool is set.

2 Likes

You could simplify to something like this:

var bools := [false, true, false]
var master_bool := false


func _ready() -> void:
	master_bool = bools.any(bool_is_true)
	print(master_bool)


func bool_is_true(flag: bool) -> bool: 
	return flag
2 Likes