-
-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Array.pick_random()
as a shorthand for Array[randi() % Array.size()]
#3454
Comments
Array.pick_random()
as a shorthand for Array[randi() % Array.size()]
This is a very useful one. I've had it in a singleton for a long time, I named mine after the GameMaker function,
|
@rainlizard Yeah I had something similar which also worked with dictionaries, but I think it'd be better if it is a method so that the user will come across it when searching the class reference for the data type. Assuming the proposal gets traction I have some extra discussion topics: I mentioned Array, does it makes sense to add pick_random() to all container types?Pool/Packed*Array: C++ equivalent of How should we handle the method being called on an empty container?Option A: Return an error.The user will have to check if the container is not empty before calling pick_random() Option B: Return null.The user won't get an error when calling pick_random() but might get an error later when trying to use the returned value. Also, Option C: Return a user defined default.In this case the method signature would be Option D: Impement both A and CThis can be similar to how get_node() and get_node_or_null() work. |
I feel like Option C would be really good. |
This is implemented in Goost as
Sounds like a good idea to me at first thought. However, by picking a random element, there's an assumption that container is not empty. Returning For reference, Python raises |
It would be a good idea to add an optional parameter to this method that takes a I mainly want this for things like procedural generation, where the result needs to be deterministic and the same random number needs to be chosen every time given the same seed. Code example: var rng: = RandomNumberGenerator.new()
var array: = ["a", "b", "c", "d"]
array.pick_random(rng) # Uses the RandomNumberGenerator's randi() function
array.pick_random() # Uses the global randi() function |
This is one of the reasons why I went for implementing and exposing Also, it's too easy for randomization methods to creep into core data structures. If Godot goes this route, I think it would make sense to implement such methods in But if Godot prefers to have lean-and-mean API, then technically even what's proposed here could be achieved with # Assuming array is not empty:
array.shuffle()
var random_pick = array[0] Of course, this is at the cost of performance, because elements need to be actually rearranged in the array. |
I've added support for |
Idea: a |
I see this useful for picking elements that won't repeat (and don't need to be reused). But this is probably Goost material anyways. Added to goostengine/goost#7. Note that popping elements from the array may not be fast, since this leads to reallocation of all successor elements in the array. But this is good enough for small arrays, should be documented. But this could also be optimized by moving the back of array to the index of the element to be popped, and then pop back the array. However, this will lead to reordering elements in the original array, which may not be desired. |
I think this should be added to the |
Implemented by godotengine/godot#67444. |
Describe the project you are working on
In most my games I sometimes have to pick a random element from an array (of cards, types of enemies, etc.).
Describe the problem or limitation you are having in your project
To get a random element I have to do
array[ randi() % array.size() ]
while also checking that it is not empty, which impacts readability and can be error prone, especially if the array has a long name.Describe the feature / enhancement and how it helps to overcome the problem or limitation
Add
Array.pick_random()
(or any method name you think makes the most sense) as syntactic sugar forArray[ randi() % Array.size() ]
It makes the code easier to read, reduces errors and makes it more accesible to beginners since they have an easy way to get random elements without having to understand that randi() give any possible int value and how modulo is use to restrict those values.
Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
A new pick_random() method will be added to arrays which does the Array[randi() % Array.size()] in C++. It could throw an error or return null for empty arrays. I'd like your input on which would be the best alternative.
I can take care of implementing it since it's a simple enough change.
If this enhancement will not be used often, can it be worked around with a few lines of script?
I can, but it is something that will be used often.
Is there a reason why this should be core and not an add-on in the asset library?
It's a method addition to Array so it has to be core.
The text was updated successfully, but these errors were encountered: