Search Apps Documentation Source Content File Folder Download Copy Actions Download

deck.gno

1.72 Kb ยท 73 lines
 1package poker
 2
 3// Deck manages a 52-card deck with deterministic shuffling
 4type Deck struct {
 5	Cards []Card
 6	Index int // Current deal position
 7}
 8
 9// NewDeck creates a standard 52-card deck
10func NewDeck() *Deck {
11	cards := make([]Card, 52)
12	idx := 0
13	for suit := 0; suit < 4; suit++ {
14		for value := 2; value <= 14; value++ {
15			cards[idx] = Card{Suit: suit, Value: value}
16			idx++
17		}
18	}
19	return &Deck{Cards: cards, Index: 0}
20}
21
22// Shuffle shuffles the deck using a seed-based Fisher-Yates algorithm
23// This is deterministic given the same seed, which is important for
24// blockchain reproducibility. In production, the seed should come from
25// a commit-reveal scheme where all players contribute randomness.
26func (d *Deck) Shuffle(seed int64) {
27	n := len(d.Cards)
28	// Simple LCG (Linear Congruential Generator) for deterministic randomness
29	state := seed
30	for i := n - 1; i > 0; i-- {
31		// LCG: state = (a * state + c) mod m
32		state = (state*6364136223846793005 + 1442695040888963407) % (1 << 62)
33		j := int(abs64(state) % int64(i+1))
34		d.Cards[i], d.Cards[j] = d.Cards[j], d.Cards[i]
35	}
36	d.Index = 0
37}
38
39// Deal deals n cards from the deck
40func (d *Deck) Deal(n int) []Card {
41	if d.Index+n > len(d.Cards) {
42		panic("not enough cards in deck")
43	}
44	cards := make([]Card, n)
45	for i := 0; i < n; i++ {
46		cards[i] = d.Cards[d.Index]
47		d.Index++
48	}
49	return cards
50}
51
52// DealOne deals a single card from the deck
53func (d *Deck) DealOne() Card {
54	cards := d.Deal(1)
55	return cards[0]
56}
57
58// Remaining returns the number of cards remaining in the deck
59func (d *Deck) Remaining() int {
60	return len(d.Cards) - d.Index
61}
62
63// Reset resets the deck to the beginning
64func (d *Deck) Reset() {
65	d.Index = 0
66}
67
68func abs64(x int64) int64 {
69	if x < 0 {
70		return -x
71	}
72	return x
73}