打地鼠重置
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using AibisDream.FixSystem;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.Framework
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AibisDream.Framework
|
||||
{
|
||||
public class MultipleSelector<T> : IMultipleSelector<T>
|
||||
{
|
||||
private readonly List<T> _items;
|
||||
private int _batchSize;
|
||||
|
||||
public MultipleSelector(IEnumerable<T> items, int batchSize)
|
||||
{
|
||||
_items = new List<T>(items);
|
||||
_batchSize = batchSize;
|
||||
}
|
||||
|
||||
public T[] Select()
|
||||
{
|
||||
int[] indexArray = IMultipleSelector<T>.MultiRange(0, Count - 1, _batchSize);
|
||||
return indexArray.Select(index => _items[index]).ToArray();
|
||||
}
|
||||
|
||||
public void RemoveItem(T item)
|
||||
{
|
||||
_items.Remove(item);
|
||||
}
|
||||
|
||||
public void AddItem(T item)
|
||||
{
|
||||
_items.Add(item);
|
||||
}
|
||||
|
||||
public void SetBatchSize(int batchSize)
|
||||
{
|
||||
_batchSize = batchSize;
|
||||
}
|
||||
|
||||
public int Count => _items.Count;
|
||||
}
|
||||
|
||||
public interface IMultipleSelector<T>
|
||||
{
|
||||
T[] Select();
|
||||
void RemoveItem(T item);
|
||||
void AddItem(T item);
|
||||
int Count { get; }
|
||||
|
||||
static int[] MultiRange(int start, int end, int batchSize)
|
||||
{
|
||||
// 确保要求的数量不超过范围
|
||||
if (batchSize > end - start + 1)
|
||||
{
|
||||
Debug.LogError("要求的数量超过了范围内的数字总数");
|
||||
return default;
|
||||
}
|
||||
|
||||
var uniqueNumbers = new HashSet<int>();
|
||||
|
||||
while (uniqueNumbers.Count < batchSize)
|
||||
{
|
||||
var number = Random.Range(start, end + 1);
|
||||
uniqueNumbers.Add(number);
|
||||
}
|
||||
|
||||
return uniqueNumbers.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6409fbaa417b4c55841a8ca0abe16593
|
||||
timeCreated: 1753859058
|
||||
+101
-15
@@ -4,16 +4,30 @@ using System.Linq;
|
||||
|
||||
namespace AibisDream.Framework
|
||||
{
|
||||
public class RandomSelector<T> : ISelector<T>
|
||||
public class SingleSelector<T> : ISelector<T>
|
||||
{
|
||||
private readonly List<T> _items;
|
||||
private readonly List<int> _prefixSums;
|
||||
private readonly int _totalWeight;
|
||||
private readonly Random _random;
|
||||
|
||||
|
||||
#region 暂时无需实现
|
||||
|
||||
public void AddItem(T item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(T item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int Count => _items.Count;
|
||||
|
||||
public RandomSelector(IEnumerable<T> items, Func<T, int> weightSelector)
|
||||
|
||||
#endregion
|
||||
|
||||
public SingleSelector(IEnumerable<T> items, Func<T, int> weightSelector)
|
||||
{
|
||||
if (items == null) throw new ArgumentNullException(nameof(items));
|
||||
if (weightSelector == null) throw new ArgumentNullException(nameof(weightSelector));
|
||||
@@ -21,7 +35,7 @@ namespace AibisDream.Framework
|
||||
var itemList = items.ToList();
|
||||
_items = new List<T>(itemList.Count);
|
||||
_prefixSums = new List<int>(itemList.Count);
|
||||
|
||||
|
||||
int sum = 0;
|
||||
foreach (var item in itemList)
|
||||
{
|
||||
@@ -40,7 +54,7 @@ namespace AibisDream.Framework
|
||||
_totalWeight = sum;
|
||||
_random = new Random();
|
||||
}
|
||||
|
||||
|
||||
public T Select()
|
||||
{
|
||||
if (_totalWeight == 0)
|
||||
@@ -79,21 +93,35 @@ namespace AibisDream.Framework
|
||||
private readonly List<int> _batchWeight;
|
||||
private readonly int _totalWeight;
|
||||
private readonly Random _random;
|
||||
|
||||
|
||||
private int _currentWeight;
|
||||
private List<int> _curBatchWeight;
|
||||
|
||||
#region 暂时无需实现
|
||||
|
||||
public void AddItem(T item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveItem(T item)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public int Count => _totalWeight;
|
||||
|
||||
|
||||
public BatchSelector(IEnumerable<T> items, Func<T, int> weightSelector)
|
||||
{
|
||||
{
|
||||
if (items == null) throw new ArgumentNullException(nameof(items));
|
||||
if (weightSelector == null) throw new ArgumentNullException(nameof(weightSelector));
|
||||
|
||||
|
||||
var itemList = items.ToList();
|
||||
_items = new List<T>(itemList.Count);
|
||||
_batchWeight = new List<int>(itemList.Count);
|
||||
|
||||
|
||||
int sum = 0;
|
||||
foreach (var item in itemList)
|
||||
{
|
||||
@@ -110,7 +138,7 @@ namespace AibisDream.Framework
|
||||
}
|
||||
|
||||
_curBatchWeight = new List<int>(_batchWeight);
|
||||
|
||||
|
||||
_totalWeight = sum;
|
||||
_currentWeight = sum;
|
||||
_random = new Random();
|
||||
@@ -129,14 +157,14 @@ namespace AibisDream.Framework
|
||||
{
|
||||
ResetSelector();
|
||||
}
|
||||
|
||||
|
||||
int randomValue = _random.Next(0, _currentWeight);
|
||||
int index = BinarySearch(randomValue);
|
||||
|
||||
|
||||
// 选择后减去权重
|
||||
_currentWeight -= 1;
|
||||
_curBatchWeight[index] -= 1;
|
||||
|
||||
|
||||
return _items[index];
|
||||
}
|
||||
|
||||
@@ -162,6 +190,64 @@ namespace AibisDream.Framework
|
||||
}
|
||||
}
|
||||
|
||||
public class LimitedSelector<T> : ISelector<T>
|
||||
{
|
||||
private readonly List<T> _items;
|
||||
private readonly Random _random;
|
||||
|
||||
public LimitedSelector(IEnumerable<T> items)
|
||||
{
|
||||
_items = items.ToList();
|
||||
_random = new Random();
|
||||
}
|
||||
|
||||
public T Select()
|
||||
{
|
||||
if (_items.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Selector is Empty");
|
||||
}
|
||||
|
||||
var res = _items[_random.Next(0, _items.Count)];
|
||||
_items.Remove(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
public int Count => _items.Count;
|
||||
}
|
||||
|
||||
public class UnRepeatSelector<T> : ISelector<T>
|
||||
{
|
||||
private readonly List<T> _items;
|
||||
private readonly Random _random;
|
||||
|
||||
private T _lastCache;
|
||||
|
||||
public int Count => _items.Count;
|
||||
|
||||
public UnRepeatSelector(IEnumerable<T> items)
|
||||
{
|
||||
_items = items.ToList();
|
||||
_random = new Random();
|
||||
}
|
||||
|
||||
public T Select()
|
||||
{
|
||||
if (_items.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("Selector is Empty");
|
||||
}
|
||||
|
||||
T res;
|
||||
do
|
||||
{
|
||||
res = _items[_random.Next(0, _items.Count)];
|
||||
} while (Equals(res, _lastCache));
|
||||
_lastCache = res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ISelector<out T>
|
||||
{
|
||||
T Select();
|
||||
Reference in New Issue
Block a user