/
combinations.go
101 lines (94 loc) · 3.63 KB
/
combinations.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
package card
import (
"errors"
"slices"
"github.com/Chopikashvili/shell-poker/general"
)
type HandStrength struct {
PlayerId int
CombStrength int
CombName string
OrderedCardValues []int
}
type Combination struct {
strength int
name string
condition func([]Card, []int, []int, []int) bool
}
var combinations = []Combination{
{strength: 8, name: "straight flush", condition: func(cards []Card, i, dis, disC []int) bool {
for _, r := range CombinedSuits {
if len(general.Filter(cards, func(c Card) bool { return c.suit == r })) == 5 && i[0]-i[4] == 4 {
return true
}
}
return false
}},
{strength: 7, name: "four of a kind", condition: func(cards []Card, i, dis, disC []int) bool { return slices.Contains(dis, 4) }},
{strength: 6, name: "full house", condition: func(cards []Card, i, dis, disC []int) bool { return slices.Contains(dis, 3) && slices.Contains(dis, 2) }},
{strength: 5, name: "flush", condition: func(cards []Card, i, dis, disC []int) bool {
for _, r := range CombinedSuits {
if len(general.Filter(cards, func(c Card) bool { return c.suit == r })) == 5 {
return true
}
}
return false
}},
{strength: 4, name: "straight", condition: func(cards []Card, i, dis, disC []int) bool {
return general.ContainsSubslice(disC, []int{1, 1, 1, 1, 1})
}},
{strength: 3, name: "three of a kind", condition: func(cards []Card, i, dis, disC []int) bool { return slices.Contains(dis, 3) }},
{strength: 2, name: "two pairs", condition: func(cards []Card, i, dis, disC []int) bool { return general.Count(dis, 2) == 2 }},
{strength: 1, name: "pair", condition: func(cards []Card, i, dis, disC []int) bool { return slices.Contains(dis, 2) }},
}
// Checks for combinations in a hand
func IdentifyCombinations(playerId int, hand []Card) (HandStrength, error) {
if len(hand) != 7 {
return HandStrength{playerId, -1, "unknown", []int{}}, errors.New("Something went wrong while calculating winner")
}
return identifyCombinations(playerId, hand)
}
func identifyCombinations(playerId int, hand []Card) (HandStrength, error) {
possibleHands := []HandStrength{}
for i := 0; i < 6; i++ {
for j := i + 1; j < 7; j++ {
//makes a hand
resultHand := make([]Card, 0)
for n, c := range hand {
if n != i && n != j {
resultHand = append(resultHand, c)
}
}
//makes a slice of just the values in the hand, plus a copy of a hand, and sorts the original by descending order
resultValues := make([]int, 0)
for _, c := range resultHand {
resultValues = append(resultValues, c.value)
}
resultValuesDesc := make([]int, 5)
resultValues, resultValuesDesc = general.SortDesc(resultValues)
//makes distribution of values, plus a copy for determining straights with a K-A-2 sequence
distribution := make([]int, 13)
distributionCopy := make([]int, 17)
for i := 0; i < 13; i++ {
distribution[i] += general.Count(resultValues, i+2)
distributionCopy[i] += general.Count(resultValues, i+2)
}
for i := 0; i < 4; i++ {
distributionCopy[i+13] = distributionCopy[i]
}
flag := false
for _, c := range combinations {
if c.condition(resultHand, resultValuesDesc, distribution, distributionCopy) {
possibleHands = append(possibleHands, HandStrength{PlayerId: playerId, CombStrength: c.strength, CombName: c.name, OrderedCardValues: resultValuesDesc})
flag = true
break
}
}
if !flag {
possibleHands = append(possibleHands, HandStrength{PlayerId: playerId, CombStrength: 0, CombName: "high card", OrderedCardValues: resultValuesDesc})
}
}
}
//finds the most valuable possible hand and returns it
return slices.MaxFunc(possibleHands, CompareHands), nil
}