|
|
|
|
Reply From: |
Robotex |
Here is my variant of solution of this problem:
extends Node
var arr = ["Tst1", "Tst2", "Tst3", "Test4", "Test5", "t1", "t2", "tt1", "tt2"]
var dict_arr = [{"value": 50}, {"value": 100, "name": "test1"}, {"value": 100, "name": "test2"}, {"value": 20}, {"value": 110, "name": "test3"}, {"value": 110, "name": "test4"}, {"value": 110, "name": "test5"}]
func _ready():
randomize()
print(random_element(arr))
print(random_element_with_biggest_property(dict_arr, "value"))
print(random_element_with_condition(arr, funcref(self, "lengthBigger2")))
print(random_element_with_condition(arr, funcref(self, "lengthBigger3")))
print(random_element_with_condition(arr, funcref(self, "lengthBigger4")))
func random_element(array):
return array[randi() % array.size()]
func random_element_with_biggest_property(array, property : String):
if array.empty():
return null
var accepted = []
var biggestValue = array[0].get(property) if property in array[0] else null
for element in array:
if property in element:
var value = element.get(property)
if value > biggestValue:
accepted.clear()
biggestValue = value
accepted.append(element)
elif value == biggestValue:
accepted.append(element)
if accepted.empty():
return null
else:
return random_element(accepted)
func random_element_with_condition(array, conditionalFunc : FuncRef):
if array.empty():
return null
var accepted = []
for element in array:
if conditionalFunc.is_valid() and conditionalFunc.call_func(element):
accepted.append(element)
if accepted.empty():
return null
else:
return random_element(accepted)
func lengthBigger2(element):
return element.length() > 2
func lengthBigger3(element):
return element.length() > 3
func lengthBigger4(element):
return element.length() > 4
Can you review it? What problems does it have? What is about performance?
Is it possible to find more elegant solution?
I’m a little confused, in your question you call them objects with properties, but here they seem to be string literals with loosely associated values in a dictionary (the string literals in your dictionary do not exactly match your capitalization in your array, and the first item in your dictionary has no “name” key).
When I read your question I expected custom objects with member variables as properties, which is probably how I would do it. Do these objects have representation in your game beyond “test” (are they monsters, players, items, etc)? The solution you’ve got now adds a convoluted (IMO) layer of abstraction that divorces the original data from how you want to manipulate it. In other words, those dictionaries have to be populated somehow, and you may introduce bugs in the transcription process that can be difficult to diagnose. If you instead used an array of references to objects in memory, potentially with a custom class (declared at the top of the object’s script with the class_name
keyword in GDScript), you could construct a for
loop to iterate over the collection, creating another collection of references based on some condition, and then randomly choosing out of that second collection.
A hypothetical example using custom objects with class_name
keyword and for
loop member variable checking (not a complete implementation of what you want, but hopefully will get you there):
Class1.gd:
extends Object
class_name Class1
var foo = 20
var bar = "spam"
Class2.gd:
extends Object
class_name Class2
var foo = 20
var baz = "runcible"
debug_scene.gd:
extends Node2D
var collection = []
func _ready():
for i in 10:
var object1 = Class1.new()
var object2 = Class2.new()
collection.push_back(object1)
collection.push_back(object2)
for item in collection:
print("item number", collection.find(item))
if "foo" in item:
print("item has member variable foo")
if "bar" in item:
print("item has member variable bar")
if "baz" in item:
print("item has member variable baz")
output:
item number0
item has member variable foo
item has member variable bar
item number1
item has member variable foo
item has member variable baz
item number2
item has member variable foo
item has member variable bar
item number3
item has member variable foo
item has member variable baz
...
in your question you call them objects with properties, but here they
seem to be string literals with loosely associated values in a
dictionary
it will be scene nodes and gdscript objects in the real game. I guess, that interface the same as with the dictionaries
Robotex | 2020-08-06 17:04