This commit is contained in:
Jeffrey Paul 2026-01-06 10:13:38 -08:00
parent e26b79751f
commit 8dbfc45ebb
7 changed files with 394 additions and 291 deletions

View File

@ -4,9 +4,9 @@ import (
"fmt"
"time"
"git.eeqj.de/sneak/pokercore"
"github.com/rcrowley/go-metrics"
"github.com/schollz/progressbar/v3"
"sneak.berlin/go/pokercore"
)
var gameCount = 50_000
@ -101,13 +101,16 @@ func main() {
timer := metrics.NewTimer()
registry.Register("pokerGame", timer)
bar := progressbar.NewOptions(gameCount,
bar := progressbar.NewOptions(
gameCount,
progressbar.OptionSetDescription("Gambling..."),
progressbar.OptionShowCount(),
progressbar.OptionShowIts(),
progressbar.OptionSetPredictTime(true),
progressbar.OptionClearOnFinish(),
progressbar.OptionThrottle(100*time.Millisecond), // Update every 100ms
progressbar.OptionThrottle(
100*time.Millisecond,
), // Update every 100ms
)
for i := 0; i < gameCount; i++ {
@ -128,11 +131,13 @@ func main() {
fmt.Printf("Max: %d ns\n", timer.Max())
fmt.Printf("Mean: %0.2f ns\n", timer.Mean())
fmt.Printf("StdDev: %0.2f ns\n", timer.StdDev())
fmt.Printf("Percentiles: 50%%: %0.2f ns, 75%%: %0.2f ns, 95%%: %0.2f ns, 99%%: %0.2f ns\n",
fmt.Printf(
"Percentiles: 50%%: %0.2f ns, 75%%: %0.2f ns, 95%%: %0.2f ns, 99%%: %0.2f ns\n",
timer.Percentile(0.50),
timer.Percentile(0.75),
timer.Percentile(0.95),
timer.Percentile(0.99))
timer.Percentile(0.99),
)
oneWinPercentage := float64(oneWins) / float64(gameCount) * 100
twoWinPercentage := float64(twoWins) / float64(gameCount) * 100
fmt.Printf("Player 1 won: %d (%0.2f%%)\n", oneWins, oneWinPercentage)

56
examples/sf/main.go Normal file
View File

@ -0,0 +1,56 @@
package main
import (
"fmt"
"sneak.berlin/go/pokercore"
)
func main() {
var sfp bool
var tries int
var found int
const maxTries = 100_000_000
for i := 0; i < maxTries; i++ {
sfp = searchStraightFlush()
if sfp {
found++
}
tries++
if tries%1000 == 0 {
fmt.Printf("Tries: %d, Found: %d\n", tries, found)
}
}
fmt.Printf("Tries: %d, Found: %d\n", tries, found)
}
func searchStraightFlush() bool {
d := pokercore.NewDeck()
d.ShuffleRandomly()
var hand pokercore.Cards
hand = d.Deal(7)
ph, err := hand.PokerHand()
if err != nil {
fmt.Println("Error: ", err)
return false
}
if ph.Type == pokercore.StraightFlush ||
ph.Type == pokercore.RoyalFlush {
fmt.Println("straight flush found")
fmt.Println("Hand: ", hand.FormatForTerminal())
fmt.Println("PokerHand: ", ph)
return true
}
return false
}

4
go.mod
View File

@ -1,14 +1,14 @@
module git.eeqj.de/sneak/pokercore
module sneak.berlin/go/pokercore
go 1.22.2
require (
git.eeqj.de/sneak/timingbench v0.0.0-20240519025145-fb13c5c56a02
github.com/logrusorgru/aurora/v4 v4.0.0
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
github.com/schollz/progressbar/v3 v3.14.2
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.0
sneak.berlin/go/timingbench v0.0.0-20240522212031-a6243a470213
)
require (

4
go.sum
View File

@ -1,5 +1,3 @@
git.eeqj.de/sneak/timingbench v0.0.0-20240519025145-fb13c5c56a02 h1:b/v1EDAlsfvINIeV4znI/vH7SY7mUJOO1KWeBD+IW90=
git.eeqj.de/sneak/timingbench v0.0.0-20240519025145-fb13c5c56a02/go.mod h1:iKAlgt/liDtXifmn7fPJK+KYMr0c4lXYFJ+j5d3gfEQ=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@ -43,3 +41,5 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sneak.berlin/go/timingbench v0.0.0-20240522212031-a6243a470213 h1:jgfwL2lUUp6aII87vgkgFenfKftsbKvUR3jlsRdS2yo=
sneak.berlin/go/timingbench v0.0.0-20240522212031-a6243a470213/go.mod h1:W+0S+VhiuNIU/06KPhWJCmNhMaCztg2MuHitNEVEFG0=

View File

@ -5,11 +5,12 @@ import (
"testing"
"time"
"git.eeqj.de/sneak/timingbench"
"github.com/stretchr/testify/assert"
"sneak.berlin/go/timingbench"
)
func TestShuffleSpeed(t *testing.T) {
t.Parallel()
iterations := 1000
t.Logf("Running %d iterations of shuffle speed test", iterations)
// Create a context with a timeout for cancellation.
@ -27,18 +28,21 @@ func TestShuffleSpeed(t *testing.T) {
}
func TestHandFindingSpeedFiveCard(t *testing.T) {
t.Parallel()
iterations := 1000
t.Logf("Running %d iterations of hand finding speed test for 5 card hand", iterations)
measureHandFinding(t, iterations, 5)
}
func TestHandFindingSpeedSevenCard(t *testing.T) {
t.Parallel()
iterations := 1000
t.Logf("Running %d iterations of hand finding speed test for 7 card hand", iterations)
measureHandFinding(t, iterations, 7)
}
func TestHandFindingSpeedNineCard(t *testing.T) {
t.Parallel()
iterations := 100
t.Logf("Running %d iterations of hand finding speed test for 9 card hand", iterations)
measureHandFinding(t, iterations, 9)

View File

@ -12,6 +12,7 @@ type ShuffleTestResults []struct {
}
func TestPokerDeck(t *testing.T) {
t.Parallel()
d := NewDeck()
//fmt.Printf("newdeck: %+v\n", d)
d.ShuffleDeterministically(437)
@ -35,6 +36,7 @@ func TestPokerDeck(t *testing.T) {
}
func TestDealing(t *testing.T) {
t.Parallel()
d := NewDeckFromCards(Cards{
Card{Rank: ACE, Suit: HEART},
Card{Rank: DEUCE, Suit: HEART},
@ -50,6 +52,7 @@ func TestDealing(t *testing.T) {
}
func TestSpecialCaseOfFiveHighStraightFlush(t *testing.T) {
t.Parallel()
// actual bug from first implementation
d := NewDeckFromCards(Cards{
Card{Rank: ACE, Suit: HEART},
@ -68,6 +71,7 @@ func TestSpecialCaseOfFiveHighStraightFlush(t *testing.T) {
}
func TestSpecialCaseOfFiveHighStraight(t *testing.T) {
t.Parallel()
// actual bug from first implementation
d := NewDeckFromCards(Cards{
Card{Rank: ACE, Suit: HEART},

View File

@ -6,15 +6,16 @@ import (
"github.com/stretchr/testify/assert"
)
func TestHandDescripionBug(t *testing.T) {
func TestHandDescriptionBug(t *testing.T) {
t.Parallel()
playerCount := 8
d := NewDeck()
d.ShuffleDeterministically(1337)
players := make([]*Cards, playerCount)
for i := 1; i-1 < playerCount; i++ {
for i := 0; i < playerCount; i++ {
c := d.Deal(2)
players[i-1] = &c
t.Logf("Player %d dealt: %+v\n", i, c)
players[i] = &c
t.Logf("Player %d dealt: %+v\n", i+1, c)
}
t.Logf("Players: %+v\n", players)
@ -23,17 +24,17 @@ func TestHandDescripionBug(t *testing.T) {
var playerResults []*PokerHand
for i := 1; i-1 < playerCount; i++ {
t.Logf("Player %d hole cards: %+v\n", i, *players[i-1])
pc := append(*players[i-1], community...)
t.Logf("Player %d cards available: %+v\n", i, pc)
for i := 0; i < playerCount; i++ {
t.Logf("Player %d hole cards: %+v\n", i+1, *players[i])
pc := append(*players[i], community...)
t.Logf("Player %d cards available: %+v\n", i+1, pc)
hand, err := pc.IdentifyBestFiveCardPokerHand()
assert.Nil(t, err, "Expected no error")
assert.NoError(t, err, "Expected no error")
ph, err := hand.PokerHand()
assert.Nil(t, err, "Expected no error")
t.Logf("Player %d five cards used: %+v\n", i, hand)
t.Logf("Player %d poker hand: %+v\n", i, ph)
t.Logf("Player %d best hand description: %s\n", i, ph.Description())
assert.NoError(t, err, "Expected no error")
t.Logf("Player %d five cards used: %+v\n", i+1, hand)
t.Logf("Player %d poker hand: %+v\n", i+1, ph)
t.Logf("Player %d best hand description: %s\n", i+1, ph.Description())
playerResults = append(playerResults, ph)
}
@ -43,30 +44,31 @@ func TestHandDescripionBug(t *testing.T) {
t.Logf("Weird one description: %s\n", weirdOne.Description())
// T♠,7♠,9♦,7♣,T♥
assert.Equal(t, weirdOne.Description(), "two pair, tens and sevens with a nine")
assert.Equal(t, "two pair, tens and sevens with a nine", weirdOne.Description())
scoreShouldBe := ScoreTwoPair
scoreShouldBe += 10000 * TEN.Score()
scoreShouldBe += 100 * SEVEN.Score()
scoreShouldBe += NINE.Score()
assert.Equal(t, weirdOne.Score, scoreShouldBe)
assert.Equal(t, scoreShouldBe, weirdOne.Score)
cards := weirdOne.Hand
assert.True(t, cards.containsTwoPair(), "Expected hand to be two pair")
bp := cards.twoPairBiggestPair() // returns Rank, because describing a pair
assert.Equal(t, bp, TEN, "Expected biggest pair to be a ten")
assert.Equal(t, TEN, bp, "Expected biggest pair to be a ten")
sp := cards.twoPairSmallestPair() // returns Rank, because describing a pair
assert.Equal(t, sp, SEVEN, "Expected smallest pair to be a seven")
assert.Equal(t, SEVEN, sp, "Expected smallest pair to be a seven")
k := cards.twoPairKicker() // returns Card, because describing a single card
assert.Equal(t, k.Rank, NINE, "Expected kicker to be a nine")
assert.Equal(t, NINE, k.Rank, "Expected kicker to be a nine")
}
func TestAceLowStraight(t *testing.T) {
t.Parallel()
t.Run("Test Ace-Low Straight", func(t *testing.T) {
hand := Cards{
AceOfSpades(),
DeuceOfHearts(),
@ -76,22 +78,25 @@ func TestAceLowStraight(t *testing.T) {
}
assert.True(t, hand.containsStraight(), "Expected hand to be a straight")
ph, err := hand.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.NoError(t, err, "Expected no error")
assert.Greater(t, ph.Score, 0, "Expected score to be greater than 0")
assert.Less(t, ph.Score, 100000000000000000, "Expected score to be less than 100000000000000000")
assert.Equal(t, ph.Score, ScoreStraight+FIVE.Score())
assert.Equal(t, ph.Description(), "a five high straight")
assert.True(t, hand.HighestRank() == ACE, "Expected highest rank to be an ace")
assert.Equal(t, "a five high straight", ph.Description())
assert.Equal(t, ACE, hand.HighestRank(), "Expected highest rank to be an ace")
s := hand.SortByRankAscending()
assert.True(t, s.First().Rank == DEUCE, "Expected first card to be a deuce")
assert.True(t, s.Last().Rank == ACE, "Expected last card in sorted to be a ace")
assert.True(t, s.Second().Rank == THREE, "Expected second card to be a three")
assert.True(t, s.Third().Rank == FOUR, "Expected third card to be a four")
assert.True(t, s.Fourth().Rank == FIVE, "Expected fourth card to be a five")
assert.True(t, s.Fifth().Rank == ACE, "Expected fifth card to be an ace")
assert.Equal(t, DEUCE, s.First().Rank, "Expected first card to be a deuce")
assert.Equal(t, ACE, s.Last().Rank, "Expected last card in sorted to be an ace")
assert.Equal(t, THREE, s.Second().Rank, "Expected second card to be a three")
assert.Equal(t, FOUR, s.Third().Rank, "Expected third card to be a four")
assert.Equal(t, FIVE, s.Fourth().Rank, "Expected fourth card to be a five")
assert.Equal(t, ACE, s.Fifth().Rank, "Expected fifth card to be an ace")
})
}
func TestAceHighStraight(t *testing.T) {
t.Parallel()
t.Run("Test Ace-High Straight", func(t *testing.T) {
hand := Cards{
TenOfSpades(),
JackOfHearts(),
@ -105,16 +110,19 @@ func TestAceHighStraight(t *testing.T) {
newDeck.ShuffleDeterministically(123456789)
shuffledHand := newDeck.Deal(5)
assert.True(t, shuffledHand.containsStraight(), "Expected hand to still be a straight after shuffle")
assert.True(t, shuffledHand.HighestRank() == ACE, "Expected highest rank to be an ace")
assert.Equal(t, ACE, shuffledHand.HighestRank(), "Expected highest rank to be an ace")
sortedHand := shuffledHand.SortByRankAscending()
assert.True(t, sortedHand[0].Rank == TEN, "Expected lowest rank to be a ten")
assert.True(t, sortedHand[1].Rank == JACK, "Expected second lowest rank to be a jack")
assert.True(t, sortedHand[2].Rank == QUEEN, "Expected third lowest rank to be a queen")
assert.True(t, sortedHand[3].Rank == KING, "Expected fourth lowest rank to be a king")
assert.True(t, sortedHand[4].Rank == ACE, "Expected highest rank to be an ace")
assert.Equal(t, TEN, sortedHand[0].Rank, "Expected lowest rank to be a ten")
assert.Equal(t, JACK, sortedHand[1].Rank, "Expected second lowest rank to be a jack")
assert.Equal(t, QUEEN, sortedHand[2].Rank, "Expected third lowest rank to be a queen")
assert.Equal(t, KING, sortedHand[3].Rank, "Expected fourth lowest rank to be a king")
assert.Equal(t, ACE, sortedHand[4].Rank, "Expected highest rank to be an ace")
})
}
func TestOtherStraight(t *testing.T) {
t.Parallel()
t.Run("Test Other Straight", func(t *testing.T) {
hand := Cards{
DeuceOfSpades(),
ThreeOfHearts(),
@ -126,17 +134,18 @@ func TestOtherStraight(t *testing.T) {
newDeck := NewDeckFromCards(hand)
newDeck.ShuffleDeterministically(123456789)
//fmt.Printf("Shuffled deck: %s\n", newDeck.String())
//fmt.Printf("new deck has %d cards\n", newDeck.Count())
shuffledHand := newDeck.Deal(5)
assert.True(t, shuffledHand.containsStraight(), "Expected hand to still be a straight after shuffle")
assert.False(t, shuffledHand.containsTwoPair(), "Expected hand to not be two pair")
assert.False(t, shuffledHand.containsPair(), "Expected hand to not be a pair")
assert.True(t, shuffledHand.HighestRank() == SIX, "Expected highest rank to be a six")
assert.True(t, shuffledHand.SortByRankAscending().First().Rank == DEUCE, "Expected first card to be a deuce")
assert.Equal(t, SIX, shuffledHand.HighestRank(), "Expected highest rank to be a six")
assert.Equal(t, DEUCE, shuffledHand.SortByRankAscending().First().Rank, "Expected first card to be a deuce")
})
}
func TestFlush(t *testing.T) {
t.Parallel()
t.Run("Test Flush", func(t *testing.T) {
hand := Cards{
AceOfSpades(),
DeuceOfSpades(),
@ -147,8 +156,6 @@ func TestFlush(t *testing.T) {
assert.True(t, hand.containsFlush(), "Expected hand to be a flush")
newDeck := NewDeckFromCards(hand)
newDeck.ShuffleDeterministically(123456789)
//fmt.Printf("Shuffled deck: %s\n", newDeck.String())
//fmt.Printf("new deck has %d cards\n", newDeck.Count())
shuffledHand := newDeck.Deal(5)
assert.True(t, shuffledHand.containsFlush(), "Expected hand to still be a flush after shuffle")
@ -159,15 +166,17 @@ func TestFlush(t *testing.T) {
x += THREE.Score()
x += FOUR.Score()
x += SIX.Score()
//fmt.Printf("a-2-3-4-6 flush score should be: %d\n", x)
ph, err := shuffledHand.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.Greater(t, ph.Score, 0, "Expected score to be nonzero 0")
assert.NoError(t, err, "Expected no error")
assert.Greater(t, ph.Score, 0, "Expected score to be nonzero")
assert.Equal(t, ph.Score, x)
})
}
func TestStraightFlush(t *testing.T) {
t.Parallel()
t.Run("Test Straight Flush", func(t *testing.T) {
hand := Cards{
SixOfSpades(),
DeuceOfSpades(),
@ -185,19 +194,20 @@ func TestStraightFlush(t *testing.T) {
assert.False(t, hand.containsTwoPair(), "Expected hand to not be two pair")
assert.False(t, hand.containsPair(), "Expected hand to not be a pair")
assert.True(t, hand.HighestRank() == SIX, "Expected highest rank to be a six")
assert.Equal(t, SIX, hand.HighestRank(), "Expected highest rank to be a six")
nd := NewDeckFromCards(hand)
nd.ShuffleDeterministically(123456789)
//fmt.Printf("Shuffled deck: %s\n", nd.String())
//fmt.Printf("new deck has %d cards\n", nd.Count())
shuffledHand := nd.Deal(5)
assert.True(t, shuffledHand.containsStraightFlush(), "Expected hand to still be a straight flush after shuffle")
assert.True(t, shuffledHand.HighestRank() == SIX, "Expected highest rank to still be a six after shuffle")
assert.True(t, shuffledHand.HighestRank() == SIX, "Expected highest rank to be a six after shuffle even with aces low")
assert.Equal(t, SIX, shuffledHand.HighestRank(), "Expected highest rank to still be a six after shuffle")
assert.Equal(t, SIX, shuffledHand.HighestRank(), "Expected highest rank to be a six after shuffle even with aces low")
})
}
func TestFourOfAKind(t *testing.T) {
t.Parallel()
t.Run("Test Four of a Kind", func(t *testing.T) {
hand := Cards{
SixOfSpades(),
SixOfHearts(),
@ -223,10 +233,13 @@ func TestFourOfAKind(t *testing.T) {
assert.True(t, hand.containsTwoPair(), "Expected hand to contain two pair")
assert.True(t, hand.containsPair(), "Expected hand to contain a pair")
assert.True(t, hand.HighestRank() == SIX, "Expected highest rank to be a six")
assert.Equal(t, SIX, hand.HighestRank(), "Expected highest rank to be a six")
})
}
func TestRoyalFlush(t *testing.T) {
t.Parallel()
t.Run("Test Royal Flush", func(t *testing.T) {
hand := Cards{
TenOfSpades(),
JackOfSpades(),
@ -245,11 +258,14 @@ func TestRoyalFlush(t *testing.T) {
assert.False(t, hand.containsTwoPair(), "Expected hand to not be two pair")
assert.False(t, hand.containsPair(), "Expected hand to not be a pair")
assert.True(t, hand.HighestRank() == ACE, "Expected highest rank to be an ace")
assert.False(t, hand.HighestRank() == TEN, "Expected highest rank to not be an ace")
assert.Equal(t, ACE, hand.HighestRank(), "Expected highest rank to be an ace")
assert.NotEqual(t, TEN, hand.HighestRank(), "Expected highest rank to not be a ten")
})
}
func TestUnmadeHand(t *testing.T) {
t.Parallel()
t.Run("Test Unmade Hand", func(t *testing.T) {
hand := Cards{
TenOfSpades(),
JackOfDiamonds(),
@ -266,11 +282,14 @@ func TestUnmadeHand(t *testing.T) {
assert.False(t, hand.containsThreeOfAKind(), "Expected hand to not be three of a kind")
assert.False(t, hand.containsTwoPair(), "Expected hand to not be two pair")
assert.False(t, hand.containsPair(), "Expected hand to not be a pair")
assert.True(t, hand.HighestRank() == KING, "Expected highest rank to be a king")
assert.Equal(t, KING, hand.HighestRank(), "Expected highest rank to be a king")
assert.True(t, hand.isUnmadeHand(), "Expected hand to be unmade")
})
}
func TestTwoPair(t *testing.T) {
t.Parallel()
t.Run("Test Two Pair", func(t *testing.T) {
hand := Cards{
KingOfSpades(),
JackOfDiamonds(),
@ -287,11 +306,14 @@ func TestTwoPair(t *testing.T) {
assert.False(t, hand.containsThreeOfAKind(), "Expected hand to not be three of a kind")
assert.True(t, hand.containsTwoPair(), "Expected hand to be two pair")
assert.True(t, hand.containsPair(), "Expected hand to also be a pair")
assert.True(t, hand.HighestRank() == KING, "Expected highest rank to be a king")
assert.Equal(t, KING, hand.HighestRank(), "Expected highest rank to be a king")
assert.False(t, hand.isUnmadeHand(), "Expected hand to not be unmade")
})
}
func TestDetectDuplicates(t *testing.T) {
t.Parallel()
t.Run("Test Detect Duplicates", func(t *testing.T) {
hand := Cards{
KingOfSpades(),
JackOfDiamonds(),
@ -300,9 +322,12 @@ func TestDetectDuplicates(t *testing.T) {
TenOfSpades(),
}
assert.True(t, hand.containsDuplicates(), "Expected hand to contain duplicates")
})
}
func TestHandScore(t *testing.T) {
t.Parallel()
t.Run("Test Hand Score", func(t *testing.T) {
hand := Cards{
KingOfSpades(),
JackOfDiamonds(),
@ -311,33 +336,33 @@ func TestHandScore(t *testing.T) {
TenOfSpades(),
}
ph, error := hand.PokerHand()
assert.Nil(t, error, "Expected no error")
assert.True(t, ph.Score > 0, "Expected score to be nonzero 0")
ph, err := hand.PokerHand()
assert.NoError(t, err, "Expected no error")
assert.True(t, ph.Score > 0, "Expected score to be nonzero")
assert.True(t, ph.Score < 100000000000000000, "Expected score to be less than 100000000000000000")
//fmt.Printf("PokerHand: %v+\n", ph)
//fmt.Printf("PH score: %d\n", ph.Score)
// write more assertions FIXME
})
}
func TestTwoPairBug(t *testing.T) {
t.Parallel()
t.Run("Test Two Pair Bug", func(t *testing.T) {
// this is an actual bug in the first implementation
c, err := NewCardsFromString("9♠,9♣,Q♥,Q♦,K♣")
assert.Nil(t, err, "Expected no error")
//fmt.Printf("Cards: %v+\n", c)
assert.NoError(t, err, "Expected no error")
ph, err := c.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.Greater(t, ph.Score, 0, "Expected score to be nonzero 0")
assert.NoError(t, err, "Expected no error")
assert.Greater(t, ph.Score, 0, "Expected score to be nonzero")
desc := ph.Description()
assert.Equal(t, desc, "two pair, queens and nines with a king")
//fmt.Printf("PokerHand: %v+\n", ph)
//fmt.Printf("PH score: %d\n", ph.Score)
assert.Equal(t, "two pair, queens and nines with a king", desc)
})
}
func TestScoringStructureQuads(t *testing.T) {
t.Parallel()
t.Run("Test Scoring Structure Quads", func(t *testing.T) {
// this test case was for a bug, but is now fixed
handA := Cards{
DeuceOfSpades(),
DeuceOfHearts(),
@ -355,13 +380,21 @@ func TestScoringStructureQuads(t *testing.T) {
}
phA, err := handA.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.NoError(t, err, "Expected no error")
phB, err := handB.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.NoError(t, err, "Expected no error")
assert.Greater(t, phB.Score, phA.Score, "Expected hand B to be higher than hand A")
})
}
func TestScoringStructureFullHouse(t *testing.T) {
t.Parallel()
t.Run("Test Scoring Structure Full House", func(t *testing.T) {
// this test case documents an actual bug i found in my scoring code
// related to the fact that i was multiplying by 100 then by 1000,
// instead of by 100 then by 10000 in the scoring. because the ranks
// are 2-14, the different levels of kickers (or in the case of a full
// house, the pair) were not distinguishing sufficiently.
handA := Cards{
DeuceOfSpades(),
DeuceOfHearts(),
@ -371,7 +404,7 @@ func TestScoringStructureFullHouse(t *testing.T) {
}
phA, err := handA.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.NoError(t, err, "Expected no error")
deucesFullOfAcesScore := phA.Score
handB := Cards{
@ -382,8 +415,9 @@ func TestScoringStructureFullHouse(t *testing.T) {
DeuceOfHearts(),
}
phB, err := handB.PokerHand()
assert.Nil(t, err, "Expected no error")
assert.NoError(t, err, "Expected no error")
threesFullOfDeucesScore := phB.Score
assert.Greater(t, threesFullOfDeucesScore, deucesFullOfAcesScore, "Expected Threes full of deuces to beat deuces full of aces")
})
}