forked from chehsunliu/poker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
evaluator.go
99 lines (80 loc) · 1.74 KB
/
evaluator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package cards
import (
"fmt"
)
var table *lookupTable
func init() {
table = newLookupTable()
}
func RankClass(rank int32) int32 {
targets := [...]int32{
maxStraightFlush,
maxFourOfAKind,
maxFullHouse,
maxFlush,
maxStraight,
maxThreeOfAKind,
maxTwoPair,
maxPair,
maxHighCard,
}
if rank < 0 {
panic(fmt.Sprintf("rank %d is less than zero", rank))
}
for _, target := range targets {
if rank <= target {
return maxToRankClass[target]
}
}
panic(fmt.Sprintf("rank %d is unknown", rank))
}
func RankString(rank int32) string {
return rankClassToString[RankClass(rank)]
}
func Evaluate(cards []Card) int32 {
switch len(cards) {
case 5:
return five(cards...)
case 6:
return six(cards...)
case 7:
return seven(cards...)
default:
panic("Only support 5, 6 and 7 cards.")
}
}
func five(cards ...Card) int32 {
if cards[0]&cards[1]&cards[2]&cards[3]&cards[4]&0xF000 != 0 {
handOR := (cards[0] | cards[1] | cards[2] | cards[3] | cards[4]) >> 16
prime := primeProductFromRankBits(int32(handOR))
return table.flushLookup[prime]
}
prime := primeProductFromHand(cards)
return table.unsuitedLookup[prime]
}
func six(cards ...Card) int32 {
var minimum int32 = maxHighCard
targets := make([]Card, len(cards))
for i := 0; i < len(cards); i++ {
copy(targets, cards)
targets := append(targets[:i], targets[i+1:]...)
score := five(targets...)
if score < minimum {
minimum = score
}
}
return minimum
}
func seven(cards ...Card) int32 {
var minimum int32 = maxHighCard
targets := make([]Card, len(cards))
for i := 0; i < len(cards); i++ {
copy(targets, cards)
targets := append(targets[:i], targets[i+1:]...)
score := six(targets...)
if score < minimum {
minimum = score
}
}
return minimum
}