Created
May 20, 2016 13:32
-
-
Save Arakade/5fe21d3d3e9119dd78a65e676ee75eab to your computer and use it in GitHub Desktop.
A way to repeatedly randomly choose from an initially provided set of possibilities.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright Rupert Key, 2016 | |
// Published under BSD license (commercial-friendly use as you wish but recognize owner wrote it) | |
using System.Collections.Generic; | |
// uses UnityEngine for Random.Range() | |
namespace UGS.Random { | |
/// <summary> | |
/// A way to repeatedly randomly choose from an initially provided set of possibilities. | |
/// Acts similarly to a deck of cards. | |
/// In much the same way that taking one card from a deck removes the possibility that that | |
/// card will be chosen again until the deck is reset (all cards returned and deck shuffled). | |
/// Use by: | |
/// 1. constructing with all the possibilities (<see cref="RandomGrabBag{T}"/>), | |
/// 2. if <see cref="hasChoicesLeft"/> | |
/// 3. call <see cref="chooseOne"/> | |
/// 4. <see cref="reset"/> to re-start with all possibilities. | |
/// Note: Each reset generates some garbage. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public class RandomGrabBag<T> { | |
private readonly T[] choices; | |
private readonly List<int> choiceIndicies; | |
public int numEntriesTotal { get { return choices.Length; } } | |
/// <summary> | |
/// Construct with these possible choices. | |
/// </summary> | |
/// <param name="choices"></param> | |
public RandomGrabBag(T[] choices) { | |
this.choices = choices; | |
choiceIndicies = new List<int>(); | |
for (int i = choices.Length - 1; i >= 0; i--) { | |
choiceIndicies.Add(i); | |
} | |
} | |
/// <summary> | |
/// Reset to choose from all choices again. | |
/// </summary> | |
public void reset() { | |
choiceIndicies.Clear(); | |
for (int i = choices.Length - 1; i >= 0; i--) { | |
choiceIndicies.Add(i); | |
} | |
} | |
/// <summary> | |
/// Returns whether there are choices remaining. | |
/// </summary> | |
/// <returns>true if there are values left; else false.</returns> | |
public bool hasChoicesLeft() { | |
return 0 < choiceIndicies.Count; | |
} | |
/// <summary> | |
/// Get one randomly chosen value (like picking a card from the deck). | |
/// </summary> | |
/// <returns>The chosen card.</returns> | |
public T chooseOne() { | |
if (0 >= choiceIndicies.Count) { | |
throw new System.IndexOutOfRangeException("No choices left"); | |
} | |
var chosenIndexIndex = UnityEngine.Random.Range(0, choiceIndicies.Count - 1); | |
var chosenIndex = choiceIndicies[chosenIndexIndex]; | |
choiceIndicies.RemoveAt(chosenIndexIndex); | |
return choices[chosenIndex]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment