You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.4 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package game
import (
"testing"
"time"
)
func TestBalanceMonteCarlo_WolfMedianGear(t *testing.T) {
n := 8000
if testing.Short() {
n = 1500
}
const seed = 424242
level := 5
r := RunBalanceMonteCarlo(level, n, seed, ReferenceGearMedian, BalanceEnemyWolfOnly)
t.Logf("level=%d wolf-only median-gear: win=%.3f med=%s p90=%s mean=%s (n=%d)",
level, r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond), r.MeanDur.Round(time.Millisecond), n)
if r.Iterations != n {
t.Fatalf("iterations: got %d want %d", r.Iterations, n)
}
}
func TestBalanceMonteCarlo_MixedSpawnL10(t *testing.T) {
if testing.Short() {
t.Skip()
}
const n = 4000
const seed = 777
r := RunBalanceMonteCarlo(10, n, seed, ReferenceGearRolled, BalanceEnemyMixedSpawn)
t.Logf("level=10 mixed rolled-gear: win=%.3f med=%s p90=%s", r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond))
}
func TestBalanceMonteCarlo_WolfCurve(t *testing.T) {
if testing.Short() {
t.Skip()
}
const n = 6000
const seed = 99
for _, level := range []int{5, 10, 15, 20, 25} {
r := RunBalanceMonteCarlo(level, n, seed+int64(level*17), ReferenceGearMedian, BalanceEnemyWolfOnly)
t.Logf("L%2d wolf-only median-gear: win=%.3f med=%s p90=%s", level, r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond))
}
}
func TestBalanceMonteCarlo_CurveProbe(t *testing.T) {
if testing.Short() {
t.Skip("curve probe")
}
const n = 5000
const seed = 2026
for _, level := range []int{1, 3, 5, 10, 15, 20} {
r := RunBalanceMonteCarlo(level, n, seed+int64(level), ReferenceGearMedian, BalanceEnemyMixedSpawn)
t.Logf("L%2d mixed median-gear: win=%.3f med=%s p90=%s", level, r.WinRate, r.MedianDur.Round(time.Millisecond), r.P90Dur.Round(time.Millisecond))
}
}
// TestBalanceMonteCarlo_L5MixedRegression guards against extreme drift after tuning changes.
func TestBalanceMonteCarlo_L5MixedRegression(t *testing.T) {
if testing.Short() {
t.Skip()
}
const n = 4000
r := RunBalanceMonteCarlo(5, n, 424242, ReferenceGearMedian, BalanceEnemyMixedSpawn)
if r.WinRate < 0.30 || r.WinRate > 1.00 {
t.Fatalf("L5 mixed win rate drift: %.3f (expected rough band 0.301.00)", r.WinRate)
}
// Mixed spawn has high variance; median duration should stay in a sane band after pace/damage retunes.
if r.MedianDur < 90*time.Second || r.MedianDur > 12*time.Minute {
t.Fatalf("L5 mixed median duration drift: %s (expected rough ~1.510 min band)", r.MedianDur)
}
}