Question about selecting a random number

I’m starting to program some enemies in my game, and I want to have them select the move they will do next by selecting a random number. I want the enemy to not be able to select the same move twice in a row.

So initially, I could use RandomInRange(). Let’s say an enemy has 4 possible moves. At first, I would use RandomInRange(1,4) to select the enemy’s first move. Let’s say the number 2 is selected first. Now, for the next move, I don’t want the enemy to be able to pick the number 2 from the list of 1 to 4. I want the possible moves for the next turn to be 1, 3, or 4 only (since 2 was picked last, it is excluded this time). Then, after that turn, the number 2 would be able to be picked again, and so on.

I wanted to know what the best way to set this up would be. I was playing around with using an array with 4 children, but every time I tried to remove the selected move number from the array, I couldn’t put it back in the array correctly so that it could be selected again later.

I assume what I’m trying to accomplish would be possible with an array called “PossibleMoves” or something like that. I would then select a random index from the array and use that index number as the move (from 0-3) that would be selected. However, how would I remove the selected move from the array, then add it back in at the index it was initially at after the next turn so it could be selected again?

Is an array even necessary to accomplish this? Is there some other way I’m not thinking of? I’m struggling to understand when and how arrays should be used in game development in general.

Here is a screenshot of some of the test code I was playing around with to see what the test array was doing:

Can someone give me some advice here on how to best implement this, with or without the use of an array? Thanks in advance!

Hey! So, this seems like a bit of a complicated math issue but I may be able to help you out. First if it’s a turn-based game, just set up something where it will pick between 1, 2, and 3 if the enemy played 4 on the last turn. If it’s like a fighting real-time game though, this might be harder to set up.
You could make a whole chain events where if the enemy picks 4, set a variable ‘EnemyMove4’ to true, than have an event to check which one of those variables is true, and runs a random number check between 1, 2, and 3? Of course this would take some time to set up, but if anyone else has a more straightforward solution let’s hear it!

Edit: ZeroX4 really said ‘Hold my beer!’

1 Like

1st event and its sub event is auto generating array for me
So if you create your manually you can skip it

So 2nd (last) event is what allows me to pick random number without repeating choice until all choices are chosen at least once

BUT issue is
Imagine i have only 4 child vars so only 4 choices
Now imagine just for example they go in order 2 1 4 3
And now 3 was last choice
And there is no child left so it auto generate again

And NOTHING is preventing it from 3 being 1st new choice on new list

I can think of a way how to prevent it but i will need some time

For now i will explain what is going on just so you can understand how it works

1st event if you are NOT gonna auto generate your array you can skip it

Condition is called compare 2 numbers
In 1st value i put expression VariableChildCount(Name of My Array) so in this case it is MyArray that is how i called it
I check if its equal to = 0
In 2nd value i put there is that 0 as you see
So if array have no child vars this event is executed and auto generate child variables
Trigger once so it don’t spam

Action
I am changing global var IncreaseIndex set to 0
It could be global object scene ANY variable as long as it is number i simply just went with global

Sub event of 1st event AGAIN you can skip it if you manually generate your array
Right click any event choose add and choose Repeat
That is how you get this event type

Where you see 10 is how many times i am gonna repeat whatever i want
So in this case i will generate 10 child vars so it means 10 choices

No condition here cause parent event is controlling when to run it

Action
We are adding child variable to our array variable in my case MyArray
And what we are adding is value of IncreaseIndex variable (remember in 1st event how i was setting it to 0? That is why so it always start from 0)
2nd action we change our IncreaseIndex by adding 1 to it

And all this crap works like this

Parent event
Array have 0 child vars
So add child var to MyArray with value of IncreaseIndex value
After child var is added
Add 1 to IncreaseIndex variable
And repeat it 10 times

You may wonder why it works 10 times if 1st event checks if there are 0 child vars?
Cause 1st even do in fact check are there 0 child vars after 1st is created nothing changes
for condition cause it was already triggered
Since it is triggering once it won’t spam it
So since sub event had repeat 10 times
It needs to repeat 10 times
And lastly
Since gdevelop read stuff from top to bottom
AGAIN 1st add child var with value of IncreaseIndex var
Then increase IncreaseIndex var by adding 1
And run same event 9 more times
So think of it as you just told gdevelop to read this event from top to bottom 10 times

NOW 2nd event

Space and trigger once is how i generate new random number
So for you it will be different

