好吧,我正在爲我的高級項目製作德州撲克AI。我已經創建了gui和投注/交易程序,但是我已經達到了需要確定誰贏了牌局的部分,但我不知道處理此問題的最佳方法。我正在使用python btw。 ATM我有2個列表,一個用於7個播放卡,另一個用於7個電腦卡。目前,所有卡都以結構形式存儲在列表中,其格式爲{'Number':XX,'Suit':x},其中數字爲2-14,套數爲1-4。我要這樣做的方式是爲每種手型制定一個功能,從最高處開始。例如。 self.CheckRoyal(playerCards),並手動瀏覽列表並評估是否實現了皇家沖洗。必須有更好的,數字化的方式來做到這一點。確定德州撲克手贏家的算法
回答
http://www.codingthewheel.com/archives/poker-hand-evaluator-roundup
你會得到最好的算法是7個在外觀尺寸100 MB查找表(如果我沒記錯)
Monte Carlo?這是我看到的第一個建議here。這是另一個高級項目。簡單而緩慢,但否則你可能會看到一些複雜的組合,我不會假裝知道很多。
ralu的帖子中使用的方法是迄今爲止我見過的最好的選擇。我在自己的項目中使用了這種方法,而且速度非常快。
懸崖:
做一些預處理,以產生一個表,包含用於每個不同的撲克手一個值。確保桌子是按手工排序的。
每個卡片值都有相應的素數值。該表格由手中每張牌值的乘積索引。因此,要找到手AAAAK的價值,你計算黃金乘法,並以此作爲索引表:
int prime = getPrime(hand); // Calculates A.getPrime()...*K.getPrime();
int value = table[prime];
(很抱歉的Java語法)。
這樣,AAAAK與KAAAA是同一隻手,並且您不需要5個暗表。
請注意,您需要通過所有最好的5張牌組合,以及可以選擇的7張牌來找到最大的值,這是手牌的真實價值。
您使用不同的表格進行沖洗。
表格變得很健壯,因爲這個實現有很多浪費的單元格。爲了解決這個問題,您可以在預處理過程中創建一個映射,它將較大的素數值映射爲整數值,並將其用作源代碼。
要求不高,至少有很好的評估者在這裏提供:code.google.com/p/specialkpokereval。在我的答案中也描述了這個頁面。請享用! – SK9 2011-03-24 06:28:11
看起來很有趣。感謝分享! – 2011-03-24 13:01:35
import itertools
from collections import Counter
# gets the most common element from a list
def Most_Common(lst):
data = Counter(lst)
return data.most_common(1)[0]
# gets card value from a hand. converts A to 14, is_seq function will convert the 14 to a 1 when necessary to evaluate A 2 3 4 5 straights
def convert_tonums(h, nums = {'T':10, 'J':11, 'Q':12, 'K':13, "A": 14}):
for x in xrange(len(h)):
if (h[x][0]) in nums.keys():
h[x] = str(nums[h[x][0]]) + h[x][1]
return h
# is royal flush
# if a hand is a straight and a flush and the lowest value is a 10 then it is a royal flush
def is_royal(h):
nh = convert_tonums(h)
if is_seq(h):
if is_flush(h):
nn = [int(x[:-1]) for x in nh]
if min(nn) == 10:
return True
else:
return False
# converts hand to number valeus and then evaluates if they are sequential AKA a straight
def is_seq(h):
ace = False
r = h[:]
h = [x[:-1] for x in convert_tonums(h)]
h = [int(x) for x in h]
h = list(sorted(h))
ref = True
for x in xrange(0,len(h)-1):
if not h[x]+1 == h[x+1]:
ref = False
break
if ref:
return True, r
aces = [i for i in h if str(i) == "14"]
if len(aces) == 1:
for x in xrange(len(h)):
if str(h[x]) == "14":
h[x] = 1
h = list(sorted(h))
for x in xrange(0,len(h)-1):
if not h[x]+1 == h[x+1]:
return False
return True, r
# call set() on the suite values of the hand and if it is 1 then they are all the same suit
def is_flush(h):
suits = [x[-1] for x in h]
if len(set(suits)) == 1:
return True, h
else:
return False
# if the most common element occurs 4 times then it is a four of a kind
def is_fourofakind(h):
h = [a[:-1] for a in h]
i = Most_Common(h)
if i[1] == 4:
return True, i[0]
else:
return False
# if the most common element occurs 3 times then it is a three of a kind
def is_threeofakind(h):
h = [a[:-1] for a in h]
i = Most_Common(h)
if i[1] == 3:
return True, i[0]
else:
return False
# if the first 2 most common elements have counts of 3 and 2, then it is a full house
def is_fullhouse(h):
h = [a[:-1] for a in h]
data = Counter(h)
a, b = data.most_common(1)[0], data.most_common(2)[-1]
if str(a[1]) == '3' and str(b[1]) == '2':
return True, (a, b)
return False
# if the first 2 most common elements have counts of 2 and 2 then it is a two pair
def is_twopair(h):
h = [a[:-1] for a in h]
data = Counter(h)
a, b = data.most_common(1)[0], data.most_common(2)[-1]
if str(a[1]) == '2' and str(b[1]) == '2':
return True, (a[0], b[0])
return False
#if the first most common element is 2 then it is a pair
# DISCLAIMER: this will return true if the hand is a two pair, but this should not be a conflict because is_twopair is always evaluated and returned first
def is_pair(h):
h = [a[:-1] for a in h]
data = Counter(h)
a = data.most_common(1)[0]
if str(a[1]) == '2':
return True, (a[0])
else:
return False
#get the high card
def get_high(h):
return list(sorted([int(x[:-1]) for x in convert_tonums(h)], reverse =True))[0]
# FOR HIGH CARD or ties, this function compares two hands by ordering the hands from highest to lowest and comparing each card and returning when one is higher then the other
def compare(xs, ys):
xs, ys = list(sorted(xs, reverse =True)), list(sorted(ys, reverse = True))
for i, c in enumerate(xs):
if ys[i] > c:
return 'RIGHT'
elif ys[i] < c:
return 'LEFT'
return "TIE"
# categorized a hand based on previous functions
def evaluate_hand(h):
if is_royal(h):
return "ROYAL FLUSH", h, 10
elif is_seq(h) and is_flush(h) :
return "STRAIGHT FLUSH", h, 9
elif is_fourofakind(h):
_, fourofakind = is_fourofakind(h)
return "FOUR OF A KIND", fourofakind, 8
elif is_fullhouse(h):
return "FULL HOUSE", h, 7
elif is_flush(h):
_, flush = is_flush(h)
return "FLUSH", h, 6
elif is_seq(h):
_, seq = is_seq(h)
return "STRAIGHT", h, 5
elif is_threeofakind(h):
_, threeofakind = is_threeofakind(h)
return "THREE OF A KIND", threeofakind, 4
elif is_twopair(h):
_, two_pair = is_twopair(h)
return "TWO PAIR", two_pair, 3
elif is_pair(h):
_, pair = is_pair(h)
return "PAIR", pair, 2
else:
return "HIGH CARD", h, 1
#this monster function evaluates two hands and also deals with ties and edge cases
# this probably should be broken up into separate functions but aint no body got time for that
def compare_hands(h1,h2):
one, two = evaluate_hand(h1), evaluate_hand(h2)
if one[0] == two[0]:
if one[0] =="STRAIGHT FLUSH":
sett1, sett2 = convert_tonums(h1), convert_tonums(h2)
sett1, sett2 = [int(x[:-1]) for x in sett1], [int(x[:-1]) for x in sett2]
com = compare(sett1, sett2)
if com == "TIE":
return "none", one[1], two[1]
elif com == "RIGHT":
return "right", two[0], two[1]
else:
return "left", one[0], one[1]
elif one[0] == "TWO PAIR":
leftover1, leftover2 = is_twopair(h1), is_twopair(h2)
twm1, twm2 = max([int(x) for x in list(leftover1[1])]), max([int(x) for x in list(leftover2[1])])
if twm1 > twm2:
return "left", one[0], one[1]
elif twm1 < twm2:
return "right", two[0], two[1]
if compare(list(leftover1[1]), list(leftover2[1])) == "TIE":
l1 = [x[:-1] for x in h1 if x[:-1] not in leftover1[1]]
l2 = [x[:-1] for x in h2 if x[:-1] not in leftover2[1]]
if int(l1[0]) == int(l2[0]):
return "none", one[1], two[1]
elif int(l1[0]) > int(l2[0]):
return "left", one[0], one[1]
else:
return "right", two[0], two[1]
elif compare(list(leftover1[1]), list(leftover2[1])) == "RIGHT":
return "right", two[0], two[1]
elif compare(list(leftover1[1]), list(leftover2[1])) == "LEFT":
return "left", one[0], one[1]
elif one[0] == "PAIR":
sh1, sh2 = int(is_pair(h1)[1]), int(is_pair(h2)[1])
if sh1 == sh2:
c1 = [int(x[:-1]) for x in convert_tonums(h1) if not int(sh1) == int(x[:-1])]
c2 = [int(x[:-1]) for x in convert_tonums(h2) if not int(sh1) == int(x[:-1])]
if compare(c1, c2) == "TIE":
return "none", one[1], two[1]
elif compare(c1, c2) == "RIGHT":
return "right", two[0], two[1]
else:
return "left", one[0], one[1]
elif h1 > h2:
return "right", two[0], two[1]
else:
return "left", one[0], one[1]
elif one[0] == 'FULL HOUSE':
fh1, fh2 = int(is_fullhouse(h1)[1][0][0]), int(is_fullhouse(h2)[1][0][0])
if fh1 > fh2:
return "left", one[0], one[1]
else:
return "right", two[0], two[1]
elif one[0] == "HIGH CARD":
sett1, sett2 = convert_tonums(h1), convert_tonums(h2)
sett1, sett2 = [int(x[:-1]) for x in sett1], [int(x[:-1]) for x in sett2]
com = compare(sett1, sett2)
if com == "TIE":
return "none", one[1], two[1]
elif com == "RIGHT":
return "right", two[0], two[1]
else:
return "left", one[0], one[1]
elif len(one[1]) < 5:
if max(one[1]) == max(two[1]):
return "none", one[1], two[1]
elif max(one[1]) > max(two[1]):
return "left", one[0], one[1]
else:
return "right", two[0], two[1]
else:
n_one, n_two = convert_tonums(one[1]), convert_tonums(two[1])
n_one, n_two = [int(x[:-1]) for x in n_one], [int(x[:-1]) for x in n_two]
if max(n_one) == max(n_two):
return "none", one[1], two[1]
elif max(n_one) > max(n_two):
return "left", one[0], one[1]
else:
return "right", two[0], two[1]
elif one[2] > two[2]:
return "left", one[0], one[1]
else:
return "right", two[0], two[1]
'''
a = ['QD', 'KD', '9D', 'JD', 'TD']
b = ['JS', '8S', 'KS', 'AS', 'QS']
print compare_hands(a,b)
'''
- 1. 教計算機玩德州撲克
- 2. Python類示例德州撲克效率
- 3. 德州撲克認出一對
- 4. 爲德州撲克撲克牌編碼邏輯子撲克系統
- 5. 如何評估德州撲克的手與Javascript?
- 6. 確定撲克手兩列
- 7. 確定贏家
- 8. 計算撲克牌手
- 9. 如何使用Javascript中的遞歸來找到最好的德州撲克手?
- 10. 德州撲克中的客戶端/服務器通信
- 11. Java Android應用 - 德州撲克的簡單AI
- 12. 德州撲克數據的關係數據庫結構
- 13. Java-撲克玩家
- 14. 打造德州撲克玩AI..從零開始
- 15. Java:撲克手
- 16. OnePair撲克手法java
- 17. 如何在撲克的贏手功能中返回列表?
- 18. 撲克之手Prolog
- 19. 麻將贏牌手算法
- 20. 在撲克中給予手牌力的算法
- 21. 類圖(德州撲克)中牌和牌之間的關係是什麼?
- 22. 5張牌撲克手中確定一種4的概率Matlab
- 23. 連接4,檢查贏家算法
- 24. 決定誰贏得了爪哇撲克牌
- 25. 撲克手造型問題
- 26. 處理隨機撲克手
- 27. VB撲克手評估器
- 28. 撲克手評估者
- 29. Python - 確定井字遊戲贏家
- 30. PHP - 創建所有可能的撲克組合的撲克算法
那麼你的問題是什麼? – Gabe 2011-03-14 00:12:22
@UCLcajun:這可能有一些幫助 - http://code.google.com/p/specialkpokereval/。 – SK9 2011-03-24 06:30:27
簡易圖書館在蟒蛇,也處理卡片,甲板等:[https://github.com/worldveil/deuces](https://github.com/worldveil/deuces)。 – lollercoaster 2014-08-19 05:11:28