shuffle bag

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// a different way of generating random values that may "feel" better than true randomness
// every possible value will show up once, but in a random order
// it simply draws from the "bag" every time you get NextValue
// 
// construct either with a list of values, or a size for the most common use
// list values like int[] numbers = {0, 0, 1, 1, 2, 2, 3, 3};
// size constructor makes a list of numbers from 0 to size-1
public class ShuffleBag {
    private int currentPosition;
    private int[] numberList;
    public int NextValue {
        get {
            int val = numberList[currentPosition];
            currentPosition++;
            if (currentPosition >= numberList.Length) {
                Reset();
            }
            return val;
        }
    }
    public ShuffleBag(int[] numbers) {
        numberList = ShuffleArray(numbers);
    }
    public ShuffleBag(int listSize) {
        numberList = new int[listSize];
        for (int i = 0; i < listSize; i++) {
            numberList[i] = i;
        }
        numberList = ShuffleArray(numberList);
    }
    private void Reset() {
        int lastValue = numberList[numberList.Length-1];
        numberList = ShuffleArray(numberList);
        // make sure not to repeat last value
        if (numberList[0] == lastValue) {
            int r = Random.Range(0, numberList.Length);
            numberList[0] = numberList[r];
            numberList[r] = lastValue;
        }
        currentPosition = 0;
    }
    // implementation of Knuth shuffle algorithm
    public static int[] ShuffleArray(int[] numbers) {
        int[] newArray = numbers.Clone() as int[];
        for (int i = 0; i < newArray.Length; i++ ) {
            int tmp = newArray[i];
            int r = Random.Range(i, newArray.Length);
            newArray[i] = newArray[r];
            newArray[r] = tmp;
        }
        return newArray;
    }
}