Action
I made scene var (again could be object or global or any as long as its number)
Called RNG
Now i set RNG var to RandomInRange(0,VariableChildCount(Name of my array) - 1)
So RandomInRange you know how works
But why why -1?
0 as lowest child index so minimum value
And - 1 cause
IF i have 4 child vars
They will look like
0 1
1 2
2 3
3 4

What it means on left 0 1 2 3 are index numbers
Imagine INDEX number as order number on list
Same as you have animations for your sprites
ALL index numbers start from 0

So if in random in range is lowest and VariableChildCount is maximum value so how many vars array have would be 4
You in this case NEVER have variable with index 4 cause 3 is highest index
Cause it starts from 0 not from 1
That is why you need -1
Cause 1st position on list is 0

Text action is there just to display whatever was picked

And last action is simply removing child by its index number from MyArray
So it DOES NOT repeat

Just so you can understand it better

Imagine my child vars instead of being numbers would be text
And i would have
0 Apple
1 Orange
2 Banana
3 Watermelon

See value is on the right but again Index is on the left
And we are picking variables here by its index

We do not specify which one exactly but randomly picking one and then removing

So if we pick 2 from
0 Apple
1 Orange
2 Banana
3 Watermelon

Then after removing that child var we will get

0 Apple
1 Orange
2 Watermelon

So Banana cannot be selected again

And same goes for case in which we have numbers as values

That wall of text should leave with no questions at least i hope
Now i am off for checking perfect solution for never repeating it even after creating new array automatically

2 Likes

I have 2 methods.

The first uses mod(). You pick a number from 1 to 3 to add to the current number and use mod() to wrap it if is 4 or more.

I used a button for testing. It returns a number from 0 to 3.

The array method is more complex. You pick an index, use its value, remove the number at the index and add the previous number (not index) to the array. The first time there isn’t a last number (not index) so you don’t add the previous value if the previous value is the default value. In my case I used 0.

The array version is more complex but the benefit is you could use a text array with commands instead of numbers. So, your condition could be say if NewAction = “attack” instead of NewNum = 1.

My variables.

2 Likes

Well, it’s kinda simple if I’m understanding it correctly, pick a random child and do its attack, set it’s value to 1 or more and the next time they attack subtract one to all attacks unless it’s already at 0, this allows for larger countdowns. They can’t use the move if it’s 1 or more.
They can if it’s 0.
The array is only needed in this case to randomly pick the child to do the move, nothing else.

1 Like

With your array method, I’m partially getting the desired result. However, when I remove the variable at index RandNum from the array, it seems to change the value to 0 rather than just taking that index out of the array altogether. So they array still has the same number of children, but now with a 0 in it. Am I doing something wrong somewhere? I want to pull that index’s value out of the array and store it in a variable, but I don’t want the index to be replaced with a 0 or the 0 could be chosen as the next move. In other words, if the array has index 0, 1, 2, 3 to start with and 2 is selected, I want the array to become 0, 1, 3 and not something like 0, 1, 0, 3. Am I missing something? I’m using the exact code you shared for your array method and I’m displaying the array values in text on the screen. That’s where I’m seeing the 0 getting added back into the array.

Can you post your current events? When a value becomes 0 it’s usually due to an attempt to read an index that doesn’t exist. Doing so will cause GD to create an index with a value of zero.

If you’re using something like repeat, make sure the number of times is the child count minus 1 because the first element is at index number 0 not 1.

Here is the code (I changed the variable names to ones while would make more sense to me in my specific case):

Capture39-2
This is for displaying the values of the array in a text object.


This is the code similar to your array method.

Where it’s displaying the values. It’s getting the values for 0 to 3 but after a number has been pulled there’s only 3 elements not 4. So, it will create the missing 3rd index. You can check the debugger or use for each child or even repeat using a counter.

With repeat.

For the first child is a number for the 2nd Counter is a number. List is the array.

I used NewLine(), you could use +“;”

You are completely right. Lol. The code I had for the text object to display the array index values was what was throwing me off. Your array method is working exactly how I intended it to now. It’s picking a different index each time, and putting that value back into the array to be selected again when I need it to.

And like you said, it could also be useful for using strings in the array. Thank you so much. Keith_1357 to the rescue again! Lol. I’ll probably have more questions regarding arrays in the future, since I know they’re a powerful data type and I might seek to learn how to implement them more in the future.

Thank you for taking the time to help me out with this!!! You’re a lifesaver on this forum! :slight_smile:

1 Like