This commit is contained in:
2024-10-16 00:03:41 +08:00
commit 897058435c
5033 changed files with 1009728 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
namespace System.RandomPool
{
[Serializable]
public enum CardQuality
{
N = 0,
R,
SR,
SSR,
UR,
SP
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a00056319b674b658ff5612096aa3820
timeCreated: 1694858873

View File

@@ -0,0 +1,19 @@
using System;
namespace Game.Data.CustomGroup
{
[Serializable]
public class CommonNoneObject
{
public object Value;
public CommonNoneObject(object value)
{
Value = value;
}
public CommonNoneObject()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 31f1a9057c244d5b96c568142385aecf
timeCreated: 1649521283

View File

@@ -0,0 +1,88 @@
using System.Collections.Generic;
using System.RandomPool;
using FJson.Core;
using UnityEngine;
using Views;
namespace Game.Data
{
/// <summary>
/// 基于此配置表扩展该通用随机池
/// </summary>
/// <typeparam name="T"></typeparam>
public class CommonPoolConfig<T> where T : class
{
internal Dictionary<int, List<RandomNode<T>>> poolContents;
internal Dictionary<int, int> poolLevelWeight;
public CommonPoolConfig ()
{
this.poolContents = new Dictionary<int, List<RandomNode<T>>> ();
this.poolLevelWeight = new Dictionary<int, int> ();
}
public CommonPoolConfig (Dictionary<int, List<RandomNode<T>>> poolContents, Dictionary<int, int> poolLevelWeight)
{
this.poolContents = poolContents;
this.poolLevelWeight = poolLevelWeight;
}
public void PutPools (int level, RandomNode<T> node)
{
if (this.poolContents.ContainsKey (level))
{
this.poolContents[level].Add (node);
}
else
{
this.poolContents[level] = new List<RandomNode<T>> () { node };
}
}
internal virtual CommonRandomGroup<T> CreateGroup (int poolId)
{
return new CommonRandomGroup<T> (poolId);
}
// /// <summary>
// /// 用于创建怪物池对应配置表
// /// </summary>
// /// <param name="poolRow"></param>
// /// <returns></returns>
// public static CommonPoolConfig<RofEnemyRow> CreateEnemyPoolConfig(RofEnemyPoolRow poolRow)
// {
// var poolConfig = new CommonPoolConfig<RofEnemyRow>();
// var poolValue = KeywordUtils.DecodeRangeNum(poolRow.EnemyIDs);
// if (!string.IsNullOrWhiteSpace(poolValue))
// {
// poolValue = poolValue.Replace(" ", "");
// var enemyIds = poolValue.Split(',');
//
// foreach (var enemyId in enemyIds)
// {
// if (int.TryParse(enemyId, out var id))
// {
// var rofEnemyRow = EnemyManager.Instance.GetEnemy(id);
// var level = (ItemQuality) rofEnemyRow.quality;
// RandomNode<RofEnemyRow> node = new RandomNode<RofEnemyRow>(rofEnemyRow.ID, rofEnemyRow,
// -1, rofEnemyRow.weight, rofEnemyRow.exploreCondition);
// poolConfig.PutPools(level, node);
// }
// }
// }
//
// if (poolConfig.poolContents.ContainsKey(ItemQuality.Normal))
// poolConfig.poolLevelWeight[ItemQuality.Normal] = poolRow.NormalWeight;
// if (poolConfig.poolContents.ContainsKey(ItemQuality.Rare))
// poolConfig.poolLevelWeight[ItemQuality.Rare] = poolRow.RareWeight;
// if (poolConfig.poolContents.ContainsKey(ItemQuality.Epic))
// poolConfig.poolLevelWeight[ItemQuality.Epic] = poolRow.EpicWeight;
// if (poolConfig.poolContents.ContainsKey(ItemQuality.Legend))
// poolConfig.poolLevelWeight[ItemQuality.Legend] = poolRow.LegendWeight;
// if (poolConfig.poolContents.ContainsKey(ItemQuality.Hide))
// poolConfig.poolLevelWeight[ItemQuality.Hide] = poolRow.HideWeight;
// return poolConfig;
// }
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 05fdcfdaf9544e0d8908119713e89d46
timeCreated: 1633771120

View File

@@ -0,0 +1,227 @@
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;
}
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4d946aa8658147658a1b2eca11f78117
timeCreated: 1633769414

View File

@@ -0,0 +1,409 @@
using System;
using System.Collections.Generic;
using System.RandomPool;
using Game;
using UnityEngine;
namespace Game.Data
{
/// <summary>
/// 通用随机池,基于权重随机
/// </summary>
public class CommonRandomPool<T> where T : class
{
protected Dictionary<int, CommonRandomGroup<T>> _randomGroups;
protected LevelRandom _levelRandom;
protected int _poolId;
protected int _seedId;
public LevelRandom LevelRandom => this._levelRandom;
public int ValidRofCount
{
get
{
int count = 0;
foreach (var randomGroupsValue in _randomGroups.Values)
{
count += randomGroupsValue.ValidRofCount;
}
return count;
}
}
public CommonRandomPool(CommonPoolConfig<T> config, int poolId, int seedId)
{
this._poolId = poolId;
this._seedId = seedId;
this._randomGroups = new Dictionary<int, CommonRandomGroup<T>>();
foreach (var contentsKey in config.poolContents.Keys)
{
var nodes = config.poolContents[contentsKey];
CommonRandomGroup<T> randomGroup = config.CreateGroup(this._poolId);
foreach (var node in nodes)
{
randomGroup.PutItem(node);
}
this._randomGroups[contentsKey] = randomGroup;
}
foreach (var groupsValue in this._randomGroups.Values)
{
groupsValue?.SetMask(-1);
}
this._levelRandom = new LevelRandom(config.poolLevelWeight , new List<int>(this._randomGroups.Keys));
}
public void PutNode(RandomNode<T> node , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
commonRandomGroup.PutItem(node);
commonRandomGroup.SetMask(-1);
}
}
public RandomNode<T> GetNode(int key , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
return commonRandomGroup.GetItem(key);
}
return null;
}
public void ResetNodeWeight(int quality ,int key , int weight)
{
if (this._randomGroups.TryGetValue (quality, out var commonRandomGroup))
{
commonRandomGroup.ResetItemWeight (key , weight);
commonRandomGroup.SetMask (-1);
}
}
public void ResetQualityWeight(int quality , int weight)
{
this._levelRandom.SetWeight (quality , weight);
}
public void PutNodes(List<RandomNode<T>> nodes , int quality)
{
if (this._randomGroups.TryGetValue (quality, out var commonRandomGroup))
{
foreach (var node in nodes)
{
commonRandomGroup.PutItem(node);
}
commonRandomGroup.SetMask(-1);
}
}
//回收随机节点
public void PullNode(int key , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
commonRandomGroup.PullItem(key);
commonRandomGroup.SetMask(-1);
}
}
public void RemoveNode(int key , int quality)
{
if (_randomGroups.ContainsKey(quality))
{
var commonRandomGroup = _randomGroups[quality];
commonRandomGroup.RemoveItem(key);
commonRandomGroup.SetMask(-1);
}
}
public void RemoveNode(int key)
{
foreach (int itemQuality in Enum.GetValues(typeof(int)))
{
RemoveNode(key , itemQuality);
}
}
public List<T> RandomItems(int maskCount, int count, bool isSign = false , object customMask = null )
{
List<T> nodes = new List<T>();
List<int> disableList = new List<int>();
for (int i = 0; i < count; i++)
{
var node = this.RandomNode(maskCount, disableList , customMask);
if (node != null)
{
nodes.Add(node.value);
if (isSign)
{
disableList.Add(node.key);
}
}
}
return nodes;
}
public List<T> RandomItems(int maskCount, int count, bool isSign, IList<int> qualities, IList<int> disableKeys , object customMask = null)
{
List<T> nodes = new List<T>();
List<int> disableList = new List<int>();
if (disableKeys != null)
{
disableList.AddRange(disableKeys);
}
for (int i = 0; i < count; i++)
{
RandomNode<T> node = null;
if (qualities?.Count > i)
{
node = this.RandomNode(maskCount, qualities[i], disableList , customMask);
}
if (node == null)
{
node = this.RandomNode(maskCount, disableList , customMask);
}
if (node != null)
{
nodes.Add(node.value);
if (isSign)
{
disableList.Add(node.key);
}
}
}
return nodes;
}
/// <summary>
/// 指定稀有度安全随机一个物品,如果指定稀有度没有满足条件,则递减一个稀有度重新随机,直到正确数据出一个物品,也可能会出现所有稀有度都无法满足条件,返回空
/// </summary>
/// <param name="maskCount"></param>
/// <param name="quality"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public T RandomItem(int maskCount, int quality, IList<int> disableKeys = null, object customMask = null)
{
var maxCount = 10;
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
for (int i = (int)quality; i >= 0; i--)
{
var level = (int)i;
if (!levelMasks.Contains(level) && this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
while (maxCount-- > 0)
{
var node = this._randomGroups[level].RandomItem(this._poolId, this._seedId);
if (node == null)
{
continue;
}
return node;
}
}
}
Debug.LogError($"随机条件不满足 poolId:{this._poolId} maskID: {maskCount}");
return null;
}
public T RandomItem(int maskCount, IList<int> disableKeys = null, object customMask = null)
{
var maxCount = 10;
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
var level = this._levelRandom.RandomItemLevel(this._seedId, levelMasks);
if (this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
while (maxCount-- > 0)
{
var node = this._randomGroups[level].RandomItem(this._poolId, this._seedId);
if (node == null)
{
continue;
}
return node;
}
}
Debug.LogError($"随机条件不满足 poolId:{this._poolId} maskID: {maskCount}");
return null;
}
/// <summary>
/// 随机一组有效的稀有度数据,用于后续随机
/// </summary>
/// <param name="count">数据长度</param>
/// <param name="maxQuality">最大稀有度限制</param>
/// <param name="qualities">期望能出现的稀有度</param>
/// <param name="randomGroup"></param>
/// <returns></returns>
public List<int> CustomRandomQuality(int count,
int maxQuality,
IList<int> qualities = null , int randomGroup = 0)
{
List<int> finalQualities = new List<int>();
if (qualities != null)
{
finalQualities.AddRange(qualities);
}
List<int> levelMasks = new List<int>();
bool isTr = false;
foreach (int value in Enum.GetValues(typeof(int)))
{
if (isTr)
levelMasks.Add(value);
else
isTr = value == maxQuality;
}
for (int i = finalQualities.Count; i < count; i++)
{
finalQualities.Add(this.LevelRandom.RandomItemLevel((int) randomGroup, levelMasks));
}
return finalQualities;
}
/// <summary>
/// 随机一个指定稀有度的节点
/// </summary>
/// <param name="maskCount"></param>
/// <param name="quality"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public RandomNode<T> RandomNode(int maskCount, int quality, IList<int> disableKeys = null , object customMask = null)
{
if (this._randomGroups.ContainsKey(quality))
{
if (this._randomGroups[quality].SetMask(maskCount, disableKeys , customMask))
{
return this._randomGroups[quality].RandomNode(this._poolId, this._seedId);
}
}
return null;
}
public RandomNode<T> RandomNode(int maskCount, List<int> qualities, IList<int> disableKeys = null , object customMask = null)
{
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!qualities.Contains(groupsKey) || !this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
var level = this._levelRandom.RandomItemLevel(this._seedId, levelMasks);
if (this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
return this._randomGroups[level].RandomNode(this._poolId, this._seedId);
}
return null;
}
public RandomNode<T> RandomNode(int maskCount, IList<int> disableKeys = null, object customMask = null)
{
var maxCount = 10;
var levelMasks = new List<int>();
foreach (var groupsKey in this._randomGroups.Keys)
{
if (!this._randomGroups[groupsKey].SetMask(maskCount, disableKeys , customMask))
{
levelMasks.Add(groupsKey);
}
}
var level = this._levelRandom.RandomItemLevel(this._seedId, levelMasks);
if (this._randomGroups.ContainsKey(level) && this._randomGroups[level].ValidRofCount > 0)
{
while (maxCount-- > 0)
{
var node = this._randomGroups[level].RandomNode(this._poolId, this._seedId);
if (node == null)
{
continue;
}
return node;
}
}
Debug.LogError($"随机条件不满足 poolId:{this._poolId} maskID: {maskCount}");
return null;
}
/// <summary>
/// 获取该随机池中当前指定稀有度下的有效数
/// </summary>
/// <param name="quality"></param>
/// <param name="maskCount"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public int GetPoolValidCount(int quality, int maskCount , IList<int> disableKeys = null, object customMask = null)
{
if (this._randomGroups.ContainsKey(quality))
{
if (this._randomGroups[quality].SetMask(maskCount , disableKeys , customMask))
{
return this._randomGroups[quality].ValidRofCount;
}
}
return 0;
}
/// <summary>
/// 获取该随机池中当前总共的有效数
/// </summary>
/// <param name="maskCount"></param>
/// <param name="disableKeys"></param>
/// <param name="customMask"></param>
/// <returns></returns>
public int GetPoolValidCount(int maskCount , IList<int> disableKeys = null, object customMask = null)
{
int count = 0;
foreach (var groupsKey in this._randomGroups.Keys)
{
var randomGroup = this._randomGroups[groupsKey];
if (!randomGroup.SetMask(maskCount, disableKeys , customMask))
{
count += randomGroup.ValidRofCount;
}
}
return count;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3f4a3f041f964ea298df7f86be3f6380
timeCreated: 1633768881

View File

@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.RandomPool;
using FJson;
using Framework.Save;
// using Framework.Save;
using Game.Data;
using UnityEngine;
namespace Game
{
/// <summary>
/// 稀有度随机
/// </summary>
public class LevelRandom
{
private LiteDictionary<int, int> _levelDic;
private Dictionary<int, int> _weightDic;
private int _weightSum;
public LevelRandom (Dictionary<int, int> levelDic, IList<int> commonRandomGroups)
{
this._weightDic = new Dictionary<int, int>();
this._levelDic = new LiteDictionary<int, int>();
foreach (var randomGroup in commonRandomGroups)
{
if (levelDic.TryGetValue (randomGroup , out var value))
{
this._levelDic[randomGroup] = value;
}
}
this.RefreshWeight();
}
/// <summary>
/// 刷新总权重
/// </summary>
private void RefreshWeight()
{
this._weightDic.Clear();
this._weightSum = 0;
foreach (var dicKey in this._levelDic.Keys)
{
this._weightSum += this._levelDic[dicKey];
this._weightDic[dicKey] = this._weightSum;
}
}
/// <summary>
/// 设置指定等级的中奖比重
/// </summary>
/// <param name="quality"></param>
/// <param name="weight"></param>
public void SetWeight(int quality, int weight)
{
this._levelDic[quality] = weight;
this.RefreshWeight();
}
public int RandomItemLevel(int seedId)
{
var d = RandomUtils.RandomFloat ();
var level = 0;
foreach (var dicKey in this._weightDic.Keys)
{
var value = this._weightDic[dicKey];
if (d <= value * 1f / this._weightSum)
{
level = dicKey;
break;
}
}
return level;
}
public int RandomItemLevel(int seedId , List<int> maskLevel)
{
var level = 0;
if (maskLevel == null || maskLevel.Count == 0)
return this.RandomItemLevel(seedId);
Dictionary<int, int> tempWeightList = new Dictionary<int, int>();
int tempWeightSum = 0;
foreach (var itemLevel in this._levelDic.Keys)
{
if (maskLevel.Contains(itemLevel))
continue;
tempWeightSum += this._levelDic[itemLevel];
tempWeightList[itemLevel] = tempWeightSum;
}
if (tempWeightSum != 0)
{
var d = RandomUtils.RandomFloat () * tempWeightSum;
foreach (var dicKey in tempWeightList.Keys)
{
var value = tempWeightList[dicKey];
if (d <= value)
{
level = dicKey;
break;
}
}
}
return level;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dabd2f28c18cee74a9b251727db1c0a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a9ae61360ae242f68446a6dac657ee3a
timeCreated: 1717494667

View File

@@ -0,0 +1,7 @@
namespace System.RandomPool.PoolLogger
{
public interface IRandomLog
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4fe4ac1ddd934f9ba2f4d26557ff865d
timeCreated: 1717494684

View File

@@ -0,0 +1,113 @@
using FJson;
using Framework.Save;
using UnityEngine;
namespace System.RandomPool
{
internal class RandomLogController
{
internal class RandomLogData : SinglePersistentData<RandomLogData>
{
/// <summary>
/// 随机池抽取记录
/// </summary>
public LiteDictionary<int, LiteDictionary<int, int>> LocalPoolLog =
new LiteDictionary<int, LiteDictionary<int, int>> ();
}
private static RandomLogData _data;
internal static RandomLogData Data
{
get
{
if (_data == null)
{
_data = new RandomLogData();
if (!_data.Load ())
{
_data.LocalPoolLog = new LiteDictionary<int, LiteDictionary<int, int>> ();
}
}
return _data;
}
}
internal static LiteDictionary<int, LiteDictionary<int, int>> LocalPoolLog => Data.LocalPoolLog;
/// <summary>
/// 从随机池中取出
/// </summary>
/// <param name="poolId"></param>
/// <param name="id"></param>
/// <returns></returns>
internal static int PoolPushLog (int poolId, int id)
{
if (!LocalPoolLog.ContainsKey (poolId))
{
LocalPoolLog[poolId] = new LiteDictionary<int, int> ();
}
if (LocalPoolLog[poolId].ContainsKey (id))
{
LocalPoolLog[poolId][id] += 1;
}
else
{
LocalPoolLog[poolId][id] = 1;
}
Data.Save ();
Debug.Log ($"随机池记录增加 池id: {poolId} 物品ID: {id}, 数量: {LocalPoolLog[poolId][id]}");
return LocalPoolLog[poolId][id];
}
/// <summary>
/// 回收到随机池中
/// </summary>
/// <param name="poolId"></param>
/// <param name="id"></param>
internal static void PoolPullLog (int poolId, int id)
{
if (LocalPoolLog.ContainsKey (poolId) && LocalPoolLog[poolId].ContainsKey (id))
{
LocalPoolLog[poolId][id] -= 1;
Debug.Log ($"随机池记录减少 池id: {poolId} 物品ID: {id} , 数量: {LocalPoolLog[poolId][id]}");
}
}
internal static int GetPoolLog (int poolId, int id)
{
if (!LocalPoolLog.ContainsKey (poolId))
{
LocalPoolLog[poolId] = new LiteDictionary<int, int> ();
}
if (!LocalPoolLog[poolId].ContainsKey (id))
{
LocalPoolLog[poolId][id] = 0;
}
return LocalPoolLog[poolId][id];
}
/// <summary>
/// 用于判断是否还可以继续取出指定id
/// </summary>
/// <param name="poolId"></param>
/// <param name="id"></param>
/// <param name="maskCount"></param>
/// <returns></returns>
internal static bool IsPush (int poolId, int id, int maskCount)
{
if (maskCount == -1)
{
return true;
}
var i = GetPoolLog (poolId, id);
return i != -1 && i < maskCount;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0efde2709a1b42aca02954a2ed20f688
timeCreated: 1717142563

View File

@@ -0,0 +1,54 @@
using System;
using UnityEngine;
namespace Game.Data
{
/// <summary>
/// 通用随机单元
/// </summary>
public class RandomNode<T> where T : class
{
public int key; // 承载key
public T value; // 承载内容
public int count; // 最大数量
public int weight; // 随机权重
public int minRange; //至少抽取次数阈值
public int maxRange; //至多抽取次数阈值
public int curWeight; //当前的权重值,用于权重随机中的值比较。
public RandomNode(int key, T value, int count, int weight, int minRange, int maxRange)
{
this.key = key;
this.value = value;
this.count = count;
this.weight = weight;
this.minRange = minRange;
this.maxRange = maxRange;
}
public RandomNode(int key, T value, int count, int weight, string range)
{
this.key = key;
this.value = value;
this.count = count;
this.weight = weight;
if (range.Equals("-1", StringComparison.OrdinalIgnoreCase))
{
this.minRange = -1;
this.maxRange = -1;
}
else
{
var rs = range.Split(',');
this.minRange = int.Parse(rs[0]);
this.maxRange = int.Parse(rs.Length == 2 ? rs[1] : rs[0]);
}
}
public bool IsValid(int nowCount)
{
return this.count == -1 || nowCount < this.count;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ec18fb4e926e4fbebdee8dd4df47c86a
timeCreated: 1633768902

View File

@@ -0,0 +1,47 @@
using UnityEngine;
namespace System.RandomPool
{
public static class RandomUtils
{
public static float RandomFloat ()
{
return 1 - UnityEngine.Random.Range (0 , 1f);
}
public static bool HasRandom (float rota)
{
if (rota <= 0)
{
return false;
}
if (rota >= 1)
{
return true;
}
return RandomFloat () <= rota;
}
public static int RandomInt (int min, int max)
{
return UnityEngine.Random.Range (min, max);
}
public static float RandomFloat (float min, float max)
{
return UnityEngine.Random.Range (min, max);
}
public static int Range (int randomCountX, int randomCountY)
{
return RandomInt (randomCountX, randomCountY);
}
public static float RandomFormVector (Vector2 range)
{
return RandomFloat (range.x, range.y);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 02c4973fa8f146b7a465eb2966fdfb00
timeCreated: 1690191117

View File

@@ -0,0 +1,76 @@
using System.Collections.Generic;
using Game;
using Game.Data;
namespace System.RandomPool
{
public class WeightRandomPool
{
private class WeightCommonRandomPool : CommonRandomPool<WeightNode>
{
public WeightCommonRandomPool (CommonPoolConfig<WeightNode> config, int poolId, int seedId) : base (config, poolId, seedId)
{
config.poolContents = new Dictionary<int, List<RandomNode<WeightNode>>> ();
config.poolContents[0] = new List<RandomNode<WeightNode>> ();
config.poolLevelWeight = new Dictionary<int, int> ();
config.poolLevelWeight[0] = 100;
this._poolId = poolId;
this._seedId = seedId;
this._randomGroups = new Dictionary<int, CommonRandomGroup<WeightNode>>();
CommonRandomGroup<WeightNode> randomGroup = new CommonRandomGroup<WeightNode> (poolId);
this._randomGroups[0] = randomGroup;
this._randomGroups[0].SetMask(-1);
this._levelRandom = new LevelRandom(config.poolLevelWeight , new List<int>(this._randomGroups.Keys));
}
}
public class WeightNode
{
public int Id;
public int Weight;
}
private WeightCommonRandomPool _weightCommonRandomPool;
public int ValidRofCount => this._weightCommonRandomPool.ValidRofCount;
public WeightRandomPool ()
{
CommonPoolConfig<WeightNode> config = new CommonPoolConfig<WeightNode> ();
config.poolLevelWeight = new Dictionary<int, int> ();
this._weightCommonRandomPool = new WeightCommonRandomPool (config , 0 , 0);
}
public void PutNode (int id , int weight , int minRange = -1, int maxRange = -1)
{
this._weightCommonRandomPool.PutNode (new RandomNode<WeightNode> (id , new WeightNode () { Id = id, Weight = weight } , -1 , weight ,
minRange , maxRange) , 0);
}
public void ResetNode (int id , int weight)
{
this._weightCommonRandomPool.ResetNodeWeight (0 ,id , weight);
}
public int RandomNode (IList<int> disableKeys = null)
{
return this._weightCommonRandomPool.RandomItem (-1 , 0 , disableKeys)?.Id ?? -1;
}
public List<int> RandomNodes (int count , IList<int> disableKeys = null , bool isSin = false , int mask = -1)
{
List<int> ids = new List<int> ();
var randomItems = this._weightCommonRandomPool.RandomItems (mask , count, isSin , null , disableKeys);
for (var index = 0; index < randomItems.Count; index++)
{
var randomItem = randomItems[index];
ids.Add (randomItem.Id);
}
return ids;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 808899a02f2a49edb7f421d962788633
timeCreated: 1701151822