This commit is contained in:
2026-06-15 16:53:25 +03:30
commit 390ef96e7e
34 changed files with 4463 additions and 0 deletions
+129
View File
@@ -0,0 +1,129 @@
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]
}
}