package main import ( "math/rand" "testing" ) func TestUrRollDiceDistribution(t *testing.T) { rnd := rand.New(rand.NewSource(1)) counts := [5]int{} for i := 0; i < 10000; i++ { counts[urRollDice(rnd)]++ } maxIdx := 0 for i, c := range counts { if c > counts[maxIdx] { maxIdx = i } } if maxIdx != 2 { t.Errorf("ожидалось, что значение 2 выпадает чаще всего (биномиальное распределение), получено распределение %v", counts) } if counts[0] == 0 || counts[4] == 0 { t.Errorf("значения 0 и 4 должны выпадать хоть иногда (редко, но не нулевая вероятность), получено %v", counts) } } func playUrFullGame(t *testing.T, g *UrGameState, botA, botB UrBot, rnd *rand.Rand, maxTurns int) { t.Helper() for turn := 0; turn < maxTurns && g.Result == nil; turn++ { var bot UrBot if g.CurrentPlayer == UrPlayerA { bot = botA } else { bot = botB } if err := bot.PlayFullTurn(g, rnd); err != nil { t.Fatalf("ход %d: неожиданная ошибка бота: %v", turn, err) } } if g.Result == nil { t.Fatalf("партия не завершилась за %d ходов — похоже на зависание", maxTurns) } } func TestUrBotFullGamesEasyVsEasy(t *testing.T) { rnd := rand.New(rand.NewSource(1)) for i := 0; i < 10; i++ { g := NewUrGame(UrPlayerA) bot := UrBot{Difficulty: UrDifficultyEasy} playUrFullGame(t, g, bot, bot, rnd, 2000) } } func TestUrBotFullGamesMediumVsMedium(t *testing.T) { rnd := rand.New(rand.NewSource(1)) for i := 0; i < 10; i++ { g := NewUrGame(UrPlayerA) bot := UrBot{Difficulty: UrDifficultyMedium} playUrFullGame(t, g, bot, bot, rnd, 2000) } } func TestUrBotFullGamesHardVsHard(t *testing.T) { rnd := rand.New(rand.NewSource(1)) for i := 0; i < 5; i++ { g := NewUrGame(UrPlayerA) bot := UrBot{Difficulty: UrDifficultyHard} playUrFullGame(t, g, bot, bot, rnd, 2000) } } func TestUrBotFullGamesMixedDifficulties(t *testing.T) { rnd := rand.New(rand.NewSource(1)) combos := []struct{ a, b UrDifficulty }{ {UrDifficultyEasy, UrDifficultyMedium}, {UrDifficultyMedium, UrDifficultyHard}, {UrDifficultyEasy, UrDifficultyHard}, } for _, c := range combos { g := NewUrGame(UrPlayerA) playUrFullGame(t, g, UrBot{Difficulty: c.a}, UrBot{Difficulty: c.b}, rnd, 2000) } } func TestUrMediumBotPrefersCaptureOverNeutralMove(t *testing.T) { rnd := rand.New(rand.NewSource(1)) g := NewUrGame(UrPlayerA) g.Path[UrPlayerA][0] = 4 g.Path[UrPlayerA][1] = 1 g.Path[UrPlayerB][0] = 7 g.CurrentPlayer = UrPlayerA g.Rolled = true g.DiceValue = 3 bot := UrBot{Difficulty: UrDifficultyMedium} choice := bot.DecideMove(g, rnd) if choice != 0 { t.Errorf("средний уровень должен был предпочесть взятие шашки соперника, получено индекс %d", choice) } }