using System.Text; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Model; using Oshima.FunGame.OshimaModules; using Oshima.FunGame.OshimaModules.Characters; using Oshima.FunGame.OshimaModules.Items; using Oshima.FunGame.OshimaModules.Skills; namespace Oshima.Core.Utils { public class FunGameSimulation { public static List Characters { get; } = []; public static List Skills { get; } = []; public static List Magics { get; } = []; public static List Items { get; } = []; public static Dictionary CharacterStatistics { get; } = []; public static Dictionary TeamCharacterStatistics { get; } = []; public static PluginConfig StatsConfig { get; } = new(nameof(FunGameSimulation), nameof(CharacterStatistics)); public static PluginConfig TeamStatsConfig { get; } = new(nameof(FunGameSimulation), nameof(TeamCharacterStatistics)); public static bool IsRuning { get; set; } = false; public static bool IsWeb { get; set; } = false; public static bool PrintOut { get; set; } = false; public static bool DeathMatchRoundDetail { get; set; } = false; public static string Msg { get; set; } = ""; public static List StartGame(bool printout, bool isWeb = false, bool isTeam = false, bool deathMatchRoundDetail = false) { PrintOut = printout; IsWeb = isWeb; DeathMatchRoundDetail = deathMatchRoundDetail; try { if (IsRuning) return ["游戏正在模拟中,请勿重复请求!"]; List result = []; Msg = ""; IsRuning = true; // M = 0, W = 7, P1 = 1, P3 = 1 // M = 1, W = 6, P1 = 2, P3 = 0 // M = 2, W = 4, P1 = 0, P3 = 2 // M = 2, W = 5, P1 = 0, P3 = 0 // M = 3, W = 3, P1 = 1, P3 = 1 // M = 4, W = 2, P1 = 2, P3 = 0 // M = 5, W = 0, P1 = 0, P3 = 2 // M = 5, W = 1, P1 = 0, P3 = 0 List list = new(Characters); if (list.Count > 11) { if (PrintOut) Console.WriteLine(); if (PrintOut) Console.WriteLine("Start!!!"); if (PrintOut) Console.WriteLine(); Character character1 = list[0].Copy(); Character character2 = list[1].Copy(); Character character3 = list[2].Copy(); Character character4 = list[3].Copy(); Character character5 = list[4].Copy(); Character character6 = list[5].Copy(); Character character7 = list[6].Copy(); Character character8 = list[7].Copy(); Character character9 = list[8].Copy(); Character character10 = list[9].Copy(); Character character11 = list[10].Copy(); Character character12 = list[11].Copy(); List characters = [ character1, character2, character3, character4, character5, character6, character7, character8, character9, character10, character11, character12 ]; int clevel = 60; int slevel = 6; int mlevel = 8; // 升级和赋能 for (int index = 0; index < characters.Count; index++) { Character c = characters[index]; c.Level = clevel; c.NormalAttack.Level = mlevel; IEnumerable magics = Magics.OrderBy(x => Random.Shared.Next()).Take(3); foreach (Skill magic in magics) { Skill m = magic.Copy(); m.Character = c; m.Level = mlevel; c.Skills.Add(m); } Skill 疾风步 = new 疾风步(c) { Level = slevel }; c.Skills.Add(疾风步); if (c == character1) { Skill META马 = new META马(c) { Level = 1 }; c.Skills.Add(META马); Skill 力量爆发 = new 力量爆发(c) { Level = mlevel }; c.Skills.Add(力量爆发); } if (c == character2) { Skill 心灵之火 = new 心灵之火(c) { Level = 1 }; c.Skills.Add(心灵之火); Skill 天赐之力 = new 天赐之力(c) { Level = slevel }; c.Skills.Add(天赐之力); } if (c == character3) { Skill 魔法震荡 = new 魔法震荡(c) { Level = 1 }; c.Skills.Add(魔法震荡); Skill 魔法涌流 = new 魔法涌流(c) { Level = slevel }; c.Skills.Add(魔法涌流); } if (c == character4) { Skill 灵能反射 = new 灵能反射(c) { Level = 1 }; c.Skills.Add(灵能反射); Skill 三重叠加 = new 三重叠加(c) { Level = slevel }; c.Skills.Add(三重叠加); } if (c == character5) { Skill 智慧与力量 = new 智慧与力量(c) { Level = 1 }; c.Skills.Add(智慧与力量); Skill 变幻之心 = new 变幻之心(c) { Level = slevel }; c.Skills.Add(变幻之心); } if (c == character6) { Skill 致命打击 = new 致命打击(c) { Level = 1 }; c.Skills.Add(致命打击); Skill 精准打击 = new 精准打击(c) { Level = slevel }; c.Skills.Add(精准打击); } if (c == character7) { Skill 毁灭之势 = new 毁灭之势(c) { Level = 1 }; c.Skills.Add(毁灭之势); Skill 绝对领域 = new 绝对领域(c) { Level = slevel }; c.Skills.Add(绝对领域); } if (c == character8) { Skill 枯竭打击 = new 枯竭打击(c) { Level = 1 }; c.Skills.Add(枯竭打击); Skill 能量毁灭 = new 能量毁灭(c) { Level = slevel }; c.Skills.Add(能量毁灭); } if (c == character9) { Skill 玻璃大炮 = new 玻璃大炮(c) { Level = 1 }; c.Skills.Add(玻璃大炮); Skill 迅捷之势 = new 迅捷之势(c) { Level = slevel }; c.Skills.Add(迅捷之势); } if (c == character10) { Skill 累积之压 = new 累积之压(c) { Level = 1 }; c.Skills.Add(累积之压); Skill 嗜血本能 = new 嗜血本能(c) { Level = slevel }; c.Skills.Add(嗜血本能); } if (c == character11) { Skill 敏捷之刃 = new 敏捷之刃(c) { Level = 1 }; c.Skills.Add(敏捷之刃); Skill 平衡强化 = new 平衡强化(c) { Level = slevel }; c.Skills.Add(平衡强化); } if (c == character12) { Skill 弱者猎手 = new 弱者猎手(c) { Level = 1 }; c.Skills.Add(弱者猎手); Skill 血之狂欢 = new 血之狂欢(c) { Level = slevel }; c.Skills.Add(血之狂欢); } } // 创建顺序表并排序 ActionQueue actionQueue = new(characters, isTeam, WriteLine); if (isTeam) { actionQueue.MaxRespawnTimes = -1; actionQueue.MaxScoreToWin = 30; } if (PrintOut) Console.WriteLine(); // 总游戏时长 double totalTime = 0; // 开始空投 Msg = ""; int 发放的武器品质 = 0; int 发放的防具品质 = 0; int 发放的鞋子品质 = 0; int 发放的饰品品质 = 0; 空投(actionQueue, 发放的武器品质, 发放的防具品质, 发放的鞋子品质, 发放的饰品品质); if (isWeb) result.Add("=== 空投 ===\r\n" + Msg); double 下一次空投 = isTeam ? 80 : 40; if (发放的武器品质 < 4) { 发放的武器品质++; } if (发放的防具品质 < 1) { 发放的防具品质++; } if (发放的鞋子品质 < 1) { 发放的鞋子品质++; } if (发放的饰品品质 < 3) { 发放的饰品品质++; } // 显示角色信息 if (PrintOut) characters.ForEach(c => Console.WriteLine(c.GetInfo())); // 因赋予了装备,所以清除排序重新排 actionQueue.ClearQueue(); actionQueue.InitCharacterQueue(characters); if (PrintOut) Console.WriteLine(); // 团队模式 if (isTeam) { Msg = "=== 团队模式随机分组 ===\r\n\r\n"; // 打乱角色列表 List shuffledCharacters = [.. characters.OrderBy(c => Random.Shared.Next())]; // 创建两个团队 List group1 = []; List group2 = []; // 将角色交替分配到两个团队中 for (int cid = 0; cid < shuffledCharacters.Count; cid++) { if (cid % 2 == 0) { group1.Add(shuffledCharacters[cid]); } else { group2.Add(shuffledCharacters[cid]); } } // 添加到团队字典 actionQueue.AddTeam("队伍一", group1); actionQueue.AddTeam("队伍二", group2); foreach (string team in actionQueue.Teams.Keys) { WriteLine($"团队【{team}】的成员:\r\n{string.Join("\r\n", actionQueue.Teams[team].Members)}\r\n"); } result.Add(Msg); } // 显示初始顺序表 actionQueue.DisplayQueue(); if (PrintOut) Console.WriteLine(); // 总回合数 int maxRound = isTeam ? 9999 : 999; int i = 1; while (i < maxRound) { Msg = ""; if (i == maxRound - 1) { if (isTeam) { WriteLine("两队打到天昏地暗,流局了!!"); break; } else { WriteLine($"=== 终局审判 ==="); Dictionary 他们的血量百分比 = []; foreach (Character c in characters) { 他们的血量百分比.TryAdd(c, c.HP / c.MaxHP); } double max = 他们的血量百分比.Values.Max(); Character winner = 他们的血量百分比.Keys.Where(c => 他们的血量百分比[c] == max).First(); WriteLine("[ " + winner + " ] 成为了天选之人!!"); foreach (Character c in characters.Where(c => c != winner && c.HP > 0)) { WriteLine("[ " + winner + " ] 对 [ " + c + " ] 造成了 99999999999 点真实伤害。"); actionQueue.DeathCalculation(winner, c); } actionQueue.EndGameInfo(winner); result.Add(Msg); break; } } // 检查是否有角色可以行动 Character? characterToAct = actionQueue.NextCharacter(); // 处理回合 if (characterToAct != null) { WriteLine($"=== Round {i++} ==="); WriteLine("现在是 [ " + characterToAct + (isTeam ? "(" + (actionQueue.GetTeam(characterToAct)?.Name ?? "") + ")" : "") + " ] 的回合!"); bool isGameEnd = actionQueue.ProcessTurn(characterToAct); if (isGameEnd) { result.Add(Msg); break; } actionQueue.DisplayQueue(); WriteLine(""); } // 模拟时间流逝 double timeLapse = actionQueue.TimeLapse(); totalTime += timeLapse; 下一次空投 -= timeLapse; if (下一次空投 <= 0) { // 空投 Msg = ""; 空投(actionQueue, 发放的武器品质, 发放的防具品质, 发放的鞋子品质, 发放的饰品品质); if (isWeb) result.Add("=== 空投 ===\r\n" + Msg); 下一次空投 = isTeam ? 100 : 40; if (发放的武器品质 < 4) { 发放的武器品质++; } if (发放的防具品质 < 1) { 发放的防具品质++; } if (发放的鞋子品质 < 1) { 发放的鞋子品质++; } if (发放的饰品品质 < 3) { 发放的饰品品质++; } } if (actionQueue.LastRound.HasKill) { string roundMsg = Msg; if (!deathMatchRoundDetail) { roundMsg = actionQueue.LastRound.ToString(); } if (!isWeb) { string[] strs = roundMsg.Split("==== 角色状态 ===="); if (strs.Length > 0) { roundMsg = strs[0]; } result.Add(roundMsg); } else { result.Add(roundMsg); } } } if (PrintOut) { Console.WriteLine("--- End ---"); Console.WriteLine($"总游戏时长:{totalTime:0.##}"); Console.WriteLine(""); } // 赛后统计 GetCharacterRating(actionQueue.CharacterStatistics, isTeam, actionQueue.EliminatedTeams); int top = isWeb ? actionQueue.CharacterStatistics.Count : 0; // 回执多少个角色的统计信息 int count = 1; if (isWeb) { WriteLine("=== 技术得分排行榜 ==="); // 这是输出在界面上的 Msg = $"=== 技术得分排行榜 TOP{top} ===\r\n"; // 这个是下一条给Result回执的标题,覆盖掉上面方法里的赋值了 } else { WriteLine("=== 本场比赛最佳角色 ==="); Msg = $"=== 本场比赛最佳角色 ===\r\n"; // 统计技术得分 Character? character = actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key).FirstOrDefault(); if (character != null) { CharacterStatistics stats = actionQueue.CharacterStatistics[character]; StringBuilder builder = new(); builder.AppendLine($"{(isWeb ? count + "." : (isTeam ? "[ " + actionQueue.GetTeamFromEliminated(character)?.Name + " ]" ?? "" : ""))} [ {character.ToStringWithLevel()} ]"); builder.AppendLine($"技术得分:{stats.Rating:0.##} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}"); builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); builder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); WriteLine(builder.ToString()); } } if (PrintOut) { Console.WriteLine(); Console.WriteLine("=== 技术得分排行榜 ==="); } if (isTeam) { foreach (Character character in actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key)) { StringBuilder builder = new(); CharacterStatistics stats = actionQueue.CharacterStatistics[character]; builder.AppendLine($"{(isWeb ? count + "." : ("[ " + actionQueue.GetTeamFromEliminated(character)?.Name + " ]" ?? ""))} [ {character.ToStringWithLevel()} ]"); builder.AppendLine($"技术得分:{stats.Rating:0.##} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}"); builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); builder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); if (count++ <= top) { WriteLine(builder.ToString()); } else { if (PrintOut) Console.WriteLine(builder.ToString()); } CharacterStatistics? totalStats = TeamCharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault(); if (totalStats != null) { UpdateStatistics(totalStats, stats); } } } else { foreach (Character character in actionQueue.CharacterStatistics.OrderByDescending(d => d.Value.Rating).Select(d => d.Key)) { StringBuilder builder = new(); CharacterStatistics stats = actionQueue.CharacterStatistics[character]; builder.AppendLine($"{(isWeb ? count + ". " : "")}[ {character.ToStringWithLevel()} ]"); builder.AppendLine($"技术得分:{stats.Rating:0.##} / 击杀数:{stats.Kills} / 助攻数:{stats.Assists}{(actionQueue.MaxRespawnTimes != 0 ? " / 死亡数:" + stats.Deaths : "")}"); builder.AppendLine($"存活时长:{stats.LiveTime} / 存活回合数:{stats.LiveRound} / 行动回合数:{stats.ActionTurn}"); builder.AppendLine($"总计伤害:{stats.TotalDamage} / 总计物理伤害:{stats.TotalPhysicalDamage} / 总计魔法伤害:{stats.TotalMagicDamage}"); builder.AppendLine($"总承受伤害:{stats.TotalTakenDamage} / 总承受物理伤害:{stats.TotalTakenPhysicalDamage} / 总承受魔法伤害:{stats.TotalTakenMagicDamage}"); builder.Append($"每秒伤害:{stats.DamagePerSecond} / 每回合伤害:{stats.DamagePerTurn}"); if (count++ <= top) { WriteLine(builder.ToString()); } else { if (PrintOut) Console.WriteLine(builder.ToString()); } CharacterStatistics? totalStats = CharacterStatistics.Where(kv => kv.Key.GetName() == character.GetName()).Select(kv => kv.Value).FirstOrDefault(); if (totalStats != null) { UpdateStatistics(totalStats, stats); } } } result.Add(Msg); // 显示每个角色的信息 if (isWeb) { if (isTeam) { top = 1; for (i = actionQueue.EliminatedTeams.Count - 1; i >= 0; i--) { Team team = actionQueue.EliminatedTeams[i]; string topTeam = ""; if (top == 1) { topTeam = "冠军"; } if (top == 2) { topTeam = "亚军"; } if (top == 3) { topTeam = "季军"; } if (top > 3) { topTeam = $"第 {top} 名"; } foreach (Character character in team.Members) { result.Add($"== {topTeam}团队 [ {team.Name} ] ==\r\n== 角色:[ {character} ] ==\r\n{character.GetInfo()}"); } top++; } } else { for (i = actionQueue.Eliminated.Count - 1; i >= 0; i--) { Character character = actionQueue.Eliminated[i]; result.Add($"=== 角色 [ {character} ] ===\r\n{character.GetInfo()}"); } } } if (isTeam) { lock (TeamStatsConfig) { foreach (Character c in TeamCharacterStatistics.Keys) { TeamStatsConfig.Add(c.ToStringWithOutUser(), TeamCharacterStatistics[c]); } TeamStatsConfig.SaveConfig(); } } else { lock (StatsConfig) { foreach (Character c in CharacterStatistics.Keys) { StatsConfig.Add(c.ToStringWithOutUser(), CharacterStatistics[c]); } StatsConfig.SaveConfig(); } } IsRuning = false; } return result; } catch (Exception ex) { IsRuning = false; Console.WriteLine(ex); return [ex.ToString()]; } } public static void WriteLine(string str) { Msg += str + "\r\n"; if (PrintOut) Console.WriteLine(str); } public static void 空投(ActionQueue queue, int wQuality, int aQuality, int sQuality, int acQuality) { WriteLine($"社区送温暖了,现在随机发放空投!!"); foreach (Character character in queue.Queue) { Item[] 武器 = Items.Where(i => i.Id.ToString().StartsWith("11") && (int)i.QualityType == wQuality).ToArray(); Item[] 防具 = Items.Where(i => i.Id.ToString().StartsWith("12") && (int)i.QualityType == aQuality).ToArray(); Item[] 鞋子 = Items.Where(i => i.Id.ToString().StartsWith("13") && (int)i.QualityType == sQuality).ToArray(); Item[] 饰品 = Items.Where(i => i.Id.ToString().StartsWith("14") && (int)i.QualityType == acQuality).ToArray(); Item? a = null, b = null, c = null, d = null; if (武器.Length > 0) { a = 武器[Random.Shared.Next(武器.Length)]; } if (防具.Length > 0) { b = 防具[Random.Shared.Next(防具.Length)]; } if (鞋子.Length > 0) { c = 鞋子[Random.Shared.Next(鞋子.Length)]; } if (饰品.Length > 0) { d = 饰品[Random.Shared.Next(饰品.Length)]; } List 这次发放的空投 = []; if (a != null) 这次发放的空投.Add(a); if (b != null) 这次发放的空投.Add(b); if (c != null) 这次发放的空投.Add(c); if (d != null) 这次发放的空投.Add(d); foreach (Item item in 这次发放的空投) { Item realItem = item.Copy(); realItem.SetGamingQueue(queue); realItem.SetLevel(1); queue.Equip(character, realItem); } } WriteLine(""); } public static void InitCharacter() { Characters.Add(new OshimaShiya()); Characters.Add(new XinYin()); Characters.Add(new Yang()); Characters.Add(new NanGanYu()); Characters.Add(new NiuNan()); Characters.Add(new DokyoMayor()); Characters.Add(new MagicalGirl()); Characters.Add(new QingXiang()); Characters.Add(new QWQAQW()); Characters.Add(new ColdBlue()); Characters.Add(new dddovo()); Characters.Add(new Quduoduo()); foreach (Character c in Characters) { CharacterStatistics.Add(c, new()); } StatsConfig.LoadConfig(); foreach (Character character in CharacterStatistics.Keys) { if (StatsConfig.ContainsKey(character.ToStringWithOutUser())) { CharacterStatistics[character] = StatsConfig.Get(character.ToStringWithOutUser()) ?? CharacterStatistics[character]; } } foreach (Character c in Characters) { TeamCharacterStatistics.Add(c, new()); } TeamStatsConfig.LoadConfig(); foreach (Character character in TeamCharacterStatistics.Keys) { if (TeamStatsConfig.ContainsKey(character.ToStringWithOutUser())) { TeamCharacterStatistics[character] = TeamStatsConfig.Get(character.ToStringWithOutUser()) ?? TeamCharacterStatistics[character]; } } Dictionary exItems = Factory.GetGameModuleInstances(OshimaGameModuleConstant.General, OshimaGameModuleConstant.Item); Items.AddRange(exItems.Values); Items.AddRange([new 攻击之爪10(), new 攻击之爪30(), new 攻击之爪50()]); Skills.AddRange([new 疾风步()]); Magics.AddRange([new 冰霜攻击(), new 火之矢(), new 水之矢(), new 风之轮(), new 石之锤(), new 心灵之霞(), new 次元上升(), new 暗物质()]); } public static void UpdateStatistics(CharacterStatistics totalStats, CharacterStatistics stats) { // 统计此角色的所有数据 totalStats.TotalDamage = Calculation.Round2Digits(totalStats.TotalDamage + stats.TotalDamage); totalStats.TotalPhysicalDamage = Calculation.Round2Digits(totalStats.TotalPhysicalDamage + stats.TotalPhysicalDamage); totalStats.TotalMagicDamage = Calculation.Round2Digits(totalStats.TotalMagicDamage + stats.TotalMagicDamage); totalStats.TotalRealDamage = Calculation.Round2Digits(totalStats.TotalRealDamage + stats.TotalRealDamage); totalStats.TotalTakenDamage = Calculation.Round2Digits(totalStats.TotalTakenDamage + stats.TotalTakenDamage); totalStats.TotalTakenPhysicalDamage = Calculation.Round2Digits(totalStats.TotalTakenPhysicalDamage + stats.TotalTakenPhysicalDamage); totalStats.TotalTakenMagicDamage = Calculation.Round2Digits(totalStats.TotalTakenMagicDamage + stats.TotalTakenMagicDamage); totalStats.TotalTakenRealDamage = Calculation.Round2Digits(totalStats.TotalTakenRealDamage + stats.TotalTakenRealDamage); totalStats.LiveRound += stats.LiveRound; totalStats.ActionTurn += stats.ActionTurn; totalStats.LiveTime = Calculation.Round2Digits(totalStats.LiveTime + stats.LiveTime); totalStats.TotalEarnedMoney += stats.TotalEarnedMoney; totalStats.Kills += stats.Kills; totalStats.Deaths += stats.Deaths; totalStats.Assists += stats.Assists; totalStats.FirstKills += stats.FirstKills; totalStats.FirstDeaths += stats.FirstDeaths; totalStats.LastRank = stats.LastRank; double totalRank = totalStats.AvgRank * totalStats.Plays + totalStats.LastRank; double totalRating = totalStats.Rating * totalStats.Plays + stats.Rating; totalStats.Plays += stats.Plays; if (totalStats.Plays != 0) totalStats.AvgRank = Calculation.Round2Digits(totalRank / totalStats.Plays); else totalStats.AvgRank = stats.LastRank; if (totalStats.Plays != 0) totalStats.Rating = Calculation.Round4Digits(totalRating / totalStats.Plays); else totalStats.Rating = stats.Rating; totalStats.Wins += stats.Wins; totalStats.Top3s += stats.Top3s; totalStats.Loses += stats.Loses; if (totalStats.Plays != 0) { totalStats.AvgDamage = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.Plays); totalStats.AvgPhysicalDamage = Calculation.Round2Digits(totalStats.TotalPhysicalDamage / totalStats.Plays); totalStats.AvgMagicDamage = Calculation.Round2Digits(totalStats.TotalMagicDamage / totalStats.Plays); totalStats.AvgRealDamage = Calculation.Round2Digits(totalStats.TotalRealDamage / totalStats.Plays); totalStats.AvgTakenDamage = Calculation.Round2Digits(totalStats.TotalTakenDamage / totalStats.Plays); totalStats.AvgTakenPhysicalDamage = Calculation.Round2Digits(totalStats.TotalTakenPhysicalDamage / totalStats.Plays); totalStats.AvgTakenMagicDamage = Calculation.Round2Digits(totalStats.TotalTakenMagicDamage / totalStats.Plays); totalStats.AvgTakenRealDamage = Calculation.Round2Digits(totalStats.TotalTakenRealDamage / totalStats.Plays); totalStats.AvgLiveRound = totalStats.LiveRound / totalStats.Plays; totalStats.AvgActionTurn = totalStats.ActionTurn / totalStats.Plays; totalStats.AvgLiveTime = Calculation.Round2Digits(totalStats.LiveTime / totalStats.Plays); totalStats.AvgEarnedMoney = totalStats.TotalEarnedMoney / totalStats.Plays; totalStats.Winrates = Calculation.Round4Digits(Convert.ToDouble(totalStats.Wins) / Convert.ToDouble(totalStats.Plays)); totalStats.Top3rates = Calculation.Round4Digits(Convert.ToDouble(totalStats.Top3s) / Convert.ToDouble(totalStats.Plays)); } if (totalStats.LiveRound != 0) totalStats.DamagePerRound = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveRound); if (totalStats.ActionTurn != 0) totalStats.DamagePerTurn = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.ActionTurn); if (totalStats.LiveTime != 0) totalStats.DamagePerSecond = Calculation.Round2Digits(totalStats.TotalDamage / totalStats.LiveTime); } public static void GetCharacterRating(Dictionary statistics, bool isTeam, List teams) { foreach (Character character in statistics.Keys) { Team? team = null; if (isTeam) { team = teams.Where(t => t.IsOnThisTeam(character)).FirstOrDefault(); } statistics[character].Rating = CalculateRating(statistics[character], team); } } public static double CalculateRating(CharacterStatistics stats, Team? team = null) { // 基础得分 double baseScore = (stats.Kills + stats.Assists) / (stats.Kills + stats.Assists + stats.Deaths + 0.01); if (team is null) { baseScore += stats.Kills * 0.1; if (stats.Deaths == 0) { baseScore += 0.5; } } else { baseScore = baseScore * 0.6 + 0.4 * (stats.Kills / (stats.Kills + stats.Deaths + 0.01)); } // 伤害贡献 double logDamageContribution = Math.Log(1 + (stats.TotalDamage / (stats.TotalTakenDamage + 1e-6))); // 存活时间贡献 double liveTimeContribution = Math.Log(1 + (stats.LiveTime / (stats.TotalTakenDamage + 0.01) * 100)); // 团队模式参团率加成 double teamContribution = 0; if (team != null) { teamContribution = (stats.Kills + stats.Assists) / (team.Score + 0.01); if (team.IsWinner) { teamContribution += 0.15; } } // 权重设置 double k = stats.Deaths > 0 ? 0.2 : 0.075; // 伤害贡献权重 double l = stats.Deaths > 0 ? 0.2 : 0.05; // 存活时间权重 double t = stats.Deaths > 0 ? 0.2 : 0.075; // 参团率权重 // 计算最终评分 double rating = baseScore + k * logDamageContribution + l * liveTimeContribution + t * teamContribution; // 确保评分在合理范围内 return Math.Max(0.01, rating); } } }