150 lines
8 KiB
Go
150 lines
8 KiB
Go
package main
|
||
|
||
import "testing"
|
||
|
||
func TestEvaluate5Categories(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
cards []Card
|
||
want PokerHandCategory
|
||
}{
|
||
{"роял-флеш", []Card{c(Ten, Spades), c(Jack, Spades), c(Queen, Spades), c(King, Spades), c(Ace, Spades)}, PokerStraightFlush},
|
||
{"стрит-флеш", []Card{c(Five, Hearts), c(Six, Hearts), c(Seven, Hearts), c(Eight, Hearts), c(Nine, Hearts)}, PokerStraightFlush},
|
||
{"каре", []Card{c(Nine, Clubs), c(Nine, Diamonds), c(Nine, Hearts), c(Nine, Spades), c(Two, Clubs)}, PokerFourOfAKind},
|
||
{"фулл-хаус", []Card{c(King, Clubs), c(King, Diamonds), c(King, Hearts), c(Two, Spades), c(Two, Clubs)}, PokerFullHouse},
|
||
{"флеш", []Card{c(Two, Hearts), c(Five, Hearts), c(Seven, Hearts), c(Nine, Hearts), c(King, Hearts)}, PokerFlush},
|
||
{"стрит", []Card{c(Four, Clubs), c(Five, Diamonds), c(Six, Hearts), c(Seven, Spades), c(Eight, Clubs)}, PokerStraight},
|
||
{"колесо (A-5 стрит)", []Card{c(Ace, Clubs), c(Two, Diamonds), c(Three, Hearts), c(Four, Spades), c(Five, Clubs)}, PokerStraight},
|
||
{"тройка", []Card{c(Jack, Clubs), c(Jack, Diamonds), c(Jack, Hearts), c(Two, Spades), c(Nine, Clubs)}, PokerThreeOfAKind},
|
||
{"две пары", []Card{c(Ten, Clubs), c(Ten, Diamonds), c(Four, Hearts), c(Four, Spades), c(Nine, Clubs)}, PokerTwoPair},
|
||
{"пара", []Card{c(Eight, Clubs), c(Eight, Diamonds), c(Two, Hearts), c(Five, Spades), c(Nine, Clubs)}, PokerPair},
|
||
{"старшая карта", []Card{c(Two, Clubs), c(Five, Diamonds), c(Seven, Hearts), c(Nine, Spades), c(King, Clubs)}, PokerHighCard},
|
||
}
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
got := evaluate5(tt.cards)
|
||
if got.Category != tt.want {
|
||
t.Errorf("ожидалась категория %v, получено %v (карты: %v)", tt.want, got.Category, tt.cards)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
func TestWheelStraightRanksAsFive(t *testing.T) {
|
||
wheel := evaluate5([]Card{c(Ace, Clubs), c(Two, Diamonds), c(Three, Hearts), c(Four, Spades), c(Five, Clubs)})
|
||
if wheel.Category != PokerStraight || wheel.Tiebreak[0] != 5 {
|
||
t.Fatalf("колесо A-2-3-4-5 должно оцениваться как стрит со старшей картой 5, получено %+v", wheel)
|
||
}
|
||
sixHighStraight := evaluate5([]Card{c(Two, Clubs), c(Three, Diamonds), c(Four, Hearts), c(Five, Spades), c(Six, Clubs)})
|
||
if ComparePokerHands(sixHighStraight, wheel) <= 0 {
|
||
t.Errorf("стрит 2-6 должен быть старше колеса A-5")
|
||
}
|
||
}
|
||
|
||
func TestNotAStraightWhenWheelBrokenByAceHigh(t *testing.T) {
|
||
notStraight := evaluate5([]Card{c(Ace, Clubs), c(Two, Diamonds), c(Three, Hearts), c(Four, Spades), c(King, Clubs)})
|
||
if notStraight.Category == PokerStraight || notStraight.Category == PokerStraightFlush {
|
||
t.Errorf("A,2,3,4,K не должно засчитываться как стрит, получено %v", notStraight.Category)
|
||
}
|
||
}
|
||
|
||
func TestRoyalFlushBeatsStraightFlush(t *testing.T) {
|
||
royal := evaluate5([]Card{c(Ten, Spades), c(Jack, Spades), c(Queen, Spades), c(King, Spades), c(Ace, Spades)})
|
||
lower := evaluate5([]Card{c(Five, Hearts), c(Six, Hearts), c(Seven, Hearts), c(Eight, Hearts), c(Nine, Hearts)})
|
||
if ComparePokerHands(royal, lower) <= 0 {
|
||
t.Errorf("роял-флеш должен быть строго сильнее стрит-флеша 5-9")
|
||
}
|
||
}
|
||
|
||
func TestFourOfAKindKickerBreaksTie(t *testing.T) {
|
||
a := evaluate5([]Card{c(Nine, Clubs), c(Nine, Diamonds), c(Nine, Hearts), c(Nine, Spades), c(King, Clubs)})
|
||
b := evaluate5([]Card{c(Nine, Clubs), c(Nine, Diamonds), c(Nine, Hearts), c(Nine, Spades), c(Two, Clubs)})
|
||
if ComparePokerHands(a, b) <= 0 {
|
||
t.Errorf("одинаковое каре девяток с кикером королём должно побеждать кикер двойку")
|
||
}
|
||
}
|
||
|
||
func TestFullHouseTripsMatterMoreThanPair(t *testing.T) {
|
||
a := evaluate5([]Card{c(Two, Clubs), c(Two, Diamonds), c(Two, Hearts), c(King, Spades), c(King, Clubs)})
|
||
b := evaluate5([]Card{c(Queen, Clubs), c(Queen, Diamonds), c(Queen, Hearts), c(Ace, Spades), c(Ace, Clubs)})
|
||
if ComparePokerHands(b, a) <= 0 {
|
||
t.Errorf("фулл-хаус на тройке дам должен побеждать фулл-хаус на тройке двоек, несмотря на более слабую пару")
|
||
}
|
||
}
|
||
|
||
func TestTwoPairComparesHigherPairFirst(t *testing.T) {
|
||
a := evaluate5([]Card{c(King, Clubs), c(King, Diamonds), c(Two, Hearts), c(Two, Spades), c(Nine, Clubs)})
|
||
b := evaluate5([]Card{c(Queen, Clubs), c(Queen, Diamonds), c(Jack, Hearts), c(Jack, Spades), c(Ace, Clubs)})
|
||
if ComparePokerHands(a, b) <= 0 {
|
||
t.Errorf("две пары королей и двоек должны побеждать пары дам и валетов, несмотря на более слабый кикер")
|
||
}
|
||
}
|
||
|
||
func TestTwoPairKickerBreaksExactTie(t *testing.T) {
|
||
a := evaluate5([]Card{c(King, Clubs), c(King, Diamonds), c(Two, Hearts), c(Two, Spades), c(Ace, Clubs)})
|
||
b := evaluate5([]Card{c(King, Hearts), c(King, Spades), c(Two, Clubs), c(Two, Diamonds), c(Nine, Hearts)})
|
||
if ComparePokerHands(a, b) <= 0 {
|
||
t.Errorf("при равных парах решает кикер — туз должен побеждать девятку")
|
||
}
|
||
}
|
||
|
||
func TestPairComparesKickersInOrder(t *testing.T) {
|
||
a := evaluate5([]Card{c(Eight, Clubs), c(Eight, Diamonds), c(Ace, Hearts), c(Two, Spades), c(Three, Clubs)})
|
||
b := evaluate5([]Card{c(Eight, Hearts), c(Eight, Spades), c(King, Clubs), c(Queen, Diamonds), c(Jack, Hearts)})
|
||
if ComparePokerHands(a, b) <= 0 {
|
||
t.Errorf("при равных парах восьмёрок кикер-туз должен побеждать набор король-дама-валет")
|
||
}
|
||
}
|
||
|
||
func TestFlushComparesAllFiveCardsInOrder(t *testing.T) {
|
||
a := evaluate5([]Card{c(Two, Hearts), c(Five, Hearts), c(Seven, Hearts), c(Nine, Hearts), c(Ace, Hearts)})
|
||
b := evaluate5([]Card{c(Two, Spades), c(Five, Spades), c(Seven, Spades), c(Nine, Spades), c(King, Spades)})
|
||
if ComparePokerHands(a, b) <= 0 {
|
||
t.Errorf("флеш с тузом должен побеждать флеш с королём при прочих равных")
|
||
}
|
||
}
|
||
|
||
func TestIdenticalHandsSplitPot(t *testing.T) {
|
||
a := evaluate5([]Card{c(Two, Hearts), c(Five, Hearts), c(Seven, Hearts), c(Nine, Hearts), c(King, Hearts)})
|
||
b := evaluate5([]Card{c(Two, Spades), c(Five, Spades), c(Seven, Spades), c(Nine, Spades), c(King, Spades)})
|
||
if ComparePokerHands(a, b) != 0 {
|
||
t.Errorf("одинаковые по значению флеши разных мастей должны оцениваться как полностью равные (сплит банка), получено a=%+v b=%+v", a, b)
|
||
}
|
||
}
|
||
|
||
func TestEvaluateBest5ChoosesBestOfSeven(t *testing.T) {
|
||
hole := []Card{c(Ace, Spades), c(Ace, Hearts)}
|
||
board := []Card{c(Ace, Clubs), c(Ace, Diamonds), c(King, Spades), c(Two, Hearts), c(Three, Clubs)}
|
||
all := append(append([]Card{}, hole...), board...)
|
||
|
||
best := EvaluateBest5(all)
|
||
if best.Category != PokerFourOfAKind {
|
||
t.Fatalf("ожидалось каре тузов из семи карт, получено %v", best.Category)
|
||
}
|
||
if best.Tiebreak[0] != 14 || best.Tiebreak[1] != 13 {
|
||
t.Errorf("кикером каре тузов должен был стать король (13), получено %+v", best.Tiebreak)
|
||
}
|
||
}
|
||
|
||
func TestEvaluateBest5IgnoresWorseFiveCardSubset(t *testing.T) {
|
||
hole := []Card{c(Two, Hearts), c(Nine, Hearts)}
|
||
board := []Card{c(Five, Hearts), c(Six, Hearts), c(Seven, Clubs), c(Eight, Diamonds), c(King, Hearts)}
|
||
all := append(append([]Card{}, hole...), board...)
|
||
|
||
best := EvaluateBest5(all)
|
||
if best.Category != PokerFlush {
|
||
t.Fatalf("ожидался флеш как лучшая комбинация из семи карт, получено %v", best.Category)
|
||
}
|
||
}
|
||
|
||
func TestCombinations5Count(t *testing.T) {
|
||
cards := make([]Card, 7)
|
||
for i := range cards {
|
||
cards[i] = c(Rank(2+i), Clubs)
|
||
}
|
||
count := 0
|
||
combinations5(cards, func(combo []Card) { count++ })
|
||
if count != 21 {
|
||
t.Errorf("ожидалось ровно 21 сочетание из 7 по 5, получено %d", count)
|
||
}
|
||
}
|