package main import "testing" // TestOneOhOneBotFullMatches прогоняет много полных матчей (до // одного оставшегося игрока) силами OneOhOneBot для 2-6 игроков, // проверяя отсутствие паник, зависаний и потери/дублирования карт. func TestOneOhOneBotFullMatches(t *testing.T) { bot := OneOhOneBot{} for numPlayers := 2; numPlayers <= 6; numPlayers++ { for match := 0; match < 15; match++ { names := make([]string, numPlayers) for i := range names { names[i] = "Bot" } g := NewOneOhOneGame(names, -1) const maxRounds = 200 round := 0 for ; round < maxRounds; round++ { const maxSteps = 6000 steps := 0 for ; steps < maxSteps && g.Phase != OneOhOnePhaseRoundOver; steps++ { if err := bot.PlayFullTurn(g); err != nil { t.Fatalf("игроков %d, матч %d, раунд %d, шаг %d: ошибка бота: %v", numPlayers, match, round, steps, err) } } if steps >= maxSteps { t.Fatalf("игроков %d, матч %d, раунд %d: раунд не завершился за %d шагов", numPlayers, match, round, maxSteps) } if g.Result == nil { t.Fatalf("игроков %d, матч %d, раунд %d: раунд завершился без результата", numPlayers, match, round) } // проверка сохранности карт: без дублей и потерь seen := map[Card]bool{} for _, p := range g.Players { for _, c := range p.Hand { if seen[c] { t.Fatalf("игроков %d, матч %d, раунд %d: карта %v встретилась дважды", numPlayers, match, round, c) } seen[c] = true } } for _, c := range g.Stock { if seen[c] { t.Fatalf("игроков %d, матч %d, раунд %d: карта %v встретилась дважды (в колоде)", numPlayers, match, round, c) } seen[c] = true } for _, c := range g.Discard { if seen[c] { t.Fatalf("игроков %d, матч %d, раунд %d: карта %v встретилась дважды (в сбросе)", numPlayers, match, round, c) } seen[c] = true } if len(seen) != 36 { t.Fatalf("игроков %d, матч %d, раунд %d: ожидалось 36 карт в игре, получено %d", numPlayers, match, round, len(seen)) } if g.Result.MatchOver { break } g.NextRound() } if round >= maxRounds { t.Fatalf("игроков %d, матч %d: матч не завершился за %d раундов (возможное зависание)", numPlayers, match, maxRounds) } } } }