좋아, 그래서 내가 수석 프로젝트에 텍사스 홀덤 AI를 만들고있다. 나는 gui 및 내기/거래 절차를 만들었지 만 누가 손을 determine 것인지 결정해야하는 부분에 도달했으며이를 해결할 수있는 최선의 방법을 모릅니다. 나는 파이썬 btw를 사용하고 있습니다. ATM에는 7 개의 컴퓨터 카드 중 하나, 7 개의 컴퓨터 카드 중 하나에 대해 2 개의 목록이 있습니다. 현재 모든 카드는 { 'Number': XX, 'Suit': x}와 같이 목록에 구조체로 저장됩니다. 숫자는 2-14, 수트는 1-4입니다. 이 방식에 접근하는 방법은 각 손 유형에 대해 가장 높은 숫자부터 시작하는 함수를 만드는 것입니다. 예 : self.CheckRoyal (playerCards)을 선택하고 수동으로 목록을 검토하여 왕실 플러시가 달성되었는지 평가합니다. 이것을하기 위해서는 수치 적으로 더 좋은 방법이 있어야합니다.텍사스 홀덤 핸드의 승자를 결정하는 알고리즘
답변
http://www.codingthewheel.com/archives/poker-hand-evaluator-roundup
최상의 알고리즘은 크기 1백메가바이트의 조회 테이블에서 7 개 모습입니까? 이것이 내가 처음으로 제안한 것입니다. here. 또 다른 선임 프로젝트입니다. 간단하고 느리지 만, 그렇지 않으면 당신은 아마도 내가 알지 못하는 복잡한 조합론을보고있을 것입니다.
Monte Carlo을 (내가 정확히 기억한다면) 당신이 얻을 것이다
ralu의 게시물에 사용 된 방법은 내가 본 가장 훌륭한 대안입니다. 저는이 방법을 제 자신의 프로젝트에서 사용했고, 매우 빠릅니다.
절벽 :
는 각각 별개의 포커 손을위한 하나 개의 값을 포함하는 테이블을 생성하기 위해, 몇 가지 전처리를 수행합니다. 테이블이 수작업으로 정렬되어 있는지 확인하십시오.
각 카드 값에는 상응하는 소수가 있습니다. 테이블은 손에있는 각 카드 - 값의 곱에 의해 인덱싱됩니다. 그래서 손 AAAAK의 가치를 찾기 위해, 당신은 주요 곱셈을 계산하고 테이블에 대한 인덱스로 사용 :
int prime = getPrime(hand); // Calculates A.getPrime()...*K.getPrime();
int value = table[prime];
(자바 구문 죄송합니다).
이렇게하면 AAAAK은 KAAAA와 같은 손이며 5 차원 테이블이 필요하지 않습니다.
최상의 5 카드 패의 모든 조합을 선택할 수있는 7 장의 카드로 가야합니다. 가장 큰 값은 손의 실제 가치입니다.
다른 테이블을 사용하여 플래시합니다.
이 구현으로 낭비되는 셀이 많기 때문에 테이블이 꽤 잘게됩니다. 이 문제를 해결하기 위해 사전 처리 중에 맵을 생성 할 수 있습니다.이 맵은 큰 소수 값을 정수 값으로 매핑하고 대신 소스로 사용합니다.
덜 까다로운 평가자와 최소한 좋은 평가자가 여기에 있습니다 : code.google.com/p/specialkpokereval. 또한이 페이지에서 내 대답에 설명되어 있습니다. 즐겨! – SK9
흥미로운 것 같습니다. 공유 해줘서 고마워! –
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. 이웃 객체를 결정하는 알고리즘
- 3. 배열의 길이를 결정하는 알고리즘
- 4. 적절한 약수를 결정하는 알고리즘
- 5. 중첩 지리적 영역을 결정하는 알고리즘
- 6. 비디오 피드에서 방의 크기를 결정하는 알고리즘
- 7. C/C++ 구조체에서 요소의 정렬을 결정하는 알고리즘
- 8. C# 값을 기반으로 사람들의 그룹을 결정하는 알고리즘
- 9. 날짜의 일광 절약 시간을 결정하는 알고리즘?
- 10. 문/텍스트가 얼마나 긍정적인지 부정인지를 결정하는 알고리즘
- 11. MySQL : 승자를 선택하고 순위를 반환하십시오.
- 12. 내 게임은 승자를 표시하지 않습니다.
- 13. sql 집계표를 반환하고 승자를 반환
- 14. 자바 스크립트 카드 게임에서 플레이어 핸드의 아키텍처
- 15. 하나 이상의 문자 쌍 사이에 점이있는 단어의 순열을 결정하는 알고리즘
- 16. 확대/축소를 기반으로지도에 표시 할 점을 결정하는 알고리즘
- 17. 위도/경도 좌표를 수집 할 최소 경계 사각형을 결정하는 알고리즘
- 18. Queuing Theory 다음 고객을 제공 할 알고리즘을 결정하는 알고리즘
- 19. 로드 균형을 조정하고 버스 경로를 결정하는 알고리즘/로직
- 20. 아핀 변환 알고리즘
- 21. 만족도를 줄이기위한 알고리즘
- 22. 그래프 알고리즘, 근사 알고리즘
- 23. 알고리즘
- 24. 결정하는 요소는
- 25. 결정하는 형식
- 26. 광고 게재를위한 스마트 알고리즘
- 27. SELECT를 사용하여 xth 위치에서 시작하는 승자를 위해 MSQL 쿼리
- 28. 거리를 결정하는 효율적인 방법이 있습니까?
- 29. 알고리즘 정의되지 않은 사용자 알고리즘
- 30. 대용량 파일 검색 알고리즘
무엇이 문제입니까? – Gabe
@UCLcajun : http://code.google.com/p/specialkpokereval/ 도움이 될 수 있습니다. – SK9
파이썬에서 카드, 데크 등을 다루는 쉬운 라이브러리 : [https://github.com/worldveil/deuces](https://github.com/worldveil/deuces)]. – lollercoaster