Skip to content

Instantly share code, notes, and snippets.

@GeorgiyRyaposov
Last active March 29, 2023 08:24
Show Gist options
  • Save GeorgiyRyaposov/9bf850f883f25d03f3ca1245d740b7f0 to your computer and use it in GitHub Desktop.
Save GeorgiyRyaposov/9bf850f883f25d03f3ca1245d740b7f0 to your computer and use it in GitHub Desktop.
namespace Assets.Scripts.Tools
{
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[System.Serializable]
public class ShuffleBag<T> : IList<T>
{
[SerializeField] private List<T> data = new();
[SerializeField] private int cursor;
/// <summary>
/// Get the next value from the ShuffleBag
/// </summary>
public T Next()
{
if (cursor < 1)
{
ResetBag();
return data.Count < 1 ? default : data[0];
}
var grab = Mathf.FloorToInt(Random.value * (cursor + 1));
var temp = data[grab];
data[grab] = data[cursor];
data[cursor] = temp;
cursor--;
return temp;
}
public void ResetBag()
{
cursor = data.Count - 1;
}
public ShuffleBag() { }
public ShuffleBag(T[] initialValues)
{
AddRange(initialValues);
}
public void AddRange(T[] values)
{
for (int i = 0; i < values.Length; i++)
{
Add(values[i]);
}
}
#region IList[T] implementation
public int IndexOf(T item)
{
return data.IndexOf(item);
}
public void Insert(int index, T item)
{
cursor = data.Count;
data.Insert(index, item);
}
public void RemoveAt(int index)
{
cursor = data.Count - 2;
data.RemoveAt(index);
}
public T this[int index]
{
get => data[index];
set => data[index] = value;
}
#endregion
#region IEnumerable[T] implementation
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return data.GetEnumerator();
}
#endregion
#region ICollection[T] implementation
public void Add(T item)
{
data.Add(item);
ResetBag();
}
public int Count => data.Count;
public void Clear()
{
data.Clear();
ResetBag();
}
public bool Contains(T item)
{
return data.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T item in data)
{
array.SetValue(item, arrayIndex);
arrayIndex += 1;
}
}
public bool Remove(T item)
{
var removed = data.Remove(item);
if (removed)
{
ResetBag();
}
return removed;
}
public bool IsReadOnly => false;
#endregion
#region IEnumerable implementation
IEnumerator IEnumerable.GetEnumerator()
{
return data.GetEnumerator();
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment