每个玩家有2张牌,公共牌有5张牌,共计7张牌。比牌时,每个玩家要找到自己组成最大牌型的5张,跟其他玩家的最大牌型比大小。
如果我们能给每5张牌算一个分数,分数越大,牌越大,问题就迎刃而解了。
德州扑克中,牌一共有52张,没有大小王。我们用0-51表示52张不同的扑克牌。其中0-51这52个数字表示牌的ID。
以下代码用python实现。
花色有4种,刚好可用最后2位表示4种花色。
def get_card_suit_id(card_id):
return card_id & 3
ID最后2位是花色,那么右移2位,剩下的信息就是牌的数字了。
def get_card_num_id(card_id):
return card_id >> 2
核心问题,每个玩家要在7张牌中找到5张,用排列组合算法,遍历一遍所有组合,取最大的分数即可。
输入:7张牌的ID。 输出:该玩家最大牌型的分数。
此外,因为德州扑克的计算规则,是先看牌型,再看数字。所以,我们可以用二维表示分数:(牌型, 该牌型的分数)
。
比大小时,先比牌型,若牌型一样大,再比后面的分数。
由于皇家同花顺是同花顺的一种,所以牌型有9种,从小到大用0-8表示。
每个牌型比大小的方式不一样,牌型分的计算方式有差别。
组合算法不用自己实现,各个编程语言都有库。
这就是根据7张牌,计算max_type
和max_value
的逻辑。其中get_type()
和get_value()
是我们后面需要实现的。
from itertools import combinations
def get_max_score(seven_cards):
max_type = -1
res = []
for cards in combinations(seven_cards, 5):
t, v = get_type(cards)
if t > max_type:
max_type = t
res = [(t, v, cards)]
elif t == max_type:
res.append((t, v, cards))
max_value = get_value(*res[0])
for r in res[1:]:
value = get_value(*r)
if value > max_value:
max_value = value
return max_type, max_value
这里介绍一个小小的优化点:我们遍历时,并不会计算所有的5张牌组合的max_type和max_value,因为可以先把max_type算出来,得到最大的type后,只需要计算最大type的max_value,省了一些没有必要的计算。
当然由于遇到顺子时,可以很快得到max_value,所以会在get_type时就算出来。
def get_type(five_cards):
straight, straight_value = is_straight(five_cards)
flush = is_flush(five_cards)
if flush and straight:
return 8, straight_value
if flush:
return 5, None # sorted([get_card_num_id(c) for c in five_cards], reverse=True)
if straight:
return 4, straight_value
nums = [0] * 13
for card in five_cards:
nums[get_card_num_id(card)] += 1
max_freq = max(nums)
if max_freq == 1:
return 0, None # sorted([get_card_num_id(c) for c in five_cards], reverse=True)
if max_freq == 4:
return 7, None # [nums.index(4), nums.index(1)]
if max_freq == 3:
if 2 in nums:
return 6, None # [nums.index(3), nums.index(2)]
return 3, None
# max_freq == 2
if nums.count(2) == 1:
return 1, None
return 2, None
其中用到了这2个函数:
def is_flush(five_cards):
s = get_card_suit_id(five_cards[0])
for c in five_cards[1:]:
if s != get_card_suit_id(c):
return False
return True
def is_straight(five_cards):
nums = sorted([get_card_num_id(c) for c in five_cards])
if nums == [0, 1, 2, 3, 12]:
return True, 3
n4 = nums[4]
for i, n in enumerate(nums[:4]):
if n4 - n != 4 - i:
return False, 0
return True, n4
def get_value(t, v, five_cards):
if v is not None:
return v
if t in (0, 5):
return sorted((get_card_num_id(c) for c in five_cards), reverse=True)
nums = [0] * 13
for card in five_cards:
nums[get_card_num_id(card)] += 1
return sorted(list(set(get_card_num_id(c) for c in five_cards)), reverse=True, key=lambda x: (nums[x] << 5) + x)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有