I know how to generate a random number from a range of numbers, but how would I go about generating a number between multiple ranges, like a number between 1 - 4 and/or 7 - 10, so it would exclude numbers 5 and 6 in this example? What would the code/syntax look like for that?

Update: I figured out that I can add an if condition within my function to reset the value of my random number if it equals a number I want to exclude.

func _input(event: InputEvent) -> void: if Input.is_action_just_pressed("ui_down"): rnd = floor(rand_range(1, 11)) if rnd == 7: rnd = floor(rand_range(1,11)) else: print(rnd) But I'd still like to know if there's a way with the random range method to just pick from multiple ranges. And also, is there a way to check if a variable falls within a certain range of numbers, like: if x == range(7, 9): Because if I need to exclude a larger range of numbers from within my rand_range, it would be way less work to do that than to exclude every single number I don't want.

I'd min and max my desired ranges and then pull a number from that.

func get_from_ranges(a1: int, a2: int, b1: int, b2: int) -> int:
    var a: = max(a1, a2)
    var b: = min(b1, b2)
    return int(floor(rand_range(a, b)))

Is that what you're trying to do?

I used your example with floor but I'd find a way to avoid that as I think you're excluding the highest number you could pick.

If you wanted to avoid specific results I'd use a loop.

func rand_without(a: int, b: int, skip: Array) -> int:
    result: = 0
    is_searching: = true
    while is_searching:
        result = int(floor(rand_range(a, b)))
        is_searching = skip.has(result)
    return result

something like that?

If you're trying to figure out if a number is within a range you just use an and statement.

func is_between(value: int, a: int, b: int) -> bool:
    return value >= a and value <= b

Whew, you threw three totally different questions out.

Thank you so much for trying to answer them! Sorry to say all three of your answers went right over my head. I've been learning GDScript for about 2 or 3 weeks now and I only just got my head around generating random numbers. I'm seeing a lot of stuff here in your examples that I haven't even heard of yet. Like skip and is searching, and I'm not sure how the min max thing works. Sorry to be a dolt, there's just a lot I don't know yet!

In my project I have a series of animations that play and they're listed in a variable as an array. In my function that tells the AnimationPlayer to play a certain animation every three seconds, I plug in a random number to represent that item in the array order. I wanted to make it so that when a player selects certain settings in the options menu, only certain animations would be randomly picked out of the array. So out of 10 animations, maybe I only want my random variable to pick from 1 to 4 and 7 to 10 in the event that the settings the player chooses wouldn't use 5 and 6.

I chose floor to avoid decimals (since I haven't quite figured out the randi and int syntax yet) and I make up for it by adjusting my ranges a number higher.

I will reflect on these examples and see if I can figure them out. Your first solution seems the most promising. Maybe if I could see your examples with actual numbers plugged in I would understand the functionality more....

Thanks again, hope I'm not asking too much!

I think the easiest way to do this would be to put all the integer numbers you want to get as a result into an array, and then use the rand function to pick an index in that array. So something like this (I iterate 100 times just so you can see in the output that it works).

extends Node2D

var valid_numbers = [1, 2, 3, 4, 7, 8, 9, 10]

func _ready():
	randomize()
	for i in range(0, 100):
		var num = get_random(valid_numbers)
		print("chosen number is ", num)
	
func get_random(nums):
	var idx = randi() % nums.size()
	return nums[idx]
var allNumbers = range(1,11)
var excludeNumbers = [7,8]
var randomNumbers = []
for value in allNumbers:
	if not (value in excludeNumbers):
		randomNumbers.append(value)
var currentRandomNumberGenerator = RandomNumberGenerator.new()
currentRandomNumberGenerator.set_seed(hash("godot"))

var i = currentRandomNumberGenerator.randi_range(0,randomNumbers.size()-1)
var result = randomNumbers[i]

try it, Sorry, gdscript does not have a Python set, so I can only use such a clumsy method

My code is basically the same as his code, except for the process of generating collections I'm sorry I didn't see your post when I posted it, so the content of the two posts is approximately the same@cybereality

min and max are just common math operations. min picks the lowest number, max picks the biggest number. int just converts to an integer from a decimal number.

I made a mistake in my second example. result and is_searching are both variables.

func rand_without(a: int, b: int, skip: Array) -> int:
    var result: = 0
    var is_searching: = true
    while is_searching:
        result = int(floor(rand_range(a, b)))
        is_searching = skip.has(result)
    return result

Nothing complicated here, jut checks skip for the result and if it isn't there exit the loop.

Thank you, all, for your helpful answers and suggestions! I've been playing around with all of them all morning. I like cybereality's use of an array that excludes unwanted numbers, which would be very simple and easy to implement when working with smaller ranges of numbers. But that method would need some LONG arrays when dealing with bigger ranges of numbers. I adopted from your method using randi( ) instead of my floor(rand_range( ) ) method.

vmjcv's concept of a variable for the whole range of valid numbers and a variable for excluded numbers is a brilliant concept, but I couldn't get the "for value in allNumbers:" part of it to work, at least plugging it in the way I am trying to use it. This is an idea I'll come back to when I understand more about for loops.

Thanks again to kequc for your original answers and subsequent clarification. I'm still a little intimidated by the layout of your function since I'm not yet comfortable with using "while" and still don't fully understand how to properly implement the parentheses on functions. However, I was able to implement the concept of checking for the value of my variable to be greater than the bottom value of my excluded range and less than the top value and set that as a boolean which tells my function to either accept that value and proceed or try again and re-randomize until that boolean is false. I simplified this method and implemented it in a way that uses the elements I currently am comfortable with, though it may be a little more verbose. In this example I am excluding numbers from 3 to 7 within the scale of 1 - 10 and having the functions loop with each other. It works perfectly in my project!

var rnd = null
var exclude = false
func ready():
	MixUp()

func MixUp():
	rnd = randi()%10 + 1
	if rnd >= 3 and rnd <= 7:
		exclude = true
	else: 
		exclude = false
	if exclude == true:
		MixUp()
	else:
		countdown()

func countdown():
	yield(get_tree().create_timer(3), "timeout")
	print("This is a useable number!" + rnd)
	MixUp()

So ultimately, the answer for me, all the other complicated details aside, was using a boolean determined by less than and greater than operators. Knowing this, I think I'll experiment with using the clamp( ) method to for excluded ranges. Let me know if you folks like this solution. Thanks again, everyone!

Yeah, that method can work. Also, with the code I posted, it does not have to be a static array. You can easily populate the valid numbers within a loop programmatically, to have any amount of numbers in it.

Cybereality, I only just got my head around using arrays at all. I haven't the faintest clue how one would incorporate a loop within an array! That may be a quest for another day. I'm just happy I found a solution that works for my present problem. Thanks for the guidance, though!

The function:

func getRandRangesNumber(ranges):
	var selectedRange = ranges[randi() % len(ranges)]
	
	var minNumber = selectedRange[0]
	var maxNumber = selectedRange[1]

	return (randi() % (maxNumber-minNumber+1)) + minNumber

Example:

getRandRangesNumber([[1,5],[10,50],[100,1000]])

Basically, you pass a 2d array with ranges: [[1,5],[10,50],[100,1000]] This array has 3 ranges in it: 1 to 5 10 to 50 100 to 1000

For your case, you can use getRandRangesNumber([[1,4],[7,10]])

3 years later