For loop stops at the middle of the loop
Asked Answered
D

3

0

I'm making an idle game about selling eggs and I want to create an egg every 2 sec. There are 5 types of eggs (as shown in the eggs array), and I have the function GenerateEgg to choose one randomly and instantiate it. Basically, the function loops over chances (a copy of eggChances) and generates a random number between 0 and 1, to determine if the egg is going to be created or not. If it isn't, the function uptades the percentages in chances (so they sum up to 1), and goes for the next element in the array.

`var eggs = ["Normal", "Half Treasure", "Treasure", "Half Trash", "Trash"]
var eggChances = [0.5, 0.15, 0.05, 0.2, 0.1]

func GenerateEgg():
var eggIndex = 0
var chances = eggChances.duplicate(true)

for egg in chances:
	var rngNum = randf_range(0, 1)
	
	if rngNum <= egg:
		print(eggs[eggIndex])
		var eggInstance
		
		match eggs[eggIndex]:
			"Normal":
				eggInstance = normalEgg.instantiate()
			"Half Treasure":
				eggInstance = halfTreasureEgg.instantiate()
			"Treasure":
				eggInstance = treasureEgg.instantiate()
			"Half Trash":
				eggInstance = halfTrashEgg.instantiate()
			"Trash":
				eggInstance = trashEgg.instantiate()
		
		eggInstance.position = conveyorBelt.get_node("Start").global_position
		eggInstance.rotation_degrees = rotation_degrees
		get_tree().get_root().call_deferred("add_child", eggInstance)
		
		break
	else:
		var lastPercentage = chances[0]
		
		chances.remove_at(0)
		eggIndex += 1
		
		for i in chances.size():
			chances[i] = chances[i] / (1 - lastPercentage)`

The problem is, the normal and both treasure eggs generate normally, but if none of them are generated the for loop just stops, it doens't even go through the rest of the array (Therefore, not generating any trash eggs). I know the problem is in the for loop because I asked it to print chances and rngNum at every iteration, and after the treasure egg it simply stops:
generate!
[0.5, 0.15, 0.05, 0.2, 0.1]
0.54929866835448 (normal egg is not generated)
[0.3, 0.1, 0.4, 0.2] (new percentages)
0.386365563353 (half treasure egg is not generated)
[0.14285714285714, 0.57142857142857, 0.28571428571429] (new percentages)
0.73908705766343 (treasure egg is not generated, nothing more printed after this)

Deathday answered 18/3, 2024 at 0:19 Comment(0)
N
0

Deathday You shouldn't be altering the array you iterate over inside the loop body.

Nealson answered 18/3, 2024 at 0:40 Comment(0)
T
0

Deathday in my experience, modifying arrays or dictionaries as you iterate very often gets weird. the best you can do instead is get clever with math and stuff.
eggs make me giggly, i'm having a hard time parsing what removing the first index in the chances array is trying to do, but it looks like you're doing it so it can add up the chances after the current iteration.
if that's all, you could replace

for egg in chances:

with:

for i in chances.size():
    var egg = chances[i]

and replace:

    chances.remove_at(0)
    eggIndex += 1
	
    for i in chances.size():
        chances[i] = chances[i] / (1 - lastPercentage)

with:

    eggIndex += 1
    
    var k = i
    while k < chances.size():
        chances[k] = chances[k] / (1 - lastPercentage)
        k += 1

that way you iterate the array the same way you were before, but without directly modifying the array as it's being iterated.
i'd also recommend static typing. it can make other bugs glaringly obvious, but to match your style, i left my modifications dynamic.
this won't fix other bugs if they exist too, i'll admit i didn't look that closely, but i hope this helps. godspeed.

Trichiasis answered 18/3, 2024 at 1:27 Comment(0)
D
0

Trichiasis Thanks, it works now

Deathday answered 18/3, 2024 at 2:26 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.