package main import ( "crypto/rand" "math/big" ) // Deck — стопка карт. Индекс 0 — верх колоды (карта, которая уходит первой). type Deck struct { cards []Card } // NewDeck создаёт полную неперетасованную колоду из 52 карт. func NewDeck() *Deck { d := &Deck{cards: make([]Card, 0, 52)} for s := Clubs; s <= Spades; s++ { for r := Ace; r <= King; r++ { d.cards = append(d.cards, Card{Suit: s, Rank: r}) } } return d } // Shuffle перемешивает колоду криптографически стойким рандомом // (алгоритм Фишера-Йейтса). func (d *Deck) Shuffle() { for i := len(d.cards) - 1; i > 0; i-- { jBig, err := rand.Int(rand.Reader, big.NewInt(int64(i+1))) if err != nil { // crypto/rand не должен падать в обычных условиях; // если это случилось — не имеет смысла продолжать игру. panic(err) } j := int(jBig.Int64()) d.cards[i], d.cards[j] = d.cards[j], d.cards[i] } } // Len возвращает количество карт, оставшихся в колоде. func (d *Deck) Len() int { return len(d.cards) } // Draw снимает верхнюю карту колоды. Второе значение — false, // если колода пуста. func (d *Deck) Draw() (Card, bool) { if len(d.cards) == 0 { return Card{}, false } c := d.cards[0] d.cards = d.cards[1:] return c, true } // DrawN снимает n верхних карт (используется при раздаче). // Если в колоде меньше карт, чем запрошено, возвращает столько, // сколько есть. func (d *Deck) DrawN(n int) []Card { if n > len(d.cards) { n = len(d.cards) } out := d.cards[:n] d.cards = d.cards[n:] return out }