订购“7 出 5”纸牌扑克(非顺子/非同花)手牌的高效算法 |分而治之
Efficient Algorithms Ordering "5 Out of 7" Card Poker (non-straight / non-flush) Hands | Divide & Conquer
考虑长度为 7 的排序列表,其中每个条目 x 是一个数字 2 <= x <= 14 并且任何条目的重复计数不能超过 4。这里的假设是高性能算法已经确定我们有一手非顺子/非同花的牌。
在线扑克网站会对高性能算法感兴趣,以便在这种情况下处理获得 5 张最佳牌的下一步。
在 Python 中编写不导入模块的程序是制作此类算法原型的好方法。
很可能 'monster size' 在线扑克网站不需要我们的任何帮助,但看到为速度而设计的算法会很有趣。在问题中
7 Card Poker Hand Evaluator
从 2010 年开始对此进行了检查,但许多链接已损坏。很高兴知道当今使用的最快的已知算法的状态。
Question: Is the algorithm discussed below known? Has some algorithm been determined to be a standout for performance?
我的作品
我注意到长度为 7 的列表有一个中点,并且有 'combinatorial symmetry' 和算法可以合并的结构。我们在下面的代码中实现了这个逻辑。人们可以想到一个用汇编程序编写的闪电般快速的程序,它计算 GOTO
数字与解决方案的偏移量。
注意:我还有一个单程排序例程,它取任意 7 张牌并确定是顺子还是同花。但我被建议让我的问题更有针对性,所以这里不讨论。
Python 程序:
hand=[2,2,7,7,8,11,12]
hand=[2,3,4,7,7,7,11]
start_spot = 3
end_spot = 3
if hand[3] == hand[4]:
if hand[4] == hand[5]:
if hand[5] == hand[6]:
end_spot = 6
else:
end_spot = 5
else:
end_spot = 4
if hand[3] == hand[2]:
if hand[2] == hand[1]:
if hand[1] == hand[0]:
start_spot = 0
else:
start_spot = 1
else:
start_spot = 2
if end_spot - start_spot == 3:
if end_spot == 6:
Kick = hand[start_spot-1]
else:
Kick = hand[6]
best5 = [Kick,hand[start_spot],hand[start_spot+1],hand[start_spot+2],hand[start_spot+3]]
print(hand, best5, 'four of a kind')
raise SystemExit
else:
pass
def multCount(c1,c2,c3):
pc = 0
if c1 == c2: pc = pc + 1
if c2 == c3: pc = pc + 10
return pc
pc_r = multCount(hand[4],hand[5],hand[6])
pc_l = multCount(hand[2],hand[1],hand[0])
if start_spot == 3 and end_spot == 3:
if pc_l == 0 and pc_r == 0:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'no pair')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
best5 = [hand[2],hand[3],hand[6],hand[4],hand[5]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 1 and pc_r == 0:
best5 = [hand[4],hand[5],hand[6],hand[1],hand[2]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 1 and pc_r == 1:
best5 = [hand[6],hand[1],hand[2],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 10:
best5 = [hand[4],hand[1],hand[2],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 11:
best5 = [hand[1],hand[2],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[4],hand[5],hand[6],hand[0],hand[1]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
best5 = [hand[6],hand[0],hand[1],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[4],hand[0],hand[1],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
best5 = [hand[0],hand[1],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 0:
best5 = [hand[5],hand[6],hand[0],hand[1],hand[2]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 11 and pc_r == 1:
best5 = [hand[4],hand[5],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 10:
best5 = [hand[5],hand[6],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 11:
best5 = [hand[1],hand[2],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
else:
pass
if start_spot == 3 and end_spot == 4:
if pc_l == 0 and pc_r == 0:
best5 = [hand[2],hand[5],hand[6],hand[3],hand[4]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
print("ERROR 1")
pass # can't happen
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
print("ERROR 2")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 0:
best5 = [hand[6],hand[1],hand[2],hand[3],hand[4]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 1:
print("ERROR 3")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 10:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 11:
print("ERROR 4")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[6],hand[0],hand[1],hand[3],hand[4]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
print("ERROR 5")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[4],hand[0],hand[1],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
print("ERROR 6")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 0:
best5 = [hand[3],hand[4],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 1:
print("ERROR 7")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 10:
best5 = [hand[5],hand[6],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 11:
print("ERROR 8")
pass # can't happen
raise SystemExit
else:
pass
if start_spot == 2 and end_spot == 3:
if pc_l == 0 and pc_r == 0:
best5 = [hand[4],hand[5],hand[6],hand[2],hand[3]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
best5 = [hand[6],hand[2],hand[3],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[4],hand[2],hand[3],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
print("ERROR 9")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 0:
print("ERROR 10")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 1:
print("ERROR 11")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 10:
print("ERROR 12")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 11:
print("ERROR 13")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[6],hand[0],hand[1],hand[2],hand[3]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
best5 = [hand[6],hand[2],hand[3],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[4],hand[2],hand[3],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
print("ERROR 14")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 0:
print("ERROR 15")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 1:
print("ERROR 16")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 10:
print("ERROR 17")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 11:
print("ERROR 18")
pass # can't happen
raise SystemExit
else:
pass
if start_spot == 2 and end_spot == 4:
if pc_l == 0 and pc_r == 0:
best5 = [hand[5],hand[6],hand[2],hand[3],hand[4]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
print("ERROR 19")
pass # can't happen
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[5],hand[6],hand[2],hand[3],hand[4]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
print("ERROR 20")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 0:
print("ERROR 21")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 1:
print("ERROR 22")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 10:
print("ERROR 23")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 11:
print("ERROR 24")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[0],hand[1],hand[2],hand[3],hand[4]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
print("ERROR 25")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[5],hand[6],hand[2],hand[3],hand[4]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
print("ERROR 26")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 0:
print("ERROR 27")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 1:
print("ERROR 28")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 10:
print("ERROR 29")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 11:
print("ERROR 30")
pass # can't happen
raise SystemExit
else:
pass
if start_spot == 1 and end_spot == 3:
if pc_r == 0:
best5 = [hand[5],hand[6],hand[1],hand[2],hand[3]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_r == 1:
best5 = [hand[4],hand[5],hand[1],hand[2],hand[3]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_r == 10:
best5 = [hand[5],hand[6],hand[1],hand[2],hand[3]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_r == 11:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
else:
pass
if start_spot == 3 and end_spot == 5:
if pc_l == 0:
best5 = [hand[2],hand[6],hand[3],hand[4],hand[5]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 1:
best5 = [hand[1],hand[2],hand[3],hand[4],hand[5]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10:
best5 = [hand[0],hand[1],hand[3],hand[4],hand[5]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11:
best5 = [hand[1],hand[2],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
else:
pass
print("ERROR 99")
pass # can't happen
raise SystemExit
以下是您在设计寻找最佳手牌的算法时可能会考虑的一些想法:
- 比较都涉及比较牌值(数量)and/or花色。因此,您可能需要考虑制作一张卡号列表和一张花色列表。或者看看
itertools
模块有什么技巧
- 同花顺和同花顺是花色重要的唯一牌。否则,您只是在查看卡号。
- 同花顺和同花顺是唯一需要寻找 5 个连续数字的手牌。请记住,这可能包括 A 和花牌。此外,如果包含 A,则它必须在开头或结尾(例如,"Q K A 2 3" 不算顺子)。您可能还想查看模块 more_itertools.consecutive_groups.
- 其他手牌(一对、两对、三种、葫芦、四种)都是基于相同数字出现的频率。如果一个值出现 4 次,则无需检查此列表中的其他手牌。如果一个出现 3 次,则检查您是否可以制作满屋,否则就是三张。您可以像这样从最高手到最低手继续检查此列表,在匹配时停止。
- 您甚至可以考虑创建一个名为
Card
的 class,并将您的卡片作为 "Card" 类型的对象输入。然后你可以在 class 到 return 卡的花色或数值中有功能。
我相信我已经实现了您指定的算法,但它很容易出错,所以如果有任何问题请告诉我。我几乎只是手头的四个核心评估
- 是顺子吗?
- 是同花吗?
- 它包含多少个 k 对?
- 最大的 k 对大小是多少?
根据这些,我确定了 5 张牌的特定组合可以在一系列 if 语句中组成的最佳手牌,并相应地对牌进行排序。然后,我从一组 7 张牌中创建一个包含所有 5 张牌组合的列表,使用此逻辑确定最大/最佳手牌(我重新排列分数和手牌顺序以完成此操作),然后 return 那手牌。
from collections import Counter
from itertools import combinations
def num_of_kind(cards):
return Counter(c[0] for c in cards)
def count_pairs(cards):
return sum(i > 1 for i in num_of_kind(cards).values())
def largest_pair(cards):
return max(num_of_kind(cards).values())
def is_straight(cards):
values = [c[0] for c in cards]
index = "A23456789TJQKA"["K" in values:].index
indices = sorted(index(v) for v in values)
return all(x == y for x, y in enumerate(indices, indices[0]))
def is_flush(cards):
suit_pop = Counter(c[1] for c in cards)
return any(s > 4 for s in suit_pop.values())
def straight_sort(cards):
values = [c[0] for c in cards]
index = "A23456789TJQKA"["K" in values:].index
return sorted(cards, key=lambda x:index(x[0]), reverse=True)
def flush_sort(cards):
suit_pop = Counter(c[1] for c in cards)
return sorted(cards, key=lambda x: suit_pop[x[1]], reverse=True)
def pair_sort(cards):
num = num_of_kind(cards)
return sorted(cards, key=lambda x: num[x[0]], reverse=True)
def card_vals(cards):
return [c[0] for c in cards]
def score_hand(cards):
pairs = count_pairs(cards)
largest = largest_pair(cards)
straight = is_straight(cards)
flush = is_flush(cards)
cards = straight_sort(cards)
hand_score = 0
if flush and straight:
hand_score, cards = 8, flush_sort(cards)
elif largest == 4:
hand_score, cards = 7, pair_sort(cards)
elif pairs == 2 and largest == 3:
hand_score, cards = 6, pair_sort(cards)
elif flush:
hand_score, cards = 5, flush_sort(cards)
elif straight:
hand_score = 4
elif largest == 3:
hand_score, cards = 3, pair_sort(cards)
else:
hand_score, cards = pairs, pair_sort(cards)
return hand_score, card_vals(cards), cards
def best_hand(cards):
cards = max(list(combinations(cards, 5)), key=score_hand)
score, _, hand = score_hand(cards)
return hand[::-1], score
def main():
hand = ['2c','Ah','3d', '5s','4h','5d', '3h']
print(*best_hand(hand))
if __name__ == "__main__":
main()
我可以用每种方法的细节让您厌烦,但我觉得这一切都是不言自明的。唯一棘手的一点是 is_straight()
,这只是一些索引技巧,以确定卡片值是否可以按顺序排序。
考虑长度为 7 的排序列表,其中每个条目 x 是一个数字 2 <= x <= 14 并且任何条目的重复计数不能超过 4。这里的假设是高性能算法已经确定我们有一手非顺子/非同花的牌。
在线扑克网站会对高性能算法感兴趣,以便在这种情况下处理获得 5 张最佳牌的下一步。
在 Python 中编写不导入模块的程序是制作此类算法原型的好方法。
很可能 'monster size' 在线扑克网站不需要我们的任何帮助,但看到为速度而设计的算法会很有趣。在问题中
7 Card Poker Hand Evaluator
从 2010 年开始对此进行了检查,但许多链接已损坏。很高兴知道当今使用的最快的已知算法的状态。
Question: Is the algorithm discussed below known? Has some algorithm been determined to be a standout for performance?
我的作品
我注意到长度为 7 的列表有一个中点,并且有 'combinatorial symmetry' 和算法可以合并的结构。我们在下面的代码中实现了这个逻辑。人们可以想到一个用汇编程序编写的闪电般快速的程序,它计算 GOTO
数字与解决方案的偏移量。
注意:我还有一个单程排序例程,它取任意 7 张牌并确定是顺子还是同花。但我被建议让我的问题更有针对性,所以这里不讨论。
Python 程序:
hand=[2,2,7,7,8,11,12]
hand=[2,3,4,7,7,7,11]
start_spot = 3
end_spot = 3
if hand[3] == hand[4]:
if hand[4] == hand[5]:
if hand[5] == hand[6]:
end_spot = 6
else:
end_spot = 5
else:
end_spot = 4
if hand[3] == hand[2]:
if hand[2] == hand[1]:
if hand[1] == hand[0]:
start_spot = 0
else:
start_spot = 1
else:
start_spot = 2
if end_spot - start_spot == 3:
if end_spot == 6:
Kick = hand[start_spot-1]
else:
Kick = hand[6]
best5 = [Kick,hand[start_spot],hand[start_spot+1],hand[start_spot+2],hand[start_spot+3]]
print(hand, best5, 'four of a kind')
raise SystemExit
else:
pass
def multCount(c1,c2,c3):
pc = 0
if c1 == c2: pc = pc + 1
if c2 == c3: pc = pc + 10
return pc
pc_r = multCount(hand[4],hand[5],hand[6])
pc_l = multCount(hand[2],hand[1],hand[0])
if start_spot == 3 and end_spot == 3:
if pc_l == 0 and pc_r == 0:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'no pair')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
best5 = [hand[2],hand[3],hand[6],hand[4],hand[5]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 1 and pc_r == 0:
best5 = [hand[4],hand[5],hand[6],hand[1],hand[2]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 1 and pc_r == 1:
best5 = [hand[6],hand[1],hand[2],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 10:
best5 = [hand[4],hand[1],hand[2],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 11:
best5 = [hand[1],hand[2],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[4],hand[5],hand[6],hand[0],hand[1]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
best5 = [hand[6],hand[0],hand[1],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[4],hand[0],hand[1],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
best5 = [hand[0],hand[1],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 0:
best5 = [hand[5],hand[6],hand[0],hand[1],hand[2]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 11 and pc_r == 1:
best5 = [hand[4],hand[5],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 10:
best5 = [hand[5],hand[6],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 11:
best5 = [hand[1],hand[2],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
else:
pass
if start_spot == 3 and end_spot == 4:
if pc_l == 0 and pc_r == 0:
best5 = [hand[2],hand[5],hand[6],hand[3],hand[4]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
print("ERROR 1")
pass # can't happen
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
print("ERROR 2")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 0:
best5 = [hand[6],hand[1],hand[2],hand[3],hand[4]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 1:
print("ERROR 3")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 10:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 1 and pc_r == 11:
print("ERROR 4")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[6],hand[0],hand[1],hand[3],hand[4]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
print("ERROR 5")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[4],hand[0],hand[1],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
print("ERROR 6")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 0:
best5 = [hand[3],hand[4],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 1:
print("ERROR 7")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 10:
best5 = [hand[5],hand[6],hand[0],hand[1],hand[2]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11 and pc_r == 11:
print("ERROR 8")
pass # can't happen
raise SystemExit
else:
pass
if start_spot == 2 and end_spot == 3:
if pc_l == 0 and pc_r == 0:
best5 = [hand[4],hand[5],hand[6],hand[2],hand[3]]
print(hand, best5, 'one pair')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
best5 = [hand[6],hand[2],hand[3],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[4],hand[2],hand[3],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
print("ERROR 9")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 0:
print("ERROR 10")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 1:
print("ERROR 11")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 10:
print("ERROR 12")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 11:
print("ERROR 13")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[6],hand[0],hand[1],hand[2],hand[3]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
best5 = [hand[6],hand[2],hand[3],hand[4],hand[5]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[4],hand[2],hand[3],hand[5],hand[6]]
print(hand, best5, 'two pair')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
print("ERROR 14")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 0:
print("ERROR 15")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 1:
print("ERROR 16")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 10:
print("ERROR 17")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 11:
print("ERROR 18")
pass # can't happen
raise SystemExit
else:
pass
if start_spot == 2 and end_spot == 4:
if pc_l == 0 and pc_r == 0:
best5 = [hand[5],hand[6],hand[2],hand[3],hand[4]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 0 and pc_r == 1:
print("ERROR 19")
pass # can't happen
raise SystemExit
elif pc_l == 0 and pc_r == 10:
best5 = [hand[5],hand[6],hand[2],hand[3],hand[4]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 0 and pc_r == 11:
print("ERROR 20")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 0:
print("ERROR 21")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 1:
print("ERROR 22")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 10:
print("ERROR 23")
pass # can't happen
raise SystemExit
elif pc_l == 1 and pc_r == 11:
print("ERROR 24")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 0:
best5 = [hand[0],hand[1],hand[2],hand[3],hand[4]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10 and pc_r == 1:
print("ERROR 25")
pass # can't happen
raise SystemExit
elif pc_l == 10 and pc_r == 10:
best5 = [hand[5],hand[6],hand[2],hand[3],hand[4]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10 and pc_r == 11:
print("ERROR 26")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 0:
print("ERROR 27")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 1:
print("ERROR 28")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 10:
print("ERROR 29")
pass # can't happen
raise SystemExit
elif pc_l == 11 and pc_r == 11:
print("ERROR 30")
pass # can't happen
raise SystemExit
else:
pass
if start_spot == 1 and end_spot == 3:
if pc_r == 0:
best5 = [hand[5],hand[6],hand[1],hand[2],hand[3]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_r == 1:
best5 = [hand[4],hand[5],hand[1],hand[2],hand[3]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_r == 10:
best5 = [hand[5],hand[6],hand[1],hand[2],hand[3]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_r == 11:
best5 = [hand[2],hand[3],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
else:
pass
if start_spot == 3 and end_spot == 5:
if pc_l == 0:
best5 = [hand[2],hand[6],hand[3],hand[4],hand[5]]
print(hand, best5, 'trips')
raise SystemExit
elif pc_l == 1:
best5 = [hand[1],hand[2],hand[3],hand[4],hand[5]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 10:
best5 = [hand[0],hand[1],hand[3],hand[4],hand[5]]
print(hand, best5, 'full house')
raise SystemExit
elif pc_l == 11:
best5 = [hand[1],hand[2],hand[4],hand[5],hand[6]]
print(hand, best5, 'full house')
raise SystemExit
else:
pass
print("ERROR 99")
pass # can't happen
raise SystemExit
以下是您在设计寻找最佳手牌的算法时可能会考虑的一些想法:
- 比较都涉及比较牌值(数量)and/or花色。因此,您可能需要考虑制作一张卡号列表和一张花色列表。或者看看
itertools
模块有什么技巧 - 同花顺和同花顺是花色重要的唯一牌。否则,您只是在查看卡号。
- 同花顺和同花顺是唯一需要寻找 5 个连续数字的手牌。请记住,这可能包括 A 和花牌。此外,如果包含 A,则它必须在开头或结尾(例如,"Q K A 2 3" 不算顺子)。您可能还想查看模块 more_itertools.consecutive_groups.
- 其他手牌(一对、两对、三种、葫芦、四种)都是基于相同数字出现的频率。如果一个值出现 4 次,则无需检查此列表中的其他手牌。如果一个出现 3 次,则检查您是否可以制作满屋,否则就是三张。您可以像这样从最高手到最低手继续检查此列表,在匹配时停止。
- 您甚至可以考虑创建一个名为
Card
的 class,并将您的卡片作为 "Card" 类型的对象输入。然后你可以在 class 到 return 卡的花色或数值中有功能。
我相信我已经实现了您指定的算法,但它很容易出错,所以如果有任何问题请告诉我。我几乎只是手头的四个核心评估
- 是顺子吗?
- 是同花吗?
- 它包含多少个 k 对?
- 最大的 k 对大小是多少?
根据这些,我确定了 5 张牌的特定组合可以在一系列 if 语句中组成的最佳手牌,并相应地对牌进行排序。然后,我从一组 7 张牌中创建一个包含所有 5 张牌组合的列表,使用此逻辑确定最大/最佳手牌(我重新排列分数和手牌顺序以完成此操作),然后 return 那手牌。
from collections import Counter
from itertools import combinations
def num_of_kind(cards):
return Counter(c[0] for c in cards)
def count_pairs(cards):
return sum(i > 1 for i in num_of_kind(cards).values())
def largest_pair(cards):
return max(num_of_kind(cards).values())
def is_straight(cards):
values = [c[0] for c in cards]
index = "A23456789TJQKA"["K" in values:].index
indices = sorted(index(v) for v in values)
return all(x == y for x, y in enumerate(indices, indices[0]))
def is_flush(cards):
suit_pop = Counter(c[1] for c in cards)
return any(s > 4 for s in suit_pop.values())
def straight_sort(cards):
values = [c[0] for c in cards]
index = "A23456789TJQKA"["K" in values:].index
return sorted(cards, key=lambda x:index(x[0]), reverse=True)
def flush_sort(cards):
suit_pop = Counter(c[1] for c in cards)
return sorted(cards, key=lambda x: suit_pop[x[1]], reverse=True)
def pair_sort(cards):
num = num_of_kind(cards)
return sorted(cards, key=lambda x: num[x[0]], reverse=True)
def card_vals(cards):
return [c[0] for c in cards]
def score_hand(cards):
pairs = count_pairs(cards)
largest = largest_pair(cards)
straight = is_straight(cards)
flush = is_flush(cards)
cards = straight_sort(cards)
hand_score = 0
if flush and straight:
hand_score, cards = 8, flush_sort(cards)
elif largest == 4:
hand_score, cards = 7, pair_sort(cards)
elif pairs == 2 and largest == 3:
hand_score, cards = 6, pair_sort(cards)
elif flush:
hand_score, cards = 5, flush_sort(cards)
elif straight:
hand_score = 4
elif largest == 3:
hand_score, cards = 3, pair_sort(cards)
else:
hand_score, cards = pairs, pair_sort(cards)
return hand_score, card_vals(cards), cards
def best_hand(cards):
cards = max(list(combinations(cards, 5)), key=score_hand)
score, _, hand = score_hand(cards)
return hand[::-1], score
def main():
hand = ['2c','Ah','3d', '5s','4h','5d', '3h']
print(*best_hand(hand))
if __name__ == "__main__":
main()
我可以用每种方法的细节让您厌烦,但我觉得这一切都是不言自明的。唯一棘手的一点是 is_straight()
,这只是一些索引技巧,以确定卡片值是否可以按顺序排序。