-
Notifications
You must be signed in to change notification settings - Fork 0
/
figure.go
165 lines (157 loc) · 3.9 KB
/
figure.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
package main
import (
"github.com/usthooz/oozlog/go"
)
// GetPlayerWeight 获取用户牌面权重
func GetPlayerWeight(playersPockers []string) int {
/*
1. 计算对子权重
2. 计算顺子权重
3. 计算飞机权重
4. 计算三对权重(三带一)
5. 计算炸弹权重
*/
var (
// 权重
weight int
)
one, two, three, four := trimBoardGroup(playersPockers)
oneC, _ := one[OneBoards]
twoC, _ := two[TwoBoards]
threeC, _ := three[ThreeBoards]
fourC, _ := four[FourBoards]
weight += len(oneC)*OneBoardsCount + len(twoC)*TwoBoardsCount + len(threeC)*ThreeBoardsCount + len(fourC)*FourBoardsCount
// 大小王权重
weight += getKingBombNum(playersPockers)
return weight
}
// getKingBombNum 王炸权重计算
func getKingBombNum(playersPockers []string) (weight int) {
b := binarySearch(playersPockers, BigKing)
s := binarySearch(playersPockers, SmallKing)
if b >= 0 && s >= 0 {
weight = KingBombCount
return
}
if b >= 0 {
weight = BigKingCount
return
}
if s >= 0 {
weight = SmallKingCount
return
}
return
}
// getTwinsNum 时间复杂度 2logn output: 单个对子的总量
func getTwinsNum(as []string) int {
var (
pss []int
w int
)
// 取出牌面
for _, a := range as {
n, err := getPockerNumber(a)
if err != nil {
ozlog.Infof("getTwinsNum: get pocker num err->%v", err)
continue
}
pss = append(pss, n)
}
for i := 0; i < len(pss); i++ {
// 用于存储成对的数
tran := make(map[int]int)
// 用于减去成对重复的数
sub := make(map[int]int)
for _, a := range pss {
// 找到对子,首先判断之前是否已经成对了,如果已经成了,那么需要拆散这一对
_, ok := tran[a]
if pss[i] == a && !ok {
tran[i] = i
w++
} else if pss[i] == a && ok {
_, ok := sub[i]
// 如果已经减去了,则不再重复减少
if !ok {
sub[i] = i
w--
}
}
}
}
return w
}
// trimBoardGroup 洗牌
func trimBoardGroup(boards []string) (map[int][]int, map[int][]int, map[int][]int, map[int][]int) {
// 查找是否存在大小王
b := binarySearch(boards, BigKing)
if b >= 0 {
boards = append(boards[:b], boards[b+1:]...)
}
s := binarySearch(boards, SmallKing)
if s >= 0 {
boards = append(boards[:s], boards[s+1:]...)
}
bs := sortBoard(boards)
return trimTwinsBoards(bs)
}
// sortBoard 洗牌-按照牌面大小将所有牌从小到大排列
func sortBoard(boards []string) []int {
var (
pss []int
)
// 取出牌面
for _, a := range boards {
n, err := getPockerNumber(a)
if err != nil {
ozlog.Infof("getTwinsNum: get pocker num err->%v", err)
continue
}
pss = append(pss, n)
}
return sectionSort(pss)
}
// trimTwinsBoards 整理连续的牌(2、3、4张)及单牌
func trimTwinsBoards(boards []int) (map[int][]int, map[int][]int, map[int][]int, map[int][]int) {
var (
curLen int
singleBoards, twoBoards, threeBoards, fourBoards map[int][]int
)
singleBoards = make(map[int][]int)
twoBoards = make(map[int][]int)
threeBoards = make(map[int][]int)
fourBoards = make(map[int][]int)
length := len(boards)
for i := 0; i < length; i++ {
if i < curLen {
continue
}
if i+1 >= length {
break
}
if boards[i] == boards[i+1] {
if i+2 >= length {
break
}
if boards[i] == boards[i+2] {
if i+3 >= length {
break
}
if boards[i] == boards[i+3] {
fourBoards[FourBoards] = append(fourBoards[FourBoards], boards[i], boards[i+1], boards[i+2], boards[1+3])
curLen += FourBoards
continue
}
threeBoards[ThreeBoards] = append(threeBoards[ThreeBoards], boards[i], boards[i+1], boards[i+2])
curLen += ThreeBoards
continue
}
twoBoards[TwoBoards] = append(twoBoards[TwoBoards], boards[i], boards[i+1])
curLen += TwoBoards
continue
}
singleBoards[OneBoards] = append(singleBoards[OneBoards], boards[i])
curLen += OneBoards
}
return singleBoards, twoBoards, threeBoards, fourBoards
}