How to make a RNG that doesnt repeat the same number

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Newby

Example from 1-10 i want it so it will get all the numbers like 1,3,5,2,4,6,9,10,7,8 then restart it again im trying to get it so that i will remember the numbers it already used and remove it from the array until all the numbers have been called then bring back all the numbers

:bust_in_silhouette: Reply From: hilfazer
extends Reference

var numbers 
var pastLastIdx


func _init( numbersArray ):
	numbers = PoolIntArray( numbersArray )
	pastLastIdx = numbers.size()


func getNumber():
	if pastLastIdx == 0:
		pastLastIdx = numbers.size()
	
	var numberIdx = randi() % pastLastIdx
	var returnNumber = numbers[numberIdx]
	numbers[numberIdx] = numbers[pastLastIdx-1]
	numbers[pastLastIdx-1] = returnNumber
	pastLastIdx -= 1
	return returnNumber


func reset():
		pastLastIdx = numbers.size()

And code to test it:
extends Node

const RngGd = "res://NoRepeatRNG.gd"

func _ready():
	randomize()

	var numbers = range(0, 11)
	var rng = preload(RngGd).new( numbers )

	for i in range(0,50):
		if i % numbers.size() == 0:
			print("\n")

		print( rng.getNumber() )

how can i make it start at 0 cause im using a 0,1,2,3,4,5 type of array also the way im using the RNG is to get questions from my list which is being call every time a question is answered. will this work if i call the _ready() in my script

Newby | 2018-08-31 23:26

Will this work for larger numbers like in the 90s

Newby | 2018-09-01 00:01

I’ve edited my answer. Now you can use any array with integers you want. It will work with bigger numbers like 90s. It will work if some numbers in array appear multiple times.
It should work in any place in your script.

hilfazer | 2018-09-01 05:41

Thanks for the help

Newby | 2018-09-01 14:06

Hello again can you repost the last code the one you gave to my is not working for some reason it getting a nonexistent PoolIntArray error

Newby | 2018-09-02 05:55

Maybe you are not passing an array of integers to NoRepeatRNG.gd script but some other type. New code need array of integers, like here:

var numbers = range(0, 11)
var rng = preload(RngGd).new( numbers )

range(0, 11) produces and array with numbers from 0 to 10. You can also to this:

var rng = preload(RngGd).new( [0,1,2,3,4,5,6,7,8,9,10] )

Code that accept single integer:

extends Reference

var numbers 
var pastLastIdx


func _init( highest ):
	numbers = PoolIntArray( range(1, highest+1) )
	pastLastIdx = numbers.size()


func getNumber():
	if pastLastIdx == 0:
		pastLastIdx = numbers.size()
	
	var numberIdx = randi() % pastLastIdx
	var returnNumber = numbers[numberIdx]
	numbers[numberIdx] = numbers[pastLastIdx-1]
	numbers[pastLastIdx-1] = returnNumber
	pastLastIdx -= 1
	return returnNumber

.

extends Node

const RngGd = "res://NoRepeatRNG.gd"

func _ready():
	randomize()

	var highest = 10
	var rng = preload(RngGd).new( highest )

	for i in range(0,50):
		if i % highest == 0:
			print("\n")

		print( rng.getNumber() )

hilfazer | 2018-09-02 10:02