You've already forked taptap2024_GJ_chidouren
227 lines
6.7 KiB
C#
227 lines
6.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.RandomPool;
|
|
|
|
namespace Game.Data
|
|
{
|
|
/// <summary>
|
|
/// 通用随机池单元组,用于最终产生随机节点
|
|
/// </summary>
|
|
public class CommonRandomGroup<T> where T : class
|
|
{
|
|
private int _poolId;
|
|
private int _weightMax;
|
|
private readonly List<RandomNode<T>> _item;
|
|
private int _curWeightSum; //当前的总权重
|
|
private int _curConditionMask; //当前条件阈值 ,必须大于此值
|
|
public int ValidRofCount { get; private set; }
|
|
|
|
public CommonRandomGroup(int poolId)
|
|
{
|
|
this._poolId = poolId;
|
|
this._item = new List<RandomNode<T>>();
|
|
this._weightMax = 0;
|
|
this._curWeightSum = 0;
|
|
this._curConditionMask = -1;
|
|
this.ValidRofCount = -2;
|
|
}
|
|
|
|
public bool SetMask(int exploreCount, IList<int> disableKeys = null , object customMask = null)
|
|
{
|
|
this.ValidRofCount = 0;
|
|
this._curWeightSum = 0;
|
|
var isSet = false;
|
|
|
|
for (int i = 0; i < this._item.Count; i++)
|
|
{
|
|
var node = this._item[i];
|
|
|
|
if (disableKeys != null && disableKeys.Contains(node.key))
|
|
{
|
|
node.curWeight = -1;
|
|
continue;
|
|
}
|
|
|
|
var isBound = this.IsBound(node, exploreCount);
|
|
if (!isBound)
|
|
{
|
|
node.curWeight = -1;
|
|
continue;
|
|
}
|
|
|
|
if (!this.OnCustomMask(node , customMask))
|
|
{
|
|
node.curWeight = -1;
|
|
continue;
|
|
}
|
|
|
|
isSet = true;
|
|
this._curWeightSum += node.weight;
|
|
node.curWeight = this._curWeightSum;
|
|
this.ValidRofCount += 1;
|
|
}
|
|
|
|
this._curConditionMask = exploreCount;
|
|
return isSet;
|
|
}
|
|
|
|
protected virtual bool OnCustomMask(RandomNode<T> node, object customMask)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
private bool IsBound(RandomNode<T> node, int maskCount)
|
|
{
|
|
if (!node.IsValid(RandomLogController.GetPoolLog(this._poolId, node.key)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (maskCount == -1)
|
|
return true;
|
|
if (node.weight <= 0)
|
|
return false;
|
|
if (node.maxRange == -1 && node.minRange == -1)
|
|
return true;
|
|
|
|
if (node.minRange == -1)
|
|
{
|
|
return maskCount <= node.maxRange;
|
|
}
|
|
|
|
if (node.maxRange == -1)
|
|
{
|
|
return maskCount >= node.minRange;
|
|
}
|
|
|
|
return maskCount >= node.minRange && maskCount <= node.maxRange;
|
|
}
|
|
|
|
public void PutItem(RandomNode<T> node)
|
|
{
|
|
//此处后续可增加数量限制判断
|
|
this._weightMax += node.weight;
|
|
this._item.Add(node);
|
|
}
|
|
|
|
public void PullItem(int node)
|
|
{
|
|
for (int i = 0; i < _item.Count; i++)
|
|
{
|
|
var randomNode = _item[i];
|
|
if (randomNode.key == node)
|
|
{
|
|
RandomLogController.PoolPullLog (this._poolId , node);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RemoveItem(int node)
|
|
{
|
|
for (int i = 0; i < _item.Count; i++)
|
|
{
|
|
var randomNode = _item[i];
|
|
if (randomNode.key == node)
|
|
{
|
|
_item.RemoveAt(i);
|
|
_weightMax -= randomNode.weight;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal RandomNode<T> GetItem(int id)
|
|
{
|
|
for (int i = 0; i < this._item.Count; i++)
|
|
{
|
|
var node = this._item[i];
|
|
if (id == node.key)
|
|
{
|
|
return node;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public float GetItemRate(int id)
|
|
{
|
|
var f = 0f;
|
|
var item = this.GetItem(id);
|
|
if (item != null)
|
|
{
|
|
if (item.curWeight != -1)
|
|
{
|
|
f = item.weight / (this._weightMax * 1.0f);
|
|
}
|
|
}
|
|
|
|
return f;
|
|
}
|
|
|
|
public T RandomItem(int poolId, int seedId)
|
|
{
|
|
if (this._item.Count == 0 || ValidRofCount == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
RandomNode<T> item = null;
|
|
var p = RandomUtils.RandomFloat () * this._curWeightSum;
|
|
for (int i = 0; i < this._item.Count; i++)
|
|
{
|
|
var randomNode = this._item[i];
|
|
if (p <= randomNode.curWeight)
|
|
{
|
|
item = randomNode;
|
|
RandomLogController.PoolPushLog(poolId, item.key);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return item?.value;
|
|
}
|
|
|
|
public RandomNode<T> RandomNode(int poolId, int seedId)
|
|
{
|
|
if (this._item.Count == 0 || ValidRofCount == 0)
|
|
{
|
|
return null;
|
|
}
|
|
RandomNode<T> item = null;
|
|
var p = RandomUtils.RandomFloat () * this._curWeightSum;
|
|
for (int i = 0; i < this._item.Count; i++)
|
|
{
|
|
var randomNode = this._item[i];
|
|
if (p <= randomNode.curWeight)
|
|
{
|
|
item = randomNode;
|
|
RandomLogController.PoolPushLog(poolId, item.key);
|
|
break;
|
|
}
|
|
}
|
|
return item;
|
|
}
|
|
|
|
public static bool IsPush(int poolId, int id, int maskCount)
|
|
{
|
|
return RandomLogController.IsPush(poolId, id, maskCount);
|
|
}
|
|
|
|
public void ResetItemWeight(int id, int weight)
|
|
{
|
|
for (int i = 0; i < this._item.Count; i++)
|
|
{
|
|
var randomNode = this._item[i];
|
|
if (randomNode.key == id)
|
|
{
|
|
this._weightMax -= randomNode.weight;
|
|
randomNode.weight = weight;
|
|
this._weightMax += randomNode.weight;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |