Using, for in range, to create a grid and I get this unexpected behaviour

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

So here is the simple code:

extends Node

var grid := {}

var _cell_info := {
	"id": "",
	"walkable" : true,
	"move_cost" : 1,
	"unit" : null
}

func create_empty_grid(x_tiles: int, y_tiles: int) -> void:
	for x in range(0, x_tiles, 1):
		for y in range(0, y_tiles, 1):
			grid[str(x) + "," + str(y)] = _cell_info
			grid[str(x) + "," + str(y)].id = str(x) + "," + str(y)

func _ready():
	create_empty_grid(2,2)
	print(grid)

Then what I get in the output is:

{
0,0:{id:1,1, move_cost:1, unit:Null, walkable:True}, 
0,1:{id:1,1, move_cost:1, unit:Null, walkable:True}, 
1,0:{id:1,1, move_cost:1, unit:Null, walkable:True}, 
1,1:{id:1,1, move_cost:1, unit:Null, walkable:True}
}

I cant understand this madness, why on earth are the “id” values all (1,1).
It has to do with the grid size (its 2 arguments), since when I do a create_empty_grid(3,4), what I get is all the “id” are now “2,3”.
Of course I notice the pattern, but cant seem to grasp why this is happening.

:bust_in_silhouette: Reply From: Ninfur

You are assigning all grid elements to the same variable “_cell_info”. Since all grid elements point to the same variable, changing one will affect all. Try copying _cell_info before assigning it, see this post for examples

Alternatively turn _cell_info into a function that returns the same dictionary. That way a new instance will be created every call.

Thanks! that was indeed the problem. I suspected this could be the problem after posting but wasnt sure. I thought that what I was putting in the values were copies of the var

Pomelo | 2022-06-02 18:51