using cfg; using SimpleJSON; using System; using System.Collections.Generic; using System.IO; using System.Linq; using Unity.Mathematics; using UnityEditor; using UnityEngine; public class LuckyCardsToolData { public int seed; public int wishPrizeIndex; public List rewards = new List(); public List intsw = new List(); } public class LuckyCardsTool : EditorWindow { [MenuItem("Tools/Helper/LuckyCardsTool")] public static void ShowWindow() { LuckyCardsTool window = GetWindow("Lucky Cards Tool"); window.minSize = new Vector2(400, 300); window.maxSize = new Vector2(400, 300); } TbEventLuckyCardsPrizePool tbEventLuckyCardsPrizePool; int seed = 0; int checkSeed = 0; int wishPrizeIndex; int MaxMultipleCardsCount = 3; int allCount; List ints = new List(); List intsw = new List(); int Quantity = 10; List luckyCardsDataList = new List(); private void OnEnable() { tbEventLuckyCardsPrizePool = new TbEventLuckyCardsPrizePool(JSON.Parse(File.ReadAllText("../cfgData/tbeventluckycardsprizepool.json"))); var value = new TbEventLuckyCardsMain(JSON.Parse(File.ReadAllText("../cfgData/tbeventluckycardsmain.json"))); var eventLuckyCardsMain = value.DataList[0]; MaxMultipleCardsCount = eventLuckyCardsMain.MaxMultipleCardsCount; } private void OnGUI() { GUILayout.Label("Lucky Cards Tool", EditorStyles.boldLabel); EditorGUILayout.LabelField("Seed:", seed.ToString()); Quantity = EditorGUILayout.IntField("Quantity:", Quantity); int count = Quantity; if (GUILayout.Button("Generate Rewards")) { luckyCardsDataList = new List(); allCount = 0; //显示 不能修改的 seed DateTime dateTime = new DateTime(2025, 1, 1, 0, 0, 0, DateTimeKind.Utc); seed = (int)(DateTime.UtcNow - dateTime).TotalDays; while (count > 0 && allCount < 1000) { wishPrizeIndex = GetWishPrizeIndex(); if (wishPrizeIndex >= 7 && wishPrizeIndex < 10) { ints = new List(); intsw = new List(); bool reward = SetRewardData(); if (reward) { count--; ints.Insert(wishPrizeIndex, 0); LuckyCardsToolData luckyCardsData = new LuckyCardsToolData { seed = seed * allCount, wishPrizeIndex = wishPrizeIndex, rewards = ints.ToList(), intsw = intsw.ToList() }; luckyCardsDataList.Add(luckyCardsData); } } allCount++; } SaveData(); } EditorGUILayout.LabelField("allCount:", allCount.ToString()); //添加空行 EditorGUILayout.Space(50); checkSeed = EditorGUILayout.IntField("Check Seed:", checkSeed); if (GUILayout.Button("Check Rewards")) { seed = checkSeed; allCount = 1; wishPrizeIndex = GetWishPrizeIndex(); ints = new List(); intsw = new List(); bool reward = SetRewardData(); ints.Insert(wishPrizeIndex, 0); EditorUtility.DisplayDialog("Rewards", $"Seed: {checkSeed}\nWish Prize Index: {wishPrizeIndex + 1}\nRewards: {string.Join(";", ints)}\nIntsw: {string.Join(";", intsw)}", "OK"); } } private void SaveData() { // 生成PVP数据的逻辑 // 这里可以使用上面定义的参数来生成数据 //然后存成一个csv文件 string path = EditorUtility.SaveFilePanel("保存序列数据", "", $"幸运卡牌前期序列.csv", "csv"); if (string.IsNullOrEmpty(path)) return; System.IO.StreamWriter sw = new System.IO.StreamWriter(path); sw.WriteLine("seed,wishPrizeIndex,itemID,intsw"); for (int i = 0; i < luckyCardsDataList.Count; i++) { sw.WriteLine($"{luckyCardsDataList[i].seed},{luckyCardsDataList[i].wishPrizeIndex},{string.Join(";", luckyCardsDataList[i].rewards)},{string.Join(";", luckyCardsDataList[i].intsw)}"); } sw.Close(); AssetDatabase.Refresh(); EditorUtility.DisplayDialog("提示", "生成序列数据成功", "确定"); } bool SetRewardData() { System.Random random = new System.Random(seed * allCount); List pools = tbEventLuckyCardsPrizePool.DataList; Dictionary poolWeight = new Dictionary(); foreach (var pool in pools) { poolWeight[pool.ID] = pool.Weight; } int multiplierCount = 0; EventLuckyCardsPrizePool selectedPool = null; bool isqualified = false; for (int i = 0; i < 9; i++) { //出现在心愿大奖之后,权重变为X,且不受权重下降的影响 if (i == wishPrizeIndex) { poolWeight = WishPrizeNewDic(poolWeight); } int selectedPoolId = GetSelectedPoolId(poolWeight, random); selectedPool = tbEventLuckyCardsPrizePool.GetOrDefault(selectedPoolId); if (selectedPool == null) { UnityEngine.Debug.LogError($"[LuckyCardsSystem]: Selected pool not found for ID: {selectedPoolId}"); } if (i < wishPrizeIndex || selectedPool.AdjustWeight2 == 0) { poolWeight[selectedPoolId] = selectedPool.AdjustWeight; } if (selectedPool.Item == -1) { multiplierCount++; if (multiplierCount >= MaxMultipleCardsCount) { poolWeight = MaxMultipleNewDic(poolWeight); } } intsw.Add(selectedPool.Count); ints.Add(selectedPool.ID); if (i == wishPrizeIndex - 1) { isqualified = selectedPool.Item != -1 && multiplierCount > 0; } } return isqualified; } int GetSelectedPoolId(Dictionary poolWeight, System.Random random) { int weightSum = poolWeight.Values.Sum(); int randomValue = random.Next(0, weightSum); int cumulativeWeight = 0; int selectedPoolId = 0; foreach (var kvp in poolWeight) { if (kvp.Value == 0) { continue; } cumulativeWeight += kvp.Value; if (randomValue < cumulativeWeight) { selectedPoolId = kvp.Key; break; } } return selectedPoolId; } Dictionary WishPrizeNewDic(Dictionary poolWeight) { var oldPoolWeight = poolWeight; poolWeight = new Dictionary(); EventLuckyCardsPrizePool selectedPool; foreach (var kvp in oldPoolWeight) { if (kvp.Value == 0) { continue; } selectedPool = tbEventLuckyCardsPrizePool.GetOrDefault(kvp.Key); if (selectedPool.AdjustWeight2 > 0) { poolWeight[kvp.Key] = selectedPool.AdjustWeight2; } else { poolWeight[kvp.Key] = kvp.Value; } } return poolWeight; } Dictionary MaxMultipleNewDic(Dictionary poolWeight) { var jsonData = tbEventLuckyCardsPrizePool; var oldPoolWeight = poolWeight; poolWeight = new Dictionary(); EventLuckyCardsPrizePool selectedPool; foreach (var kvp in oldPoolWeight) { if (kvp.Value == 0) { continue; } selectedPool = jsonData.GetOrDefault(kvp.Key); if (selectedPool.Item != -1) { poolWeight[kvp.Key] = kvp.Value; } } return poolWeight; } int GetWishPrizeIndex() { System.Random random = new System.Random(seed * allCount); TbEventLuckyCardsConfig config = new TbEventLuckyCardsConfig(JSON.Parse(File.ReadAllText("../cfgData/tbeventLuckycardsconfig.json"))); List configs = config.DataList; //权重随机 int weightSum = configs.Select(c => c.WishPrizeWeight).Sum(); int randomValue = random.Next(0, weightSum); int cumulativeWeight = 0; int wishPrizeIndex = 0; for (int i = 0; i < configs.Count; i++) { cumulativeWeight += configs[i].WishPrizeWeight; if (randomValue < cumulativeWeight) { wishPrizeIndex = i; break; } } //Debug.Log($"[LuckyCardsSystem]:Wish Prize Index: {wishPrizeIndex}, Seed: {luckyCardsData.seed}"); return wishPrizeIndex; } [MenuItem("Tools/Helper/tbeventluckycardsprizepool")] public static void Synctbeventluckycardsprizepool() { string EventLuckyCardsPrizePoolPath = "../cfgData/tbeventluckycardsprizepool.json"; var jsonData = new TbEventLuckyCardsPrizePool(JSON.Parse(File.ReadAllText(EventLuckyCardsPrizePoolPath))); List pools = jsonData.DataList; List multiplierCounts = new List(); int multiplier0 = 0; int multiplier1 = 0; int multiplier2 = 0; int multiplier3 = 0; int multiplier4 = 0; //测试100次抽奖 for (int j = 0; j < 10000; j++) { Dictionary poolWeight = new Dictionary(); for (int i = pools.Count - 1; i >= 0; i--) { EventLuckyCardsPrizePool pool = pools[i]; poolWeight[pool.ID] = pool.Weight; } int multiplierCount = 0; for (int i = 0; i < 9; i++) { int selectedPoolId = GetSelectedPoolId(poolWeight); EventLuckyCardsPrizePool selectedPool = jsonData.GetOrDefault(selectedPoolId); poolWeight[selectedPoolId] = selectedPool.AdjustWeight; if (selectedPool.Item == -1) { multiplierCount++; } } if (multiplierCount == 0) { multiplier0++; } else if (multiplierCount == 1) { multiplier1++; } else if (multiplierCount == 2) { multiplier2++; } else if (multiplierCount == 3) { multiplier3++; } else if (multiplierCount == 4) { multiplier4++; } multiplierCounts.Add(multiplierCount); } Debug.Log($"[LuckyCardsSystem]: Test Set Reward Data - Multiplier Counts: 0x{multiplier0}, 1x{multiplier1}, 2x{multiplier2}, 3x{multiplier3}, 4x{multiplier4} ==> {string.Join(", ", multiplierCounts)}"); } static int GetSelectedPoolId(Dictionary poolWeight) { int weightSum = poolWeight.Values.Sum(); int randomValue = UnityEngine.Random.Range(0, weightSum); int cumulativeWeight = 0; int selectedPoolId = 0; foreach (var kvp in poolWeight) { //if (kvp.Value == 0) //{ // continue; //} cumulativeWeight += kvp.Value; if (randomValue < cumulativeWeight) { selectedPoolId = kvp.Key; break; } } return selectedPoolId; } }