打地鼠重置

This commit is contained in:
2025-08-01 15:18:12 +08:00
parent f883c502f7
commit 171bae4663
25 changed files with 4190 additions and 4083 deletions
@@ -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
@@ -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();