Hi there people, i did try to randomly take 3 element(buttons) from an array and make them visible. and i did that, but there is a problem. When same element got selected randomly, one of them goes selected.visible = false

so what i need is, first: make that same button doesn't selected randomly same time or: its okay the return with the same button, but make it visible.

but, dont no how. i even supprise how did i write this down, i mean im pretty noob =) =) =)

soo, need help.

https://streamable.com/eecr0x

this is my code:

    onready var ability1_a = get_node("ability1")
    onready var ability2_a = get_node("ability2")
    onready var ability3_a = get_node("ability3")
    onready var ability4_a = get_node("ability4")
    onready var ability5_a = get_node("ability5")
    onready var ability6_a = get_node("ability6")
    onready var ability7_a = get_node("ability7")
    onready var ability8_a = get_node("ability8")
    onready var ability9_a = get_node("ability9")
    
    
    func _on_Button_pressed():
    	randomize()
    	var ability_select = [ability1_a,ability2_a,ability3_a,ability4_a,ability5_a,ability6_a,ability7_a,ability8_a,ability9_a]
    	var selected_1 = ability_select[randi() % ability_select.size()]
    	var selected_2 = ability_select[randi() % ability_select.size()]
    	var selected_3 = ability_select[randi() % ability_select.size()]
    
    
    
    	selected_1.visible = true
    	selected_2.visible = true
    	selected_3.visible = true
    
    	selected_1.set_position(Vector2(-10,0))
    	selected_2.set_position(Vector2(115,0))
    	selected_3.set_position(Vector2(240,0))
    
	print ("first: "+selected_1.name,"      second: "+selected_2.name,"     third:  "+selected_3.name)    

also every TextureButton has this code on it:

	func _on_ability8_pressed():
	game_start_t.start(3)
	$ability1.visible = false
	$ability2.visible = false
	$ability3.visible = false
	$ability4.visible = false
	$ability5.visible = false
	$ability6.visible = false
	$ability7.visible = false
	$ability8.visible = false
	$ability9.visible = false

I would use a for loop to handle this, as then you can do it arithmetically and if there is a duplicate, just keep looping until you find a unique element. Something like this (untested):

# The array. I left it empty for this example but you will
# want to fill it with your values.
var ability_select = []
# Another array to contain the randomly selected values
var randomly_selected_abilities = []

# Get three random elements from the array
randomize()
for i in range(0, 3):
	var random_element = round(rand_range(0, ability_select.size()-1)
	if randomly_selected_abilities.has(random_element):
		i -= 1
		continue
	else:
		randomly_selected_abilities.append(i)

# Make the abilities visible and position them, as in the OP example
var pos_horizontal_offset = 105
var pos_horizontal_start = -10
for i in range(0, randomly_selected_abilities.size()):
	var element = randomly_selected_abilities[i]
	element.visible = true
	element.position = Vector2(horizontal_start + (horizontal_offset * i), 0)
	print (element.name, " was selected!")

Thank you for answer.

line 22 element.visible = true return a int value, so doesn't work unfortunately.

! !

and if u have time, can you tell me pls, why the first code i written doesn't work. there is a logical problem i think but i cant point it out?

i notice that always the first one of the double that got visible = false.

i tho use difrent array for every unit and control if there is a value in the variables before enebled the visibility of the texture buttons,

func _on_Button_pressed():

	randomize()
	var ability_select = [ability1_a,ability2_a,ability3_a,ability4_a,ability5_a,ability6_a,ability7_a,ability8_a,ability9_a]
	var ability_select2 = [ability1_a,ability2_a,ability3_a,ability4_a,ability5_a,ability6_a,ability7_a,ability8_a,ability9_a]
	var ability_select3 = [ability1_a,ability2_a,ability3_a,ability4_a,ability5_a,ability6_a,ability7_a,ability8_a,ability9_a]
	
	var selected_1 = ability_select[randi() % ability_select.size()]
	var selected_2 = ability_select2[randi() % ability_select2.size()]
	var selected_3 = ability_select3[randi() % ability_select3.size()]



	if selected_1:
		if selected_1.visible == false:
			selected_1.visible = true
			print("first: "+selected_1.name)
			selected_1.set_position(Vector2(-10,0))
	if selected_2:
		if selected_2.visible == false:
			selected_2.visible = true
			print("second: "+selected_2.name)
			selected_2.set_position(Vector2(115,0))
	if selected_3:
		if selected_3.visible == false:
			selected_3.visible = true
			print("third: "+selected_3.name)
			selected_3.set_position(Vector2(240,0))

this time, when same number came, second one do not return a value: like this:

https://streamable.com/5sxynv

So, the issue on line 22 was my bad. I thought the data stored in the array was different and forgot how I initially planned to handle it. The following code below should work:

var ability_select = []
var randomly_selected_abilities = []

randomize()
for i in range(0, 3):
	var random_element = round(rand_range(0, ability_select.size()-1)
	if randomly_selected_abilities.has(random_element):
		i -= 1
		continue
	else:
		randomly_selected_abilities.append(i)

var pos_horizontal_offset = 105
var pos_horizontal_start = -10

for i in range(0, randomly_selected_abilities.size()):
	# Get the index of the item in the array (just like before)
	var chosen_element = randomly_selected_abilities[i]
	# But now, use that index to get the element from the original array!
	# This is what was causing the issue before, I think.
	var element = ability_select[chosen_element]
	element.visible = true
	element.position = Vector2(horizontal_start + (horizontal_offset * i), 0)
	print (element.name, " was selected!")

well i edit it like this

	element.set_position(Vector2(pos_horizontal_start + (pos_horizontal_offset * i), 0)) 

it run the game without error but result is every time same numbers return

!

this code return a randomly elements from array, but as a whole the show them as buttons var random_element = round(rand_range(0, ability_select.size()-1))

!

edit:

when godot run this line

if randomly_selected_abilities.has(random_element):

values change to: 0,1,2

! !

first 3 element of array aparently. looking way to fix it right now.

edit 2:

well i have day job, soo time to sleep =)

My bad, the issue is that it is appending i to the array rather than random_element. The following code should fix the issue:

for i in range(0, 3):
	var random_element = round(rand_range(0, ability_select.size()-1)
	if randomly_selected_abilities.has(random_element):
		i -= 1
		continue
	else:
		# This is the line of code that changed!
		randomly_selected_abilities.append(random_element)

If you would like to use your first option: select buttons but never have it selected more than once

This should help you along the way:


func _on_Button_pressed():

	randomize()
	
	# create an array with the indices from the first array -> 0, 1, 2, ..., n-1
	var indices = range(ability_select.size())
	
	# shuffle it, array will now contain 1, 7, n-1, 3, ... (randomly)
	indices.shuffle()

	# use the first 3 items of indices to get to random element in ability_select
	for i in range(3):
		var random_element = ability_select[indices[i]]

Hi,

If you would like to use the "first" option: "randomly select buttons, but do not have the same button selected multiple times"

Then you could use this:

partial code to show how to achieve this:

func _on_Button_Pressed():
	
	randomize()

	# create an array with the indices from the first array -> 0, 1, 2, ..., n-1
	var indices = range(ability_select.size()) 

	# shuffle it, array will now contain 7,1,n-1,... (randomly)
	indices.shuffle()

	# use the first three items of indices as this contains random indices to use from ability_select
	for i in range(3):
		var random_element = ability_select[indices[i]]
		# ...

Thank you two both, in the end i combine the both awnsers =) and it works.

func _on_Button_pressed():
	randomize()
	var ability_select = [ability1_a,ability2_a,ability3_a,ability4_a,ability5_a,ability6_a,ability7_a,ability8_a,ability9_a]
	
	
	var indices = range(ability_select.size())
	
	indices.shuffle()
	
	
	for i in range(3):
		var random_element = ability_select[indices[i]]
		print (random_element.name)
		random_element.visible = true
		var pos_horizontal_offset = 105
		var pos_horizontal_start = -10
		
		random_element.set_position(Vector2(pos_horizontal_start + (pos_horizontal_offset * i), 0)) 

https://streamable.com/2o42gz

2 years later