From c2dfd09e9f4533b410166584a508bec3037e5b45 Mon Sep 17 00:00:00 2001 From: sneak Date: Sun, 22 Dec 2019 19:14:12 -0800 Subject: [PATCH] cleaning up now that i actually know this language --- Makefile | 8 +- card.go | 94 ++++++++++ main.go => cmd/hehand/main.go | 2 +- deck.go | 92 ++++++++++ pokercore/pokercore_test.go => deck_test.go | 2 +- pokercore/pokerhand.go => hand.go | 6 +- misc/generateTestSuite.go | 10 - pokercore/Makefile | 10 - pokercore/pokercore.go | 191 -------------------- 9 files changed, 197 insertions(+), 218 deletions(-) create mode 100644 card.go rename main.go => cmd/hehand/main.go (98%) create mode 100644 deck.go rename pokercore/pokercore_test.go => deck_test.go (97%) rename pokercore/pokerhand.go => hand.go (93%) delete mode 100644 misc/generateTestSuite.go delete mode 100644 pokercore/Makefile delete mode 100644 pokercore/pokercore.go diff --git a/Makefile b/Makefile index d0ae92e..cb24be5 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,8 @@ default: test -test: - cd pokercore && make test +test: *.go + go get -t -v + go test -v + +run: + cd cmd/* && go get -v && go build . diff --git a/card.go b/card.go new file mode 100644 index 0000000..bbd92f2 --- /dev/null +++ b/card.go @@ -0,0 +1,94 @@ +package poker + +import "encoding/binary" +import "fmt" +import crand "crypto/rand" +import . "github.com/logrusorgru/aurora" +import log "github.com/sirupsen/logrus" + +import "strings" + +type Suit rune +type Rank rune + +const ( + CLUB Suit = '\u2663' + SPADE Suit = '\u2660' + DIAMOND Suit = '\u2666' + HEART Suit = '\u2665' +) + +const ( + ACE Rank = 'A' + DEUCE Rank = '2' + THREE Rank = '3' + FOUR Rank = '4' + FIVE Rank = '5' + SIX Rank = '6' + SEVEN Rank = '7' + EIGHT Rank = '8' + NINE Rank = '9' + TEN Rank = 'T' + JACK Rank = 'J' + QUEEN Rank = 'Q' + KING Rank = 'K' +) + +type Card struct { + Rank Rank + Suit Suit +} + +type Cards []*Card + +func (c *Cards) formatForTerminal() (output string) { + var cardstrings []string + for _, card := range *c { + cardstrings = append(cardstrings, card.formatForTerminal()) + } + output = strings.Join(cardstrings, ",") + return output +} + +func (c *Card) formatForTerminal() (output string) { + var rank string + var suit string + color := Red + switch c.Suit { + case Suit(DIAMOND): + color = Blue + case Suit(HEART): + color = Red + case Suit(CLUB): + color = Green + case Suit(SPADE): + color = Black + } + + rank = fmt.Sprintf("%s", BgGray(Bold(color(*c.Rank)))) + suit = fmt.Sprintf("%s", BgGray(Bold(color(*c.Suit)))) + output = fmt.Sprintf("%s%s", rank, suit) + return output +} + +func cryptoUint64() (v uint64) { + err := binary.Read(crand.Reader, binary.BigEndian, &v) + if err != nil { + log.Fatal(err) + } + log.Debugf("crand cryptosource is returning Uint64: %d", v) + return v +} + +func (self *Card) String() string { + return fmt.Sprintf("%s%s", string(self.Rank), string(self.Suit)) +} + +func (s Cards) String() (output string) { + var cardstrings []string + for i := 0; i < len(s); i++ { + cardstrings = append(cardstrings, s[i].String()) + } + output = strings.Join(cardstrings, ",") + return output +} diff --git a/main.go b/cmd/hehand/main.go similarity index 98% rename from main.go rename to cmd/hehand/main.go index af490fa..f5bf002 100644 --- a/main.go +++ b/cmd/hehand/main.go @@ -4,7 +4,7 @@ import ( "errors" "fmt" log "github.com/sirupsen/logrus" - "github.com/sneak/gopoker/pokercore" + "github.com/sneak/poker" "io" "net/http" "net/rpc" diff --git a/deck.go b/deck.go new file mode 100644 index 0000000..d69abd2 --- /dev/null +++ b/deck.go @@ -0,0 +1,92 @@ +package poker + +import "encoding/binary" +import "fmt" +import crand "crypto/rand" +import . "github.com/logrusorgru/aurora" +import log "github.com/sirupsen/logrus" +import rand "math/rand" + +import "strings" + +type Deck struct { + Cards Cards + DealIndex int + ShuffleSeedVal int64 +} + +func cryptoUint64() (v uint64) { + err := binary.Read(crand.Reader, binary.BigEndian, &v) + if err != nil { + log.Fatal(err) + } + log.Debugf("crand cryptosource is returning Uint64: %d", v) + return v +} + +func NewShuffledDeck() *Deck { + d := newDeck() + d.ShuffleSeedVal = int64(cryptoUint64()) + d.Shuffle() +} + +func NewDeckFromSeed(seed int64) *Deck { + d := newDeck() + d.ShuffleSeedVal = seed + d.Shuffle() +} + +func newDeck() *Deck { + + self := new(Deck) + + ranks := []Rank{ + ACE, DEUCE, THREE, FOUR, FIVE, + SIX, SEVEN, EIGHT, NINE, TEN, JACK, + QUEEN, KING} + + suits := []Suit{HEART, DIAMOND, CLUB, SPADE} + + self.Cards = make([]*Card, 52) + + tot := 0 + for i := 0; i < len(ranks); i++ { + for n := 0; n < len(suits); n++ { + self.Cards[tot] = &Card{ + Rank: ranks[i], + Suit: suits[n], + } + tot++ + } + } + self.DealIndex = 0 + return self +} + +func (self *Deck) Shuffle() { + //FIXME(sneak) not sure if this is constant time or not + rnd := rand.New(rand.NewSource(self.ShuffleSeedVal))) + rnd.Shuffle(len(self.Cards), func(i, j int) { self.Cards[i], self.Cards[j] = self.Cards[j], self.Cards[i] }) + self.DealIndex = 0 +} + +func (self *Deck) Deal(n int) (output Cards) { + + if (self.DealIndex + n) > len(self.Cards) { + return output + } + + for i := 0; i < n; i++ { + output = append(output, self.Cards[self.DealIndex+1]) + self.DealIndex++ + } + return output +} + +func (self *Deck) Dealt() int { + return self.DealIndex +} + +func (self *Deck) Remaining() int { + return (len(self.Cards) - self.DealIndex) +} diff --git a/pokercore/pokercore_test.go b/deck_test.go similarity index 97% rename from pokercore/pokercore_test.go rename to deck_test.go index e525155..89b2bfe 100644 --- a/pokercore/pokercore_test.go +++ b/deck_test.go @@ -1,4 +1,4 @@ -package pokercore +package poker import "github.com/stretchr/testify/assert" import "testing" diff --git a/pokercore/pokerhand.go b/hand.go similarity index 93% rename from pokercore/pokerhand.go rename to hand.go index 48b9dbf..3f427de 100644 --- a/pokercore/pokerhand.go +++ b/hand.go @@ -1,4 +1,4 @@ -package pokercore +package poker type HEPokerHand struct { Cards Cards @@ -28,7 +28,7 @@ const ( ) func (self *HandScore) BeatsHand(v *HandScore) bool { - + panic("not implemented") } func (self *HEPokerHand) IsReducedYet() bool { @@ -53,7 +53,7 @@ func (self *HEPokerHand) IsStraight() bool { func (self *HEPokerHand) IsFlush() bool { } -func (self *HEPokerHand) IsBoat() bool { +func (self *HEPokerHand) IsFullHouse() bool { } func (self *HEPokerHand) ScoreHand() *HandScore { diff --git a/misc/generateTestSuite.go b/misc/generateTestSuite.go deleted file mode 100644 index 5ea67de..0000000 --- a/misc/generateTestSuite.go +++ /dev/null @@ -1,10 +0,0 @@ -package main - -import "fmt" -import "github.com/sneak/gopoker/pokercore" - -func main() { - myDeck := pokercore.NewDeck() - myDeck.ShuffleRandomly() - fmt.Println("%s", myDeck.Cards) -} diff --git a/pokercore/Makefile b/pokercore/Makefile deleted file mode 100644 index 9772059..0000000 --- a/pokercore/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -default: test - -.PHONY: pkgs test - -fetch: - go get -t - -test: *.go - go test -v - diff --git a/pokercore/pokercore.go b/pokercore/pokercore.go deleted file mode 100644 index 2bb9405..0000000 --- a/pokercore/pokercore.go +++ /dev/null @@ -1,191 +0,0 @@ -package pokercore - -import "encoding/binary" -import "fmt" -import crand "crypto/rand" -import . "github.com/logrusorgru/aurora" -import log "github.com/sirupsen/logrus" -import rand "math/rand" - -import "strings" - -type Suit rune -type Rank rune - -const ( - CLUB Suit = '\u2663' - SPADE Suit = '\u2660' - DIAMOND Suit = '\u2666' - HEART Suit = '\u2665' -) - -/* -// emoji are cooler anyway -const CLUB = "C" -const SPADE = "S" -const DIAMOND = "D" -const HEART = "H" -*/ - -const ( - ACE Rank = 'A' - DEUCE Rank = '2' - THREE Rank = '3' - FOUR Rank = '4' - FIVE Rank = '5' - SIX Rank = '6' - SEVEN Rank = '7' - EIGHT Rank = '8' - NINE Rank = '9' - TEN Rank = 'T' - JACK Rank = 'J' - QUEEN Rank = 'Q' - KING Rank = 'K' -) - -type TestGenerationIteration struct { - Deck *Deck - Seed int64 -} - -type Card struct { - Rank Rank - Suit Suit -} - -type Cards []*Card - -type Deck struct { - Cards Cards - DealIndex int - ShuffleSeedVal int64 -} - -func formatCardsForTerminal(c Cards) (output string) { - var cardstrings []string - for i := 0; i < len(c); i++ { - cardstrings = append(cardstrings, formatCardForTerminal(*c[i])) - } - output = strings.Join(cardstrings, ",") - return output - -} - -func formatCardForTerminal(c Card) (output string) { - var rank string - var suit string - color := Red - switch c.Suit { - case Suit(DIAMOND): - color = Blue - case Suit(HEART): - color = Red - case Suit(CLUB): - color = Green - case Suit(SPADE): - color = Black - } - - rank = fmt.Sprintf("%s", BgGray(Bold(color(c.Rank)))) - suit = fmt.Sprintf("%s", BgGray(Bold(color(c.Suit)))) - output = fmt.Sprintf("%s%s", rank, suit) - return output -} - -func cryptoUint64() (v uint64) { - err := binary.Read(crand.Reader, binary.BigEndian, &v) - if err != nil { - log.Fatal(err) - } - log.Debugf("crand cryptosource is returning Uint64: %d", v) - return v -} - -func (self *Card) String() string { - return fmt.Sprintf("%s%s", string(self.Rank), string(self.Suit)) -} - -func NewDeck() *Deck { - - self := new(Deck) - - ranks := []Rank{ - ACE, DEUCE, THREE, FOUR, FIVE, - SIX, SEVEN, EIGHT, NINE, TEN, JACK, - QUEEN, KING} - - suits := []Suit{HEART, DIAMOND, CLUB, SPADE} - - self.Cards = make([]*Card, 52) - - tot := 0 - for i := 0; i < len(ranks); i++ { - for n := 0; n < len(suits); n++ { - self.Cards[tot] = &Card{ - Rank: ranks[i], - Suit: suits[n], - } - tot++ - } - } - self.DealIndex = 0 - return self -} - -func (self *Deck) ShuffleRandomly() { - rnd := rand.New(rand.NewSource(int64(cryptoUint64()))) - //FIXME(sneak) not sure if this is constant time or not - rnd.Shuffle(len(self.Cards), func(i, j int) { self.Cards[i], self.Cards[j] = self.Cards[j], self.Cards[i] }) - self.DealIndex = 0 -} - -func (self *Deck) ShuffleDeterministically(seed int64) { - r := rand.New(rand.NewSource(seed)) - //FIXME(sneak) not sure if this is constant time or not - r.Shuffle(len(self.Cards), func(i, j int) { self.Cards[i], self.Cards[j] = self.Cards[j], self.Cards[i] }) - self.DealIndex = 0 -} - -func (self *Deck) Deal(n int) (output Cards) { - - if (self.DealIndex + n) > len(self.Cards) { - return output - } - - for i := 0; i < n; i++ { - output = append(output, self.Cards[self.DealIndex+1]) - self.DealIndex++ - } - return output -} - -func (self *Deck) Dealt() int { - return self.DealIndex -} - -func (self *Deck) Remaining() int { - return (len(self.Cards) - self.DealIndex) -} - -func (s Cards) String() (output string) { - var cardstrings []string - for i := 0; i < len(s); i++ { - cardstrings = append(cardstrings, s[i].String()) - } - output = strings.Join(cardstrings, ",") - return output -} - -func generate() { - log.SetLevel(log.DebugLevel) -} - -func proto() { - myDeck := NewDeck() - myDeck.ShuffleDeterministically(42) - myHand := myDeck.Deal(2) - //spew.Dump(myHand) - fmt.Printf("my hand: %s\n", myHand) - cmty := myDeck.Deal(5) - fmt.Printf("community: %s\n", cmty) -}