package main import ( "math/rand" "testing" ) func TestPokerHandStrengthPocketAcesBeatsRandomMost(t *testing.T) { rnd := rand.New(rand.NewSource(1)) aces := [2]Card{c(Ace, Spades), c(Ace, Hearts)} strength := pokerHandStrength(aces, nil, 1, 300, rnd) if strength < 0.7 { t.Errorf("пара тузов против одного случайного соперника должна выигрывать заметно чаще, чем в 70%% случаев, получено %.2f", strength) } } func TestPokerHandStrengthWeakHandLowerThanPocketAces(t *testing.T) { rnd := rand.New(rand.NewSource(1)) aces := [2]Card{c(Ace, Spades), c(Ace, Hearts)} weak := [2]Card{c(Two, Clubs), c(Seven, Diamonds)} acesStrength := pokerHandStrength(aces, nil, 1, 300, rnd) weakStrength := pokerHandStrength(weak, nil, 1, 300, rnd) if weakStrength >= acesStrength { t.Errorf("слабая рука 2-7 разномастные не должна оцениваться сильнее пары тузов: слабая=%.2f тузы=%.2f", weakStrength, acesStrength) } } func TestCrudeStrengthPairHigherThanHighCardOnly(t *testing.T) { pair := crudeStrength([2]Card{c(King, Clubs), c(King, Diamonds)}, nil) highCard := crudeStrength([2]Card{c(Two, Clubs), c(Seven, Diamonds)}, nil) if pair <= highCard { t.Errorf("пара королей должна оцениваться выше, чем непарные 2-7, получено пара=%.2f старшая=%.2f", pair, highCard) } } func TestRemainingDeckExcludesKnownCards(t *testing.T) { hole := [2]Card{c(Ace, Spades), c(King, Hearts)} board := []Card{c(Two, Clubs), c(Three, Diamonds), c(Four, Hearts)} deck := remainingDeck(hole, board) if len(deck) != 52-5 { t.Fatalf("ожидалось 47 оставшихся карт, получено %d", len(deck)) } known := map[Card]bool{hole[0]: true, hole[1]: true} for _, cc := range board { known[cc] = true } for _, card := range deck { if known[card] { t.Errorf("известная карта %v не должна встречаться в оставшейся колоде", card) } } } func playPokerFullTournament(t *testing.T, g *PokerGameState, bots []PokerBot, rnd *rand.Rand, maxHands int) { t.Helper() for hand := 0; hand < maxHands && g.Phase != PokerPhaseTournamentOver; hand++ { steps := 0 for g.Phase != PokerPhaseShowdown && g.Phase != PokerPhaseTournamentOver && steps < 500 { steps++ seat := g.CurrentPlayerIdx if err := bots[seat].PlayFullTurn(g, seat, rnd); err != nil { t.Fatalf("раздача %d, шаг %d: неожиданная ошибка бота на месте %d: %v", hand, steps, seat, err) } } if g.Phase != PokerPhaseShowdown && g.Phase != PokerPhaseTournamentOver { t.Fatalf("раздача %d не завершилась за %d шагов — похоже на зависание", hand, steps) } if g.Phase == PokerPhaseShowdown { g.NextHand(rnd) } } if g.Phase != PokerPhaseTournamentOver { t.Fatalf("турнир не завершился за %d раздач", maxHands) } } func TestPokerBotFullTournamentAllEasy(t *testing.T) { rnd := rand.New(rand.NewSource(1)) for trial := 0; trial < 3; trial++ { g := NewPokerGame(4, 500, 10, 20, rnd) bots := []PokerBot{{Difficulty: PokerDifficultyEasy}, {Difficulty: PokerDifficultyEasy}, {Difficulty: PokerDifficultyEasy}, {Difficulty: PokerDifficultyEasy}} playPokerFullTournament(t, g, bots, rnd, 300) } } func TestPokerBotFullTournamentMixedDifficulties(t *testing.T) { rnd := rand.New(rand.NewSource(2)) for trial := 0; trial < 2; trial++ { g := NewPokerGame(4, 500, 10, 20, rnd) bots := []PokerBot{ {Difficulty: PokerDifficultyEasy}, {Difficulty: PokerDifficultyMedium}, {Difficulty: PokerDifficultyHard}, {Difficulty: PokerDifficultyMedium}, } playPokerFullTournament(t, g, bots, rnd, 300) } } func TestPokerBotFullTournamentHeadsUp(t *testing.T) { rnd := rand.New(rand.NewSource(3)) for trial := 0; trial < 3; trial++ { g := NewPokerGame(2, 500, 10, 20, rnd) bots := []PokerBot{{Difficulty: PokerDifficultyHard}, {Difficulty: PokerDifficultyEasy}} playPokerFullTournament(t, g, bots, rnd, 300) } } func TestPokerBotFullTournamentSixPlayers(t *testing.T) { rnd := rand.New(rand.NewSource(4)) g := NewPokerGame(6, 500, 10, 20, rnd) bots := make([]PokerBot, 6) for i := range bots { bots[i] = PokerBot{Difficulty: PokerDifficulty(i % 3)} } playPokerFullTournament(t, g, bots, rnd, 500) } func TestPokerBotNeverActsWithInvalidAmount(t *testing.T) { rnd := rand.New(rand.NewSource(5)) for trial := 0; trial < 5; trial++ { g := NewPokerGame(3, 200, 10, 20, rnd) bots := []PokerBot{{Difficulty: PokerDifficultyHard}, {Difficulty: PokerDifficultyHard}, {Difficulty: PokerDifficultyHard}} steps := 0 for g.Phase != PokerPhaseShowdown && g.Phase != PokerPhaseTournamentOver && steps < 200 { steps++ seat := g.CurrentPlayerIdx if err := bots[seat].PlayFullTurn(g, seat, rnd); err != nil { t.Fatalf("бот попытался сделать недопустимое действие: %v", err) } } } }