package game import ( "crypto/rand" "fmt" "math/big" "strings" ) // Suit خال کارت. type Suit uint8 const ( Spades Suit = iota Hearts Diamonds Clubs ) var suitChar = [4]byte{'S', 'H', 'D', 'C'} var suitName = [4]string{"spades", "hearts", "diamonds", "clubs"} func (s Suit) String() string { return suitName[s] } // ParseSuit نام انگلیسی خال را به Suit تبدیل می‌کند. func ParseSuit(name string) (Suit, error) { switch strings.ToLower(name) { case "spades", "s": return Spades, nil case "hearts", "h": return Hearts, nil case "diamonds", "d": return Diamonds, nil case "clubs", "c": return Clubs, nil } return 0, fmt.Errorf("invalid suit: %q", name) } // Rank ارزش کارت؛ 2..10 معمولی، 11=J 12=Q 13=K 14=A. type Rank uint8 const ( Jack Rank = 11 Queen Rank = 12 King Rank = 13 Ace Rank = 14 ) // Card یک کارت بازی. type Card struct { Suit Suit Rank Rank } // String کد کوتاه کارت مثل "AS", "10H", "2C". func (c Card) String() string { var r string switch c.Rank { case Ace: r = "A" case King: r = "K" case Queen: r = "Q" case Jack: r = "J" default: r = fmt.Sprintf("%d", c.Rank) } return r + string(suitChar[c.Suit]) } // ParseCard کد کوتاه کارت را پارس می‌کند (مثلاً "10H", "AS"). func ParseCard(code string) (Card, error) { code = strings.ToUpper(strings.TrimSpace(code)) if len(code) < 2 { return Card{}, fmt.Errorf("invalid card: %q", code) } rankStr := code[:len(code)-1] suitStr := code[len(code)-1:] s, err := ParseSuit(suitStr) if err != nil { return Card{}, fmt.Errorf("invalid card %q: %w", code, err) } var r Rank switch rankStr { case "A": r = Ace case "K": r = King case "Q": r = Queen case "J": r = Jack default: var n int if _, err := fmt.Sscanf(rankStr, "%d", &n); err != nil || n < 2 || n > 10 { return Card{}, fmt.Errorf("invalid rank in card %q", code) } r = Rank(n) } return Card{Suit: s, Rank: r}, nil } // NewDeck یک دسته ۵۲ کارتی مرتب می‌سازد. func NewDeck() []Card { deck := make([]Card, 0, 52) for s := Suit(0); s < 4; s++ { for r := Rank(2); r <= Ace; r++ { deck = append(deck, Card{Suit: s, Rank: r}) } } return deck } // Shuffle دسته را با crypto/rand به‌صورت Fisher-Yates بُر می‌زند. func Shuffle(deck []Card) { for i := len(deck) - 1; i > 0; i-- { jBig, err := rand.Int(rand.Reader, big.NewInt(int64(i+1))) if err != nil { continue // عملاً رخ نمی‌دهد } j := int(jBig.Int64()) deck[i], deck[j] = deck[j], deck[i] } }