我将为您介绍几种实现扑克牌随机生成的算法,并提供完整的Python代码示例。
这是最经典且高效的洗牌算法,保证每张牌出现在每个位置的概率相等。
python
import random
def create_deck:
创建一副标准的52张扑克牌
suits = ['♠', '♥', '♦', '♣']
ranks ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
return [f"{rank}{suit}" for suit in suits for rank in ranks]
def fisher_yates_shuffle(deck):
Fisher-Yates洗牌算法
n = len(deck)
for i in range(n-1, 0, -1):
j = random.randint(0, i)
deck[i], deck[j] = deck[j], deck[i]
return deck
# 使用示例
deck = create_deck
print("原始牌组:", deck[:10], "...") # 显示前10张牌
shuffled_deck = fisher_yates_shuffle(deck.copy)
print("洗牌后:", shuffled_deck[:10], "...")
Python内置的`random.shuffle`函数实现了类似的洗牌算法,使用起来更简单。
python
import random
def shuffle_with_builtin(deck):
使用Python内置函数洗牌
shuffled = deck.copy
random.shuffle(shuffled)
return shuffled
# 使用示例
deck = create_deck
print("原始("原始牌组:", deck[:10], "...")
shuffled_deck = shuffle_with_builtin(deck)
print("洗牌后:", shuffled_deck[:10], "...")
这种方法模拟现实中的洗牌动作,包括切牌和插牌。
python
import random
def realistic_shuffle(deck, iterations=5):
模拟真实洗牌过程
iterations: 洗牌次数
shuffled = deck.copy
for _ in range in range(iterations):
aapoker.games官网入口# 切牌
cut_point = random.randint(20, 32) # 大约在大约在中间位置切牌
top_half = shuffled[:cut_point]
bottom_half = shuffled[cut_point:]
# 插牌
new_deck = []
while top_half and bottom_half:
# 随机选择从哪叠牌取牌
if random.random
if len(top_half) > len(bottom_half):
cards_to_take = min(random.randint(1, 3), len(top_half))
new_deck.extend(top_half[:cards_to_take])
top_half = top_half[cards_to_take:]
else:
cards_to_take = min(random.randint(1, 3), len(bottom_half))
new_deck.extend(bottom_half[:cards_to_take])
bottom_half = bottom_half[cards_to_take:]
else:
# 小概率从较少的牌叠取牌
if len(top_half)
cards_to_take = min(random.randint(1, 2), len(top_half))
new_deck.extend(top_half[:cards_to_take])
top_half = top_half[cards_to_take:]
elif bottom_half:
cards_to_take = min(random.randint(1, 2), len(bottom_half))
new new_deck.extend(bottom_half[:cards_to_take])
bottom_half = bottom_half[cards_to_take:]
# 添加剩余牌
new_deck.extend(top_half)
new_deck.extend(bottom_half)
shuffled = new_deck
return shuffled
# 使用示例
deck = create_deck
realistic_shuffled = realistic_shuffle(deck)
print("模拟洗牌结果:", realistic_shuffled[:10], "...")
python
import random
class PokerDeck:
def __init__(self):
self.suits = ['♠', '♥', '♦', '♣']
self.ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
self.deck = self.create_deck
def create_deck(self):
创建一副新牌
return [f"{rank}{suit}" for suit in self.suits for rank in self.ranks]
def shuffle(self, method='fisher_yates'):
洗牌
if method == 'fisher_yisher_yates':
self.fisher_yates_shuffle
elif method == 'builtin':
random.shuffle(self.deck)
elif method == 'realistic':
self.deck = realistic_shuffle(self.deck)
def fisher_yates_shuffle(self):
Fisher-Yates洗牌算法
n = len(self.deck)
for i in range(n-1, 0, -1):
j = random.randint(0, i)
self.deck[i], self.deck[j] = self = self.deck[j], self.deck[i]
def deal(self, num_players=4, cards_per_player=5):
发牌给指定数量的玩家
if num_players * cards_per_player > len(self.deck):
raise ValueError("牌不够发!")
hands = [[] for _ in range(num_players)]
for card_index in range(cards_per_player):
for player in range(num_players):
hands[player].append(self.deck.pop(0))
return hands
def reset(self):
重置牌组
self.deck = self.create_deck
def realistic_shuffle(deck, iterations=5):
模拟真实洗牌过程的辅助函数
shuffled = deck.copy
for _ in range(iterations):
cut_point = random.randint(20, 32)
top_half = shuffled[:cut_point]
bottom_half = shuffled[cut_point:]
new_deck = []
while top_half and bottom_half:
if random.random
if len(top_half) > len(bottom_half):
cards_to_take = min(random.randint(1, 3), len(top_half))
new new_deck.extend(top_half[:cards_to_take])
top_half = top_half[cards_to_take:]
else:
cards_to_take = min(random.randint(1, 3), len(bottom_half))
new new_deck.extend(bottom_half[:cards_to_take])
bottom_half = bottom_half[cards_to_take:]
else:
if len(top_half)
cards_to_take = min(random.randint(1, 2), len(top len(top_half))
new_deck.extend(top_half[:cards_to_take])
])
top_half = top_half[cards_to_take:]
elif bottom_half:
cards_to_take = min(random.randint(1, 2), len(bottom_half))
new_deck.extend(bottom_half[:cards_to_take])
bottom_half = bottom_half[cards_to_take:]
new_deck.extend(top_half)
new_deck.extend(bottom_half)
shuffled = new_deck
return shuffled
# 演示使用
if __name__ == "__main__":
# 创建一副牌
poker = PokerDeck
print("初始牌组:", poker.deck[:13]) # 显示前13张牌
# 使用不同方法洗牌
print("\
=== Fisher-Yates洗牌 ===")
poker.reset
poker.shuffle('fisher_yates')
print("洗牌后:", poker.deck[:13])
print("\
=== 内置函数洗牌 ===")
poker.reset
poker.shuffle('builtin')
print("洗牌后:", poker.deck[:13])
print("\
=== 模拟真实洗牌 ===")
poker.reset
poker.shuffle('realistic')
print("洗牌后:", poker.deck[:13])
# 发牌演示
print("\
=== 发牌演示 (4位玩家,每人5张牌) ===")
poker.reset
poker.shuffle('fisher_yates')
hands = poker.deal(num_players_players=4, cards_per_player=5)
for i, hand in enumerate(hands):
print(f"玩家{i+1}的手牌: {hand}")
print(f"\
剩余牌数: {len(poker.deck)}")
| 算法 | 优点 | 缺点 | 适用场景 |
||||-|
| Fisher-Yates | 完全随机,时间复杂度O(n) | 需要手动实现 | 大多数需要高质量随机性的场景 |
| random.shuffle | 简单易用,Python内置 | 无法自定义洗牌过程 | 快速原型开发,简单应用 |
| 模拟真实洗牌 | 更贴近现实体验 | 随机性稍差,复杂度高 | 游戏需要模拟真实洗牌过程 |
推荐使用Fisher-Yates算法或Python内置的`random.shuffle`函数来实现扑克牌的随机生成,它们都能提供高质量的随机性且效率很高。如果您想模拟真实的洗牌体验,可以考虑第三种方法,但要注意其随机性可能不如前两种方法理想。