1
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class LayeredPool
|
||||
{
|
||||
// ⭐ 网络发送回调:由游戏侧(CreateFishManager)注入,框架层不再反向依赖 CreateFishManager
|
||||
public static Action<int, List<RedPacketRecord>, Vector3, int> OnSendRandomDieFishID;
|
||||
public static Action<List<RedPacketRecord>, Vector3, int> OnSendRandomCoinFX;
|
||||
|
||||
public LayeredPool(int poolNum,int prizeCount)
|
||||
{
|
||||
game = new CascadeRedPacketInt(poolNum, prizeCount);
|
||||
}
|
||||
CascadeRedPacketInt game;
|
||||
public List<RedPacketRecord> BossGlodCoin(int count,Vector3 v3Point, int killerSitPos = -1)
|
||||
{
|
||||
if (game.HasNext())
|
||||
{
|
||||
|
||||
int currentSubCount = count;
|
||||
|
||||
// 传入动态的个数
|
||||
List<RedPacketRecord> result = game.GrabFullCycle(currentSubCount);
|
||||
OnSendRandomDieFishID?.Invoke(currentSubCount, result, v3Point, killerSitPos);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public List<RedPacketRecord> BossGlodCoinNotFish(int count)
|
||||
{
|
||||
if (game.HasNext())
|
||||
{
|
||||
|
||||
int currentSubCount = count;
|
||||
|
||||
// 传入动态的个数
|
||||
List<RedPacketRecord> result = game.GrabFullCycle(currentSubCount);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public List<RedPacketRecord> BossGlodCoinRandrom(Vector3 v3Point, int min=3,int max=8, int killerSitPos = -1)
|
||||
{
|
||||
if (game.HasNext())
|
||||
{
|
||||
// --- 模拟动态逻辑 ---
|
||||
// 假设:第1个人裂变成3个包,第2个人裂变成10个包...
|
||||
// 这里用随机数模拟每次裂变个数不同 (3 到 8 之间)
|
||||
int currentSubCount = UnityEngine.Random.Range(min, max + 1);
|
||||
|
||||
// 传入动态的个数
|
||||
List<RedPacketRecord> result = game.GrabFullCycle(currentSubCount);
|
||||
OnSendRandomDieFishID?.Invoke(currentSubCount, result, v3Point, killerSitPos);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 随机分包 + 随机爆金币但不死鱼:
|
||||
/// 发 randomDieFish 帧(guids 为空),所有客户端只播屏幕随机位置的金币特效,场上鱼不死亡。
|
||||
/// </summary>
|
||||
public List<RedPacketRecord> BossGlodCoinRandromNotFish(Vector3 v3Point, int min=3, int max=8, int killerSitPos = -1)
|
||||
{
|
||||
if (game.HasNext())
|
||||
{
|
||||
int currentSubCount = UnityEngine.Random.Range(min, max + 1);
|
||||
|
||||
List<RedPacketRecord> result = game.GrabFullCycle(currentSubCount);
|
||||
OnSendRandomCoinFX?.Invoke(result, v3Point, killerSitPos);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21c16f4f5a7d9af4cafd5dd3608547b7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,141 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
[Serializable]
|
||||
/// <summary>
|
||||
/// 纯整数红包记录
|
||||
/// 金额单位:分 (int)
|
||||
/// </summary>
|
||||
public class RedPacketRecord
|
||||
{
|
||||
public int Phase { get; set; } // 阶段:1 或 2
|
||||
public int Index { get; set; } // 第几个包
|
||||
public long Amount { get; set; } // 金额(单位:分,纯整数)
|
||||
|
||||
// 方便调试看日志的格式化方法
|
||||
public string GetMoneyString()
|
||||
{
|
||||
return (Amount / 100) + "." + (Amount % 100).ToString("D2");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 纯整数版级联红包算法(支持动态裂变个数)
|
||||
/// </summary>
|
||||
public class CascadeRedPacketInt
|
||||
{
|
||||
private Random _random;
|
||||
private const int MIN_AMOUNT = 1; // 最小 1 分钱
|
||||
|
||||
// --- 第一阶段配置 ---
|
||||
private int _phase1TotalAmount; // 总金额(分)
|
||||
private int _phase1Count; // 第一阶段总人数
|
||||
private int _phase1Grabbed = 0; // 已抢人数
|
||||
|
||||
public CascadeRedPacketInt(int totalMoneyCents, int phase1Count, int? seed = null)
|
||||
{
|
||||
_random = seed.HasValue ? new Random(seed.Value) : new Random();
|
||||
_phase1TotalAmount = totalMoneyCents;
|
||||
_phase1Count = phase1Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 核心方法:执行一次完整的“抢大包 -> 拆小包”
|
||||
/// </summary>
|
||||
/// <param name="subCount">【动态参数】第二轮要裂变出的红包个数</param>
|
||||
/// <returns>该用户最终获得的一堆小红包列表</returns>
|
||||
public List<RedPacketRecord> GrabFullCycle(int subCount)
|
||||
{
|
||||
// 1. 第一阶段:从大奖池抢一个金额
|
||||
int phase1Amount = GrabPhase1();
|
||||
|
||||
if (phase1Amount <= 0) return null;
|
||||
|
||||
// 2. 第二阶段:把这个金额拆分成 subCount 个小包
|
||||
return SplitPhase2(phase1Amount, subCount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 第一阶段逻辑(不变)
|
||||
/// </summary>
|
||||
private int GrabPhase1()
|
||||
{
|
||||
if (_phase1Grabbed >= _phase1Count) return -1;
|
||||
|
||||
int amount;
|
||||
int remainingCount = _phase1Count - _phase1Grabbed;
|
||||
|
||||
if (_phase1Grabbed == _phase1Count - 1)
|
||||
{
|
||||
amount = _phase1TotalAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
int avg = _phase1TotalAmount / remainingCount;
|
||||
int max = avg * 2;
|
||||
int safeMax = _phase1TotalAmount - (remainingCount * MIN_AMOUNT);
|
||||
|
||||
if (max > safeMax) max = safeMax;
|
||||
if (max < MIN_AMOUNT) max = MIN_AMOUNT;
|
||||
|
||||
amount = _random.Next(MIN_AMOUNT, max + 1);
|
||||
}
|
||||
|
||||
_phase1TotalAmount -= amount;
|
||||
_phase1Grabbed++;
|
||||
return amount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 第二阶段逻辑(修改点:接收动态个数)
|
||||
/// </summary>
|
||||
/// <param name="seedAmount">种子金额(第一阶段抢到的钱)</param>
|
||||
/// <param name="subCount">要拆分的个数</param>
|
||||
private List<RedPacketRecord> SplitPhase2(int seedAmount, int subCount)
|
||||
{
|
||||
List<RedPacketRecord> subPackets = new List<RedPacketRecord>();
|
||||
int remainingAmount = seedAmount;
|
||||
|
||||
// 如果要求的个数小于等于0,直接把钱全给用户(或者你可以选择报错)
|
||||
if (subCount <= 0)
|
||||
{
|
||||
subPackets.Add(new RedPacketRecord { Phase = 2, Index = 1, Amount = seedAmount });
|
||||
return subPackets;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= subCount; i++)
|
||||
{
|
||||
int amount;
|
||||
int remainingCount = subCount - i;
|
||||
|
||||
if (remainingCount == 0)
|
||||
{
|
||||
// 最后一个包,兜底拿走所有剩余
|
||||
amount = remainingAmount;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 二倍均值法
|
||||
int avg = remainingAmount / remainingCount;
|
||||
int max = avg * 2;
|
||||
|
||||
// 边界保护
|
||||
int safeMax = remainingAmount - (remainingCount * MIN_AMOUNT);
|
||||
if (max > safeMax) max = safeMax;
|
||||
if (max < MIN_AMOUNT) max = MIN_AMOUNT;
|
||||
|
||||
amount = _random.Next(MIN_AMOUNT, max + 1);
|
||||
}
|
||||
|
||||
remainingAmount -= amount;
|
||||
subPackets.Add(new RedPacketRecord { Phase = 2, Index = i, Amount = amount });
|
||||
}
|
||||
|
||||
return subPackets;
|
||||
}
|
||||
|
||||
public bool HasNext()
|
||||
{
|
||||
return _phase1Grabbed < _phase1Count;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c4ad3c4505490040b83415c4716b1d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user