Fix false draw case.
This commit is contained in:
+18
-12
@@ -392,8 +392,8 @@ func effectCount(e Effect, s *battleSide, u *BattleUnit, enemy *battleSide) int
|
||||
// pet with Damage >= Power faints, firing Faint effects. Survivors that
|
||||
// took damage fire Hurt effects. Shields (Turtle, Gorilla, Melon) block
|
||||
// entire hits; Garlic shaves 1 from each; Scorpion KOs whatever its clash
|
||||
// attack manages to hurt. A clash that changes nothing ends the battle as a
|
||||
// stalemate.
|
||||
// attack manages to hurt. A clash that changes nothing is a stalemate: that
|
||||
// pair both faint so the pets behind them can settle the battle.
|
||||
//
|
||||
// resolveBattles is the orchestrator: it runs each (deterministic) simulation
|
||||
// and publishes the completed results.
|
||||
@@ -1807,12 +1807,18 @@ func (g *Game) runBattle(first, second int) *BattleResult {
|
||||
if dealtB > 0 && ua.hasKnockout() {
|
||||
ub.Damage = max(ub.Damage, ub.Power())
|
||||
}
|
||||
// Stalemate: the clash changed nothing at all, so repeating it never
|
||||
// will either — this pair is stuck no matter how many exchanges it
|
||||
// gets. Resolve it like a deadlock (below) rather than ending the
|
||||
// battle: the pets *behind* these two can still settle it.
|
||||
stuck := ua.Alive() && ub.Alive() && dealtA == 0 && dealtB == 0 &&
|
||||
blockA == nil && blockB == nil && prevA == nil && prevB == nil
|
||||
// Deadlock guard: if the pair keeps surviving, count the exchanges and
|
||||
// force a mutual knockout once they hit the limit.
|
||||
deadlocked := false
|
||||
if ua.Alive() && ub.Alive() {
|
||||
clashStreak++
|
||||
if clashStreak >= deadlockLimit {
|
||||
if stuck || clashStreak >= deadlockLimit {
|
||||
deadlocked = true
|
||||
ua.Damage = max(ua.Damage, ua.Power())
|
||||
ub.Damage = max(ub.Damage, ub.Power())
|
||||
@@ -1823,6 +1829,9 @@ func (g *Game) runBattle(first, second int) *BattleResult {
|
||||
clashTxt := fmt.Sprintf("%s's %s and %s's %s trade blows.",
|
||||
pname(0), ua.Card.Name, pname(1), ub.Card.Name)
|
||||
switch da, db := !ua.Alive(), !ub.Alive(); {
|
||||
case stuck:
|
||||
clashTxt = fmt.Sprintf("%s's %s and %s's %s can't hurt each other — both faint.",
|
||||
pname(0), ua.Card.Name, pname(1), ub.Card.Name)
|
||||
case deadlocked:
|
||||
clashTxt = fmt.Sprintf("%s's %s and %s's %s are deadlocked after %d clashes — both faint.",
|
||||
pname(0), ua.Card.Name, pname(1), ub.Card.Name, deadlockLimit)
|
||||
@@ -1851,10 +1860,6 @@ func (g *Game) runBattle(first, second int) *BattleResult {
|
||||
if prevB != nil {
|
||||
emitPrevent(1, ub.Card.Name, prevB)
|
||||
}
|
||||
if ua.Alive() && ub.Alive() && dealtA == 0 && dealtB == 0 &&
|
||||
blockA == nil && blockB == nil && prevA == nil && prevB == nil {
|
||||
break // stalemate: nothing can ever change
|
||||
}
|
||||
dealt := []int{dealtA, dealtB}
|
||||
for seat, u := range []*BattleUnit{ua, ub} {
|
||||
if !u.Alive() {
|
||||
@@ -1874,15 +1879,16 @@ func (g *Game) runBattle(first, second int) *BattleResult {
|
||||
}
|
||||
|
||||
// A single side that can still field a pet wins; anything else (both out,
|
||||
// or a stalemate with pets on both sides) is a draw. We test canField,
|
||||
// not unit, because the loop can break the instant one side runs out while
|
||||
// the other's current pet has just fainted — that side still has pets left
|
||||
// in its stack (it simply wasn't refilled) and is the rightful winner.
|
||||
// or the iteration cap tripping with pets on both sides) is a draw. We test
|
||||
// canField, not unit, because the loop can break the instant one side runs
|
||||
// out while the other's current pet has just fainted — that side still has
|
||||
// pets left in its stack (it simply wasn't refilled) and is the rightful
|
||||
// winner.
|
||||
winner := -1
|
||||
for side, s := range sides {
|
||||
if s.canField() {
|
||||
if winner >= 0 {
|
||||
winner = -1 // both still standing: a stalemate draw
|
||||
winner = -1 // both still standing: a draw
|
||||
break
|
||||
}
|
||||
winner = side
|
||||
|
||||
Reference in New Issue
Block a user