diff --git a/GameFrameX.Hotfix/Logic/ServerRole/Battle/BattleRules.cs b/GameFrameX.Hotfix/Logic/ServerRole/Battle/BattleRules.cs index 5d63c418..25ac914c 100644 --- a/GameFrameX.Hotfix/Logic/ServerRole/Battle/BattleRules.cs +++ b/GameFrameX.Hotfix/Logic/ServerRole/Battle/BattleRules.cs @@ -115,30 +115,7 @@ public static (List Rounds, bool WinnerAtk) Simulate(int atkRa while (atkWins < winsNeeded && defWins < winsNeeded) { - double atkPower; - double defPower; - while (true) - { - attempts++; - if (attempts > maxAttempts) - { - // 护栏触发:以尝试次数奇偶交替打破平局(攻/守交替受益),保证有界终止。 - atkPower = attempts % 2 == 1 ? 1 : -1; - defPower = -atkPower; - break; - } - - var atkRoll = rollIndex < rolls.Count ? rolls[rollIndex] : 0.5; - rollIndex++; - var defRoll = rollIndex < rolls.Count ? rolls[rollIndex] : 0.5; - rollIndex++; - atkPower = RoundPower(atkRating, atkRoll); - defPower = RoundPower(defRating, defRoll); - if (atkPower != defPower) - { - break; - } - } + var (atkPower, defPower) = ResolveRoundPower(atkRating, defRating, rolls, ref rollIndex, ref attempts, maxAttempts); var atkWin = atkPower > defPower; if (atkWin) @@ -162,6 +139,50 @@ public static (List Rounds, bool WinnerAtk) Simulate(int atkRa return (rounds, atkWins > defWins); } + /// + /// 求解单回合双方战力:平局重掷(每次重掷仍前进 rolls 游标),护栏触发后按尝试次数奇偶交替破平局。 + /// + /// 攻方评分。 + /// 守方评分。 + /// 注入的随机数序列([0,1))。 + /// rolls 消费游标(0.5 兜底消费也前进)。 + /// 尝试次数累计(跨回合累计,含护栏触发判定)。 + /// 尝试次数硬上限。 + /// 该回合双方战力(保证不相等)。 + private static (double AtkPower, double DefPower) ResolveRoundPower(int atkRating, int defRating, IReadOnlyList rolls, ref int rollIndex, ref int attempts, int maxAttempts) + { + while (true) + { + attempts++; + if (attempts > maxAttempts) + { + // 护栏触发:以尝试次数奇偶交替打破平局(攻/守交替受益),保证有界终止。 + var guardAtkPower = attempts % 2 == 1 ? 1 : -1; + return (guardAtkPower, -guardAtkPower); + } + + var atkPower = RoundPower(atkRating, NextRoll(rolls, ref rollIndex)); + var defPower = RoundPower(defRating, NextRoll(rolls, ref rollIndex)); + if (atkPower != defPower) + { + return (atkPower, defPower); + } + } + } + + /// + /// 取下一个随机数:序列耗尽后按 0.5 兜底(游标仍前进,保持消费计数一致)。 + /// + /// 注入的随机数序列([0,1))。 + /// rolls 消费游标。 + /// 随机数(序列耗尽回落 0.5)。 + private static double NextRoll(IReadOnlyList rolls, ref int rollIndex) + { + var roll = rollIndex < rolls.Count ? rolls[rollIndex] : 0.5; + rollIndex++; + return roll; + } + /// /// 应用积分变化:胜 +30 / 败 -20,下限 0。 ///