test: add fight length and KO rate distribution test
Simulates 1000 full fights with HP tracking (200 HP start, 7-10 rounds) to verify average fight length (5-10 rounds) and KO rate (20-80%). Validates the balance between damage output and HP pool. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
57af4e6a25
commit
1f532681df
@@ -420,6 +420,63 @@ describe('fight lifecycle', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('average fight lasts 5-10 rounds with ~30-70% KO rate', () => {
|
||||
const STARTING_HP = 200
|
||||
let totalRounds = 0
|
||||
let totalKOs = 0
|
||||
const totalFights = 1000
|
||||
|
||||
for (let f = 0; f < totalFights; f++) {
|
||||
const eloA = 1000 + Math.floor(Math.random() * 800)
|
||||
const eloB = 1000 + Math.floor(Math.random() * 800)
|
||||
const botA = { id: 'fl-a', name: 'A' }
|
||||
const botB = { id: 'fl-b', name: 'B' }
|
||||
const usedTypes = new Set<string>()
|
||||
let hpA = STARTING_HP
|
||||
let hpB = STARTING_HP
|
||||
let comboA = 0
|
||||
let comboB = 0
|
||||
const maxRounds = 7 + Math.floor(Math.random() * 4) // 7-10 rounds like mock.ts
|
||||
let rounds = 0
|
||||
|
||||
for (let r = 0; r < maxRounds; r++) {
|
||||
const challenge = pickChallenge(usedTypes, null, undefined, r + 1)
|
||||
usedTypes.add(challenge.type)
|
||||
const respA = mockResponse(challenge, 'confident', eloA)
|
||||
const respB = mockResponse(challenge, 'confident', eloB)
|
||||
const result = scoreRound(
|
||||
challenge, botA, botB,
|
||||
{ answer: respA.answer, timeMs: respA.timeMs, timedOut: respA.timedOut, error: respA.error },
|
||||
{ answer: respB.answer, timeMs: respB.timeMs, timedOut: respB.timedOut, error: respB.error },
|
||||
null, comboA, comboB,
|
||||
)
|
||||
|
||||
hpB = Math.max(0, hpB - result.botADamage)
|
||||
hpA = Math.max(0, hpA - result.botBDamage)
|
||||
if (result.winnerId === botA.id) { comboA++; comboB = 0 }
|
||||
else if (result.winnerId === botB.id) { comboB++; comboA = 0 }
|
||||
rounds++
|
||||
|
||||
if (hpA <= 0 || hpB <= 0) {
|
||||
totalKOs++
|
||||
break
|
||||
}
|
||||
}
|
||||
totalRounds += rounds
|
||||
}
|
||||
|
||||
const avgRounds = totalRounds / totalFights
|
||||
const koRate = totalKOs / totalFights
|
||||
|
||||
// Average fight should be 5-10 rounds
|
||||
expect(avgRounds).toBeGreaterThan(4)
|
||||
expect(avgRounds).toBeLessThan(10)
|
||||
|
||||
// KO rate should be reasonable (30-70% of fights end in KO)
|
||||
expect(koRate).toBeGreaterThan(0.2)
|
||||
expect(koRate).toBeLessThan(0.8)
|
||||
})
|
||||
|
||||
it('Elo difference correlates with win rate', () => {
|
||||
const scenarios = [
|
||||
{ eloA: 1400, eloB: 1400, expectedAWinMin: 0.40, expectedAWinMax: 0.60 },
|
||||
|
||||
Reference in New Issue
Block a user