+1 vote

Trying to apply procedural generation in my project, but I've got confused with dictionary. I'm certainly doing something wrong. I'm inserting currenttile which is a vector2 (as a key) and var blockcombination which is array of one or two numbers (as a value). Code is inside while loop and works as intended on first go, but something not right happens on the next goes and output shows that dictionary gets the key but value is assigned onto the first of the keys and rest of the values in keys changes into this weird array with ellipsis inside. I would really appreciate any input.

This is the code:

if (clear_tile == 0 or next_tile in empties) and one_after in unvisited and not block_combination.has(0):
    Map.set_cellv(next_tile, 4)
    print("chose empty")
    if neighbours.size()> 1 and not block_combination.has(2):
        block_combination.append(0)
        blocks_c[current_tile] = block_combination
        print("current_tile : ", current_tile)
        print("block_combination : ", block_combination)
        print("blocks_c current's tile value: ", blocks_c[current_tile])
        print("all of blocks_c: ", blocks_c)
        print("blocks_c's keys: ", blocks_c.keys())
        print("blocks_c's values:  ", blocks_c.values())
        blocks_d[current_tile] = direction
    current_tile = next_tile
    next_tile = one_after
    empties.append(current_tile)
else:
    print("got to Ds")
    if not block_combination.has(2):
        var two_ways = cell_walls[direction]
        var lucky_dip = randi() % 2
        var d_a  = direction_after[two_ways[lucky_dip+2]]
        if next_tile + d_a in unvisited:
            print("turn d1")
            Map.set_cellv(next_tile, two_ways[lucky_dip])
            if neighbours.size() > 1:
                if not block_combination.has(1):
                    block_combination.append(1)
                blocks_c[current_tile] = block_combination
                blocks_d[current_tile] = direction
                print("current_tile : ", current_tile)
                print("block_combination : ", block_combination)
                print("blocks_c current's tile value: ", blocks_c[current_tile])
                print("all of blocks_c: ", blocks_c)
                print("blocks_c's keys: ", blocks_c.keys())
                print("blocks_c's values:  ", blocks_c.values())
                print("block d1 given")
            current_tile = next_tile
            next_tile = next_tile + d_a
            direction = d_a
            unvisited.erase(current_tile)
        else:
            if lucky_dip == 1:
                lucky_dip = 0
            else:
                lucky_dip = 1
            var d_a2  = direction_after[two_ways[lucky_dip+2]]
            if next_tile + d_a2 in unvisited:
                print("turn d2")
                Map.set_cellv(next_tile, two_ways[lucky_dip])
                if neighbours.size()> 1 and not block_combination.has(0):
                    block_combination.append(2)
                    blocks_c[current_tile] = block_combination
                    blocks_d[current_tile] = direction
                    print("current_tile : ", current_tile)
                    print("block_combination : ", block_combination)
                    print("blocks_c current's tile value: ", blocks_c[current_tile])
                    print("all of blocks_c: ", blocks_c)
                    print("blocks_c's keys: ", blocks_c.keys())
                    print("blocks_c's values:  ", blocks_c.values())
                    print("block d2 given")
                current_tile = next_tile
                next_tile = next_tile + d_a2
                direction = d_a2
                unvisited.erase(current_tile)

And this is output:

got to clear
chose empty
currenttile : (6, 2)
block
combination : [0]
blocksc current's tile value: [0]
all of blocks
c: {(6, 2):[0]}
blocksc's keys: [(6, 2)]
blocks
c's values: [[0]]
current tile is: (5, 2)
neighbours are: [(5, 1), (5, 3), (4, 2)]
next tile is:(4, 2)
got to clear
chose empty
currenttile : (5, 2)
block
combination : [0]
blocksc current's tile value: [0]
all of blocks
c: {(5, 2):[...], (6, 2):[0]}
blocksc's keys: [(6, 2), (5, 2)]
blocks
c's values: [[0], [...]]
got to clear
got to Ds
turn d1
currenttile : (4, 2)
block
combination : [1]
blocksc current's tile value: [1]
all of blocks
c: {(4, 2):[...], (5, 2):[...], (6, 2):[1]}
blocksc's keys: [(6, 2), (5, 2), (4, 2)]
blocks
c's values: [[1], [...], [...]]
block d1 given

asked Apr 5 in Engine by aya9 (13 points)

The ... you are getting are probably a string containing "...". But hard to tell where it comes from, it's from outside the code you posted.

I don't know where the problem would be in your code, but:

which is array of one or two numbers (as a value).

Keep in mind arrays are reference types, regardless. If you store an array in a dictionary without making it unique (using duplicate), modifying that array later will reproduce the same change everywhere you stored it (because it's all referring to the same array).

So when you do:

var d = {}
var a = [1, 2, 3]
d["test"] = a
print("Before: ", d)
a.append(4)
print("After: ", d)

You will get:

Before: {test:[1, 2, 3]}
After: {test:[1, 2, 3, 4]}

See how the array in the dictionary also changed, because it is the same array.
But if you do:

var d = {}
var a = [1, 2, 3]
d["test"] = a.duplicate()
print("Before: ", d)
a.append(4)
print("After: ", d)

You will get:

Before: {test:[1, 2, 3]}
After: {test:[1, 2, 3]}

Because the array inside the dictionary is a copy of the array before it was modified later.

Thank you for replying and trying to help me with the problem. I understand what you are saying but that is not where the problem is. If you look at that part of the output:

currenttile : (4, 2)
blockcombination : [1]
blocksc current's tile value: [1]
all of blocksc: {(4, 2):[...], (5, 2):[...], (6, 2):[1]}

Especially the last line should really look like this: all of blocksc: {(4, 2):[1], (5, 2):[0], (6, 2):[0]}. But it looks like it is only applying value to the first (created) key (which is (6,2)) and creating those strange arrays inside any new keys. Even if for some reason the output is showing them as this, it shouldn't be applying the value only to the first created key. You can see that from code and output that tile is changing and value is changing but output shows that it is applied only to the first created key of the dictionary, while changing others to those ellipsis ones.

I've changed blockcombination from array to regular variable and it doesn't give me that problem. Will see if I can work around that code like that. But I still would like to know why did it behaved like that.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.