using System; using System.Collections.Generic; using System.RandomPool; namespace Game.Data { /// /// 通用随机池单元组,用于最终产生随机节点 /// public class CommonRandomGroup where T : class { private int _poolId; private int _weightMax; private readonly List> _item; private int _curWeightSum; //当前的总权重 private int _curConditionMask; //当前条件阈值 ,必须大于此值 public int ValidRofCount { get; private set; } public CommonRandomGroup(int poolId) { this._poolId = poolId; this._item = new List>(); this._weightMax = 0; this._curWeightSum = 0; this._curConditionMask = -1; this.ValidRofCount = -2; } public bool SetMask(int exploreCount, IList 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 node, object customMask) { return true; } private bool IsBound(RandomNode 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 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 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 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 RandomNode(int poolId, int seedId) { if (this._item.Count == 0 || ValidRofCount == 0) { return null; } RandomNode 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; } } } } }