I am getting an [ invalid operands 'int' and 'object' in operator '==' ] error when I try adding a number

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By YusukeHashi

Hi guys. I am trying to make my first simple game (similar to the Simon Says but with 9 buttons) and I got stuck at the part where I have to manually give some input to the program.

On the function “func _on_button_pressed():” if I just return a random number (for example 4) the program will just run as normal, but if I try to add some input by myself I will run into an error [ invalid operands ‘int’ and ‘object’ in operator ‘==’ ]

Could you help me understand why is that happening?

Thanks in advance

extends GridContainer

export(ButtonGroup) var group

var random_number = 0
var start_game = true
var beatSeq = Array()
var userSeq = Array()
var buttonPressed = 0

func _ready():

for i in group.get_buttons():
	i.connect("pressed", self, "_on_button_pressed")

while start_game:
	random_number = random_number_generator()

	var buttonPressed = _on_button_pressed()
	print("UserPressed is " + str(buttonPressed))

	var result = check_seq(beatSeq, userSeq)

	if beatSeq.size() > 3:
		start_game = false


func _on_button_pressed():
	for i in group.get_buttons():
		if i.is_pressed():
			if i.get_name() == "a1":
				return 0
			elif i.get_name() == "a2":
				return 1
			elif i.get_name() == "a3":
				return 2
			elif i.get_name() == "b1":
				return 3
			elif i.get_name() == "b2":
				return 4
			elif i.get_name() == "b3":
				return 5
			elif i.get_name() == "c1":
				return 6
			elif i.get_name() == "c2":
				return 7
			elif i.get_name() == "c3":
				return 8
#		yield()
		return 4

func random_number_generator():
	var rndNum = 0
	for n in range(0, 1):
		rndNum = randi() % 9
	return rndNum

func check_seq(sequence, attempt):
	var result = false
	var k = 0
	for i in sequence.size():
		if sequence[i] == attempt[i]:
			result = true
			k += 1
			result = false
	return result

At what line/point is the error invalid operands 'int' and 'object' in operator '==' being returned?

Ertain | 2022-07-18 17:17

I am getting that happening inside the “func check_seq()” at this point:

if sequence[i] == attempt[i]:

I am trying to figure it out by myself but it is difficult to comprehend it.

When I hover over the sequence[i] I get sequence:[8], and when I hover over the attempt[i] I get attempt:[[EncodedObjectAsID:32330]].

Does that tell you anything?

YusukeHashi | 2022-07-18 17:29

Add a break point at the line that is causing the issue. Then look at the variable values in the memory. The error is saying your comparing an integer to an object, so looking at the variables’ values at the error line will tell you which variable has an invalid value. That should help you find the source of the issue.

godot_dev_ | 2022-07-18 19:02

I have no idea what could be causing it. It is my second week with Godot and I don’t have much experience coding.

On the other hand, running this code and looking at the output is giving me a hard time to figure out what is happening.

For example, sometimes, when I run the code it gives me something like this:

UserPressed is Null
[5, 2]
UserPressed is Null
[5, 2, 7]
UserPressed is Null
[5, 2, 7, 8]
UserPressed is Null
[5, 2, 7, 8]
[4, 4, 4, 4]

Where it shows that userPressed is Null but the at the end it gives me [4,4,4,4] which is the number I gave it.

Maybe my fault for starting a project that is too complex for me.

YusukeHashi | 2022-07-18 19:47

:bust_in_silhouette: Reply From: DaddyMonster

The issue is exactly exactly what godot says it is: attempt is an array of ints and sequence is an array of objects. You can’t evaluate those different data types.

Easily fixed. Add a script to your button object and add a member variable.

var button_seq

Give each button instance the appropriate button_seq int value obviously. Then just pick up the value:


That’s all you need do.

ps. quick tip to make your life easier: all of these if i.get_name() == "a1": could be replaced with a single dictionary. So the method could shorter / easier to read / more manageable / more performant:

var btns = {"a1": 0, "a2": 1, "etc": 123}

func _on_button_pressed():
    for b in group.get_buttons():
        if b.is_pressed():
            return btns[b.get_name()]
        return 4

The convention is to reserve the variable name i for integers in a loop so I changed it to b.

Thank you so much for taking the time to answer me.

I have one question tho, and my apologies if it does not make sense, I am just trying to figure out things:

If the buttons are already rigged and they are displaying and returning something, why do I need to add a script to each one of them?

I actually rigged them with a group of buttons. Maybe by having a look to what I’ve got makes more sense: https://drive.google.com/drive/folders/1nI0FocfV2GpD3zGOUP-d4VmkuuAu5teU?usp=sharing

On the other hand, I do agree with making the dictionary and I will keep this in mind for the next time.

Again, thanks and sorry for the headaches.

YusukeHashi | 2022-07-18 20:21

Most welcome! I’m hoping that answering some questions will help me ignore the sweltering heat here! :slight_smile:

Ah, you’ve linked the code. Let me download and take a look.

DaddyMonster | 2022-07-18 20:51

I hope you don’t mind but I redid the project. Working version here:

Beat Repeat copy – Google Drive

Things I changed:

  1. I made the button a scene. Rule of thumb: anything in Godot that has more than one instance should be a scene. Actually, it’s pretty much a cast iron rule. Even a lot of things you only have one of should be its own scene.
  2. I spawned the buttons in code, named them, positioned them and gave them an id. The “spacing” value controls their distancing if you want to adjust.
  3. I added a signal and a member variable to the Button scene.
  4. I used the inbuild Godot rng object for the random sequence.
  5. I made the button call the parent node when it was pressed and when that was as long as the beat seq I totted up the scores.

Everything else I deleted. I think only two or three lines of your code survived… Sorry!!! Don’t mean to be mean! It’s a lot shorter even though it’s doing more by spawning the buttons and it’s simpler.

DaddyMonster | 2022-07-18 21:44

You are a legend! I will check it out later.

I am so amazed that you took the time to give this idea a try and reworked it yourself. I am sure that this will help me to compare my version with yours and learn how to do things in the right way.

Thank you so much!

YusukeHashi | 2022-07-19 06:31

Hey, I had time to have a look! What a beautiful and readable way of writing code, dude. Even as a noob I can clearly understand what everything does and how it works.

Again, thank you so so much!

YusukeHashi | 2022-07-19 10:12

Most welcome! Ah, it only took 15 minutes and I quite enjoyed doing it while I was skipping the gym. :wink: Plus, we were all beginners once.

Some tips:

  1. Each method/function should ideally do one simple thing
  2. Each object should hold its own data
  3. Don’t repeat code. Don’t repeat code. Don’t repeat code.
  4. Don’t have more than one variable holding the same data. GOTO 3.
  5. Keep scope as local as it can be.
  6. Never ever hard-code data, use a data type
  7. Make distinct objects their own scene. Your player has a sword? Put it in its own scene.
  8. Long if-elif-else chains are never the best approach.
  9. Complex is life, complicated is… Something. Google “zen of python”, it’s universal.
  10. Use snake case and the gods of Godot will smile upon you.

Good luck!

DaddyMonster | 2022-07-19 10:41

Thanks a lot, legend! This will definitely help with my Godot adventure. All the best to you, my friend!

YusukeHashi | 2022-07-19 12:54