-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpoker.go
192 lines (171 loc) · 4.76 KB
/
poker.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package main
import (
"fmt"
"os"
"bufio"
"strings"
"time"
)
type Card struct {
value, suit byte
}
type Hand []Card
/*func (hand Hand) ContainsCard(value, suit byte) bool {
for i:=0; i < len(hand); i++ {
if hand[i].value== value && hand[i].suit == suit {
return true
}
}
return false
}*/
func (hand Hand) Value() (value int, cardValue byte) {
/*
0 - High Card: Highest value card.
1 - One Pair: Two cards of the same value.
2 - Two Pairs: Two different pairs.
3 - Three of a Kind: Three cards of the same value.
4 - Straight: All cards are consecutive values.
5 - Flush: All cards of the same suit.
6 - Full House: Three of a kind and a pair.
7 - Four of a Kind: Four cards of the same value.
8 - Straight Flush: All cards are consecutive values of same suit.
9 - Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
*/
//Sort the hand by value
for card:=0; card<len(hand); card++ {
for i:=0; i<len(hand)-1; i++ {
if hand[i].value > hand[i+1].value {
heavyCard := hand[i+1]
hand[i+1] = hand[i]
hand[i] = heavyCard
}
}
}
var Straight bool = true
for i:=0; i < len(hand)-1; i++ {
if hand[i].value + byte(1) != hand[i+1].value { Straight=false; break }
}
var Flush bool = false
if hand[0].suit == hand[1].suit &&
hand[0].suit == hand[2].suit &&
hand[0].suit == hand[3].suit &&
hand[0].suit == hand[4].suit {
Flush = true
}
if Flush && Straight && hand[0].value == byte(8) { //8 is index of 'T' in order array
return 9, hand[4].value //Royal Flush
}
if Straight && Flush {
return 8, hand[4].value //Straight Flush
}
var kindsCountArray []int
var kindsArray []Card
for i:=0; i < len(hand); i++ {
found:=false
for kind:=0; kind< len(kindsArray); kind++{
if hand[i].value == kindsArray[kind].value {
kindsCountArray[kind] += 1; found= true; break
}
}
if found == false || len(kindsArray)==0 {
kindsCountArray = append(kindsCountArray, 1)
kindsArray = append(kindsArray, hand[i])
}
}
var FourOfAKind bool = false
var ThreeOfAKind bool = false
var TwoOfAKind bool = false
var HighestKindIndex int
for i:=0; i < len(kindsCountArray); i++ {
if kindsCountArray[i] == 4 {FourOfAKind=true;HighestKindIndex=i;break}
if kindsCountArray[i] == 3 {ThreeOfAKind=true; HighestKindIndex=i}
if kindsCountArray[i] == 2 {
TwoOfAKind=true
if !ThreeOfAKind{HighestKindIndex=i}
}
}
if FourOfAKind {
return 7, kindsArray[HighestKindIndex].value //Four of a kind
}
if TwoOfAKind && ThreeOfAKind {
return 6, kindsArray[HighestKindIndex].value //Full House
}
if Straight {
return 5, hand[4].value //Straight
}
if Flush {
return 4, hand[4].value //Flush
}
if ThreeOfAKind {
return 3, kindsArray[HighestKindIndex].value //Three of a kind
}
if TwoOfAKind {
if len(kindsArray)<=3 {
return 2, kindsArray[HighestKindIndex].value //Two Pair
} else {
return 1, kindsArray[HighestKindIndex].value //One Pair
}
}
return 0, hand[4].value
}
func StringToByteHand(str string) (hand Hand) {
OrderedByValue := []byte{'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'}
StrArray := strings.Split(str, " ")
for i:= 0; i<len(StrArray); i++ {
var card Card;
for index:=0; index < len(OrderedByValue); index++ {
if []byte(StrArray[i])[0] == OrderedByValue[index] {card.value = byte(index);break}
}
card.suit = []byte(StrArray[i])[1]
hand = append(hand, card)
}
return hand
}
func ByteHandToString(hand Hand) (str string) {
OrderedByValue := []byte{'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'}
for i:=0; i<len(hand); i++ {
str = str + string(OrderedByValue[hand[i].value]) +string(hand[i].suit)
if i != len(hand)-1 {str = str + " "}
}
return str
}
func HighestHand(players []Hand, winCount []int) (winner int){
HighestHand := -1
HighCard := byte(0)
for hand:=0; hand<len(players); hand++ {
CurrentHand, ThisHighCard := players[hand].Value()
if CurrentHand > HighestHand {
HighestHand = CurrentHand
winner = hand
HighCard = ThisHighCard
} else if CurrentHand == HighestHand {
if ThisHighCard>HighCard {
winner = hand
HighCard = ThisHighCard
}
}
}
winCount[winner] = winCount[winner]+1
return winner
}
func main() {
beginning:=time.Now()
fmt.Println("Begin Euler Problem #54: Poker Hands")
file, err := os.Open("poker.txt"); if err != nil {
return
}
reader := bufio.NewReader(file)
winCount := []int{0, 0}
for {
str, err := reader.ReadString('\n')
hand := StringToByteHand(str)
var players []Hand
for i:=0; i+5 <= 10; i+=5 {
players = append(players, hand[i:i+5])
}
go HighestHand(players, winCount)
if err != nil { break }
}
fmt.Println("player 1 won ", winCount[0], "times")
fmt.Println("completed in", time.Since(beginning).Nanoseconds()/1000/1000, "milliseconds")
}