90 lines
1.7 KiB
Go
90 lines
1.7 KiB
Go
package poker
|
|
|
|
import "encoding/binary"
|
|
import crand "crypto/rand"
|
|
import log "github.com/sirupsen/logrus"
|
|
import rand "math/rand"
|
|
|
|
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()
|
|
return d
|
|
}
|
|
|
|
func NewDeckFromSeed(seed int64) *Deck {
|
|
d := newDeck()
|
|
d.ShuffleSeedVal = seed
|
|
d.Shuffle()
|
|
return d
|
|
}
|
|
|
|
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)
|
|
}
|