1196 lines
25 KiB
Go
1196 lines
25 KiB
Go
package thirteen
|
||
|
||
import (
|
||
"fmt"
|
||
"sort"
|
||
"strings"
|
||
)
|
||
|
||
func getIndex(a []int, e int) int {
|
||
for k, v := range a {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if v == e {
|
||
return k
|
||
}
|
||
}
|
||
return -1
|
||
}
|
||
|
||
func compareLine(a, b []int, getFunc, cmpFunc func(int) int) (int, int, int) {
|
||
ac := make([]int, len(a))
|
||
copy(ac, a)
|
||
sort.Sort(sort.Reverse(sort.IntSlice(ac)))
|
||
bc := make([]int, len(b))
|
||
copy(bc, b)
|
||
sort.Sort(sort.Reverse(sort.IntSlice(bc)))
|
||
var maxA, maxB int
|
||
for i := 0; i < 15; i++ {
|
||
if len(ac) == 0 || len(bc) == 0 {
|
||
return 0, -1, -1
|
||
}
|
||
maxA = -1
|
||
for _, v := range ac {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if getFunc(v) > getFunc(maxA) {
|
||
maxA = v
|
||
}
|
||
}
|
||
if maxA < 0 {
|
||
break
|
||
}
|
||
|
||
maxB = -1
|
||
for _, v := range bc {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if getFunc(v) > getFunc(maxB) {
|
||
maxB = v
|
||
}
|
||
}
|
||
if maxB < 0 {
|
||
break
|
||
}
|
||
|
||
ca, cb := cmpFunc(maxA), cmpFunc(maxB)
|
||
if ca > cb {
|
||
return 1, getIndex(a, maxA), getIndex(b, maxB)
|
||
}
|
||
if ca < cb {
|
||
return -1, getIndex(a, maxA), getIndex(b, maxB)
|
||
}
|
||
ac = DelCards(ac, []int{maxA})
|
||
bc = DelCards(bc, []int{maxB})
|
||
}
|
||
return 0, -1, -1
|
||
}
|
||
|
||
// CompareColorByLogic 依次比最大逻辑点数牌的花色大小
|
||
func CompareColorByLogic(a, b []int) int {
|
||
n, _, _ := compareLine(a, b, ToLogic, ToColor)
|
||
return n
|
||
}
|
||
|
||
func IndexCompareColorByLogic(a, b []int) (int, int, int) {
|
||
return compareLine(a, b, ToLogic, ToColor)
|
||
}
|
||
|
||
// CompareLogic 依次比逻辑点数大小
|
||
func CompareLogic(a, b []int) int {
|
||
n, _, _ := compareLine(a, b, ToLogic, ToLogic)
|
||
return n
|
||
}
|
||
|
||
func IndexCompareLogic(a, b []int) (int, int, int) {
|
||
return compareLine(a, b, ToLogic, ToLogic)
|
||
}
|
||
|
||
func CompareFirstLogic(a, b []int) int {
|
||
if len(a) != 0 && len(b) != 0 {
|
||
if ToLogic(a[0]) > ToLogic(b[0]) {
|
||
return 1
|
||
} else if ToLogic(a[0]) < ToLogic(b[0]) {
|
||
return -1
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// Group 出牌组合
|
||
type Group struct {
|
||
Head [3]int
|
||
Mid [5]int
|
||
End [5]int
|
||
PokerType int // -1 无牌数据,0 有牌数据, 1-13 特殊牌型
|
||
}
|
||
|
||
func (p *Group) String() string {
|
||
buf := strings.Builder{}
|
||
buf.WriteString("\tHead:")
|
||
buf.WriteString(PokerName(p.Head[0]))
|
||
for _, v := range p.Head[1:] {
|
||
buf.WriteString(",")
|
||
buf.WriteString(PokerName(v))
|
||
}
|
||
buf.WriteString("\tMid:")
|
||
buf.WriteString(PokerName(p.Mid[0]))
|
||
for _, v := range p.Mid[1:] {
|
||
buf.WriteString(",")
|
||
buf.WriteString(PokerName(v))
|
||
}
|
||
buf.WriteString("\tEnd:")
|
||
buf.WriteString(PokerName(p.End[0]))
|
||
for _, v := range p.End[1:] {
|
||
buf.WriteString(",")
|
||
buf.WriteString(PokerName(v))
|
||
}
|
||
buf.WriteString(fmt.Sprintf("\tPokerType:%v", SpecialTypeName[p.PokerType]))
|
||
return buf.String()
|
||
}
|
||
|
||
func thanT(c, cs []int) bool {
|
||
num := 0
|
||
for k, v := range c {
|
||
if cs[k] == v {
|
||
num++
|
||
}
|
||
}
|
||
if len(c) == 3 && len(cs) == 3 && num == 3 {
|
||
return true
|
||
}
|
||
if len(c) == 5 && len(cs) == 5 && num == 5 {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
type Logic struct {
|
||
LaiZi []int
|
||
}
|
||
|
||
// GetType 获取牌型
|
||
// cards 牌
|
||
func (l *Logic) GetType(cards []int) int {
|
||
return GetType(cards, l.LaiZi)
|
||
}
|
||
|
||
func (l *Logic) isLaiZi(c int) bool {
|
||
if c < 0 {
|
||
return false
|
||
}
|
||
for _, v := range l.LaiZi {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if v == c {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
func (l *Logic) SortMidAndEnd(cards *Group) *Group {
|
||
if cards.Head[0] == -1 {
|
||
return nil
|
||
}
|
||
a := l.GetType(cards.Head[:])
|
||
b := l.GetType(cards.Mid[:])
|
||
c := l.GetType(cards.End[:])
|
||
if a < b || a < c {
|
||
return nil // 牌型错了就不要了
|
||
}
|
||
|
||
if a == b {
|
||
switch a {
|
||
case PokersTypeThree:
|
||
// 有癞子,癞子一定在三条中
|
||
r1, c1 := FindMaxThreeAAA(cards.Head[:], l.LaiZi)
|
||
r2, c2 := FindMaxThreeAAA(cards.Mid[:], l.LaiZi)
|
||
if len(c1) > 0 && len(c2) > 0 {
|
||
// 比三条
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n == 1 {
|
||
// 交换三条,结束
|
||
var cp1 []int
|
||
for k, v := range cards.Head {
|
||
for i, n := range r1 {
|
||
if v == n {
|
||
cards.Head[k] = -1
|
||
r1[i] = -1
|
||
cp1 = append(cp1, n)
|
||
}
|
||
}
|
||
}
|
||
r1 = cp1
|
||
var cp2 []int
|
||
for k, v := range cards.Mid {
|
||
for i, n := range r2 {
|
||
if v == n {
|
||
cards.Mid[k] = -1
|
||
r2[i] = -1
|
||
cp2 = append(cp2, n)
|
||
}
|
||
}
|
||
}
|
||
r2 = cp2
|
||
for k, v := range cards.Head {
|
||
if v == -1 {
|
||
for m, n := range r2 {
|
||
if n != -1 {
|
||
cards.Head[k] = n
|
||
r2[m] = -1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for k, v := range cards.Mid {
|
||
if v == -1 {
|
||
for m, n := range r1 {
|
||
if n != -1 {
|
||
cards.Mid[k] = n
|
||
r1[m] = -1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else if n == 0 { // 三条点数相同
|
||
// 比逻辑点数
|
||
changeMid := append(DelCards(cards.Mid[:], r2), c2...)
|
||
n = CompareLogic(c1, changeMid)
|
||
if n == 1 {
|
||
// 不可能
|
||
} else if n == 0 { // 逻辑点数相同
|
||
// 比花色,比三条就行了
|
||
//n, index1, index2 := IndexCompareColorByLogic(c1, c2)
|
||
n = 0
|
||
if n == 1 {
|
||
// 花色交换,结束
|
||
//if index1 >= 0 && index2 >= 0 {
|
||
// for k, v := range cards.Head {
|
||
// if v == r1[index1] {
|
||
// cards.Head[k] = -1
|
||
// break
|
||
// }
|
||
// }
|
||
// for k, v := range cards.Mid {
|
||
// if v == r2[index2] {
|
||
// cards.Mid[k] = -1
|
||
// break
|
||
// }
|
||
// }
|
||
// for k, v := range cards.Head {
|
||
// if v == -1 && r2[index2] >= 0 {
|
||
// cards.Head[k] = r2[index2]
|
||
// break
|
||
// }
|
||
// }
|
||
// for k, v := range cards.Mid {
|
||
// if v == -1 && r1[index1] >= 0 {
|
||
// cards.Mid[k] = r1[index1]
|
||
// break
|
||
// }
|
||
// }
|
||
//}
|
||
} else if n == 0 {
|
||
// 比癞子数
|
||
if l.LaiZiCount(r1) < l.LaiZiCount(r2) {
|
||
// 中墩三条中的癞子和头墩三条中的非癞子牌交换一张,结束
|
||
indexMid := -1
|
||
indexHead := -1
|
||
for k, v := range cards.Mid {
|
||
if l.isLaiZi(v) {
|
||
indexMid = k
|
||
break
|
||
}
|
||
}
|
||
for k, v := range cards.Head {
|
||
if v >= 0 && !l.isLaiZi(v) {
|
||
indexHead = k
|
||
break
|
||
}
|
||
}
|
||
if indexMid >= 0 && indexHead >= 0 {
|
||
cards.Head[indexHead], cards.Mid[indexMid] = cards.Mid[indexMid], cards.Head[indexHead]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
case PokersTypePair: // 最多有一个癞子,并且癞子一定在对子中
|
||
r1, c1 := FindMaxPairs(cards.Head[:], l.LaiZi)
|
||
r2, c2 := FindMaxPairs(cards.Mid[:], l.LaiZi)
|
||
if len(c1) > 0 && len(c2) > 0 {
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n == 1 {
|
||
// 交换对子,结束
|
||
var cp1 []int
|
||
for k, v := range cards.Head {
|
||
for i, n := range r1 {
|
||
if v == n {
|
||
cards.Head[k] = -1
|
||
r1[i] = -1
|
||
cp1 = append(cp1, n)
|
||
}
|
||
}
|
||
}
|
||
r1 = cp1
|
||
var cp2 []int
|
||
for k, v := range cards.Mid {
|
||
for i, n := range r2 {
|
||
if v == n {
|
||
cards.Mid[k] = -1
|
||
r2[i] = -1
|
||
cp2 = append(cp2, n)
|
||
}
|
||
}
|
||
}
|
||
r2 = cp2
|
||
for k, v := range cards.Head {
|
||
if v == -1 {
|
||
for m, n := range r2 {
|
||
if n != -1 {
|
||
cards.Head[k] = n
|
||
r2[m] = -1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for k, v := range cards.Mid {
|
||
if v == -1 {
|
||
for m, n := range r1 {
|
||
if n != -1 {
|
||
cards.Mid[k] = n
|
||
r1[m] = -1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} else if n == 0 {
|
||
// 比点数
|
||
nHead := cards.Head
|
||
nMid := cards.Mid
|
||
for k, v := range nHead {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if l.isLaiZi(v) {
|
||
nHead[k] = ToLogic(c1[0]) + 13*3
|
||
break
|
||
}
|
||
}
|
||
for k, v := range nMid {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if l.isLaiZi(v) {
|
||
nHead[k] = ToLogic(c2[0]) + 13*3
|
||
break
|
||
}
|
||
}
|
||
n, index1, index2 := IndexCompareLogic(nHead[:], nMid[:])
|
||
if n == 1 {
|
||
// 最大逻辑点数牌交换,结束
|
||
if index1 >= 0 && index2 >= 0 {
|
||
cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
|
||
}
|
||
} else if n == 0 { // 点数相同
|
||
// 比花色
|
||
//n, index1, index2 := IndexCompareColorByLogic(nHead[:], nMid[:])
|
||
n = 0
|
||
if n == 1 {
|
||
// 交换花色,结束
|
||
//if index1 >= 0 && index2 >= 0 {
|
||
// cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
|
||
//}
|
||
} else if n == 0 {
|
||
// 比癞子多少
|
||
if l.LaiZiCount(r1) < l.LaiZiCount(r2) {
|
||
// 中墩对子中有一个癞子,头墩没有癞子
|
||
// 中墩对中的癞子和头墩对子中的非癞子牌交换一张,结束
|
||
indexMid := -1
|
||
indexHead := -1
|
||
for k, v := range cards.Mid {
|
||
if l.isLaiZi(v) {
|
||
indexMid = k
|
||
break
|
||
}
|
||
}
|
||
for k, v := range cards.Head {
|
||
if v >= 0 && v == r1[0] {
|
||
indexHead = k
|
||
break
|
||
}
|
||
}
|
||
if indexMid >= 0 && indexHead >= 0 {
|
||
cards.Head[indexHead], cards.Mid[indexMid] = cards.Mid[indexMid], cards.Head[indexHead]
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
case PokersTypeOne:
|
||
// 都不会有癞子
|
||
n, index1, index2 := IndexCompareLogic(cards.Head[:], cards.Mid[:])
|
||
if n == 1 {
|
||
// 交换最大逻辑点数的牌
|
||
if index1 >= 0 && index2 >= 0 {
|
||
cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
|
||
}
|
||
} else if n == 0 {
|
||
// 点数相同比花色
|
||
//n, index1, index2 := IndexCompareColorByLogic(cards.Head[:], cards.Mid[:])
|
||
//if n == 1 {
|
||
// // 交换最大花色的牌
|
||
// if index1 >= 0 && index2 >= 0 {
|
||
// cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
|
||
// }
|
||
//}
|
||
}
|
||
}
|
||
}
|
||
|
||
//换牌之后重新识别
|
||
a = l.GetType(cards.Head[:])
|
||
b = l.GetType(cards.Mid[:])
|
||
c = l.GetType(cards.End[:])
|
||
if a < b || a < c {
|
||
return nil
|
||
}
|
||
|
||
if b < c {
|
||
cards.Mid, cards.End = cards.End, cards.Mid
|
||
} else if c == b {
|
||
n := l.CompareFive(cards.Mid, cards.End)
|
||
if n == 1 {
|
||
cards.Mid, cards.End = cards.End, cards.Mid
|
||
}
|
||
}
|
||
return cards
|
||
}
|
||
|
||
func (l *Logic) delPokers(poker []*Group) []*Group {
|
||
if len(poker) == 0 {
|
||
return nil
|
||
}
|
||
//去重
|
||
for _, v := range poker {
|
||
num := 0
|
||
s := 0
|
||
for i := 0; i < len(poker); i++ {
|
||
if poker[i].Head[0] == -1 {
|
||
continue
|
||
}
|
||
if thanT(poker[i].Head[:], v.Head[:]) {
|
||
num++
|
||
}
|
||
if thanT(poker[i].Mid[:], v.Mid[:]) {
|
||
num++
|
||
}
|
||
if thanT(poker[i].End[:], v.End[:]) {
|
||
num++
|
||
}
|
||
if num == 3 {
|
||
s++
|
||
if s > 1 {
|
||
poker[i] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
|
||
}
|
||
}
|
||
num = 0
|
||
}
|
||
}
|
||
//修正
|
||
for k, v := range poker {
|
||
if v.Head[0] != -1 {
|
||
a := l.SortMidAndEnd(v)
|
||
if a != nil {
|
||
poker[k] = a
|
||
} else {
|
||
poker[k] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
|
||
}
|
||
}
|
||
}
|
||
return poker
|
||
}
|
||
|
||
// 查找牌型 返回 (是否找到,找到的牌,找到牌之后剩余的牌)
|
||
func (l *Logic) getPokerTypeCards(cards []int, n int) (b bool, card, remainCards []int) {
|
||
if len(cards) < 3 {
|
||
return
|
||
}
|
||
switch n {
|
||
case PokersTypeFive:
|
||
card, _ := FindMaxFive(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeStraightFlush:
|
||
//找同花顺
|
||
card, _ := FindMaxSameColorFlush(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeFour:
|
||
//找铁支
|
||
card, _ := FindMaxFourAAAA(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeFullHouse:
|
||
//找葫芦
|
||
card, _ := FindMaxGourdCards(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeFlush:
|
||
//找同花
|
||
card, _ := FindMaxSameColors(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeStraight:
|
||
//找顺子
|
||
card, _ := FindMaxFlush(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeThree:
|
||
//找三条
|
||
card, _ := FindMaxThreeAAA(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
case PokersTypeTwoPairs:
|
||
//找对子
|
||
card, _ := FindMaxPairs(cards, l.LaiZi)
|
||
if len(card) != 0 {
|
||
return true, card, DelCards(cards, card)
|
||
}
|
||
}
|
||
|
||
return false, card, remainCards
|
||
}
|
||
|
||
func (l *Logic) findAllCombine(cards [13]int) (pokers []*Group) {
|
||
copyCards := make([]int, 13)
|
||
copy(copyCards, cards[:])
|
||
for i := 0; i < 8; i++ {
|
||
pokers = append(pokers, &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}})
|
||
}
|
||
poker := &Group{}
|
||
index := PokersTypeFive
|
||
for zz := 0; zz < 10; zz++ {
|
||
for _, v := range pokers {
|
||
if v != nil && v.Head[0] == -1 {
|
||
poker = v
|
||
break
|
||
}
|
||
}
|
||
// 从尾墩往前,从大到小牌型顺序获取组合
|
||
for i := index; i < PokersTypePair; i++ {
|
||
b, card, cards2 := l.getPokerTypeCards(copyCards, i)
|
||
if b {
|
||
//fmt.Printf("找到牌型%v----%v\n", PokersShow(card), PokersShow(cards2))
|
||
copyCards = cards2
|
||
if poker.End[0] == -1 {
|
||
if i != PokersTypeTwoPairs {
|
||
copy(poker.End[:], card)
|
||
} else {
|
||
if len(copyCards) == 11 { // 对子
|
||
copy(poker.End[2:], card)
|
||
} else if len(copyCards) == 9 { // 两对
|
||
copy(poker.End[:], card)
|
||
} else {
|
||
copyCards = append(copyCards, card...)
|
||
i++
|
||
}
|
||
}
|
||
i--
|
||
} else if poker.Mid[0] == -1 {
|
||
if i == PokersTypeFive || i == PokersTypeStraightFlush || i == PokersTypeFullHouse || i == PokersTypeFlush || i == PokersTypeStraight {
|
||
copy(poker.Mid[:], card)
|
||
} else if i == PokersTypeFour {
|
||
if len(copyCards) != 1 {
|
||
copy(poker.Mid[:], card)
|
||
} else {
|
||
copyCards = append(copyCards, card...)
|
||
i++
|
||
}
|
||
} else if i == PokersTypeThree {
|
||
al := len(copyCards)
|
||
if al == 5 || al == 6 || al == 7 {
|
||
copy(poker.Mid[:], card)
|
||
} else {
|
||
copyCards = append(copyCards, card...)
|
||
i++
|
||
}
|
||
} else if i == PokersTypeTwoPairs {
|
||
// 6,7,8 对子
|
||
// 4,5,6 两对
|
||
al := len(copyCards)
|
||
if al == 8 || al == 7 {
|
||
copy(poker.Mid[2:], card)
|
||
} else if al == 5 || al == 4 {
|
||
copy(poker.Mid[:], card)
|
||
} else if al == 6 {
|
||
if poker.Mid[2] == -1 {
|
||
copy(poker.Mid[2:], card)
|
||
} else {
|
||
copy(poker.Mid[:], card)
|
||
}
|
||
} else {
|
||
copyCards = append(copyCards, card...)
|
||
i++
|
||
}
|
||
} else {
|
||
i++
|
||
}
|
||
i--
|
||
} else {
|
||
if i == PokersTypeTwoPairs {
|
||
if len(copyCards) == 2 || len(copyCards) == 1 {
|
||
copy(poker.Head[:], card)
|
||
} else if len(copyCards) == 4 || len(copyCards) == 5 {
|
||
copy(poker.Head[:], card)
|
||
copyCards = DelCards(copyCards, card[:])
|
||
} else {
|
||
copyCards = append(copyCards, card...)
|
||
i++
|
||
}
|
||
} else {
|
||
copyCards = append(copyCards, card...)
|
||
i++
|
||
}
|
||
i--
|
||
}
|
||
//fmt.Printf("填充后%v\n", poker)
|
||
}
|
||
}
|
||
//fmt.Println("-->", poker)
|
||
if poker.End[2] == -1 {
|
||
for k, v := range pokers {
|
||
if v.End[2] == -1 {
|
||
pokers[k] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
|
||
}
|
||
}
|
||
pokers = l.delPokers(pokers)
|
||
return
|
||
}
|
||
//fmt.Println(poker)
|
||
// 填充剩余位置的牌
|
||
ci := 0
|
||
for m, n := range poker.End {
|
||
if n == -1 && ci < len(copyCards) {
|
||
poker.End[m] = copyCards[ci]
|
||
ci++
|
||
}
|
||
}
|
||
for m, n := range poker.Mid {
|
||
if n == -1 && ci < len(copyCards) {
|
||
poker.Mid[m] = copyCards[ci]
|
||
ci++
|
||
}
|
||
}
|
||
for m, n := range poker.Head {
|
||
if n == -1 && ci < len(copyCards) {
|
||
poker.Head[m] = copyCards[ci]
|
||
ci++
|
||
}
|
||
}
|
||
//fmt.Println(poker)
|
||
//fmt.Println()
|
||
if index < PokersTypePair {
|
||
index = l.GetType(poker.End[:]) + 1
|
||
copyCards = make([]int, 13)
|
||
copy(copyCards, cards[:])
|
||
for k, v := range pokers {
|
||
if l.GetType(v.End[:]) == 9 {
|
||
pokers[k] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
|
||
break
|
||
}
|
||
}
|
||
} else {
|
||
break
|
||
}
|
||
}
|
||
pokers = l.delPokers(pokers)
|
||
return
|
||
}
|
||
|
||
// GetAllCombine 获取所有组合
|
||
// 特殊组合的 PokerType > 0,无牌数据,数据为 -1
|
||
// 普通组合的 PokerType = 0,有牌数据
|
||
func (l *Logic) GetAllCombine(cards [13]int) (pokers []*Group) {
|
||
tp := l.GetSpecialType(cards)
|
||
if tp != 0 {
|
||
poker := Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
|
||
poker.PokerType = tp
|
||
pokers = append(pokers, &poker)
|
||
}
|
||
aps := l.findAllCombine(cards)
|
||
if len(aps) != 0 {
|
||
for _, v := range aps {
|
||
pokers = append(pokers, v)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// Suggest 获取所有组合,带牌型标记
|
||
func (l *Logic) Suggest(cards [13]int) map[int]*Group {
|
||
m := make(map[int]*Group)
|
||
pokers := l.GetAllCombine(cards)
|
||
if pokers != nil {
|
||
for _, v := range pokers {
|
||
num := 0
|
||
if v != nil && v.PokerType != 0 {
|
||
m[v.PokerType*1000000] = v
|
||
}
|
||
if v != nil && v.PokerType == 0 && v.Head[0] != -1 && v.Head[1] != -1 && v.Head[2] != -1 {
|
||
num += l.GetType(v.Head[:]) * 10000
|
||
num += l.GetType(v.Mid[:]) * 100
|
||
num += l.GetType(v.End[:])
|
||
m[num] = v
|
||
}
|
||
}
|
||
}
|
||
return m
|
||
}
|
||
|
||
func (l *Logic) GetSpecialType(cards [13]int) int {
|
||
return GetSpecialType(cards, l.LaiZi)
|
||
}
|
||
|
||
func (l *Logic) LaiZiCount(cards []int) int {
|
||
var ret int
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
for _, vv := range l.LaiZi {
|
||
if vv < 0 {
|
||
continue
|
||
}
|
||
if v == vv {
|
||
ret++
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return ret
|
||
}
|
||
|
||
// 将癞子牌变成 黑桃A
|
||
func (l *Logic) laiZiTo51(card []int) {
|
||
for k, v := range card {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
for _, vv := range l.LaiZi {
|
||
if vv < 0 {
|
||
continue
|
||
}
|
||
if v == vv {
|
||
card[k] = 51
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func (l *Logic) CompareHead(c, cs [3]int) int {
|
||
a := l.GetType(c[:])
|
||
b := l.GetType(cs[:])
|
||
if a < b {
|
||
return 1
|
||
} else if a > b {
|
||
return -1
|
||
}
|
||
|
||
var r1, r2 []int
|
||
var c1, c2 []int
|
||
switch a {
|
||
case PokersTypeThree:
|
||
r1, c1 = FindMaxThreeAAA(c[:], l.LaiZi)
|
||
r1, c2 = FindMaxThreeAAA(cs[:], l.LaiZi)
|
||
|
||
case PokersTypePair:
|
||
r1, c1 = FindMaxPairs(c[:], l.LaiZi)
|
||
r2, c2 = FindMaxPairs(cs[:], l.LaiZi)
|
||
|
||
case PokersTypeOne:
|
||
// 乌龙肯定不会有癞子
|
||
n := CompareLogic(c[:], cs[:])
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
n = CompareColorByLogic(c[:], cs[:])
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
re1 := DelCards(c[:], r1)
|
||
l.laiZiTo51(re1)
|
||
c1 = append(c1, re1...)
|
||
re2 := DelCards(cs[:], r2)
|
||
l.laiZiTo51(re2)
|
||
c2 = append(c2, re2...)
|
||
n = CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
// 比癞子数
|
||
z1, z2 := l.LaiZiCount(c[:]), l.LaiZiCount(cs[:])
|
||
if z1 < z2 {
|
||
return 1
|
||
}
|
||
if z1 > z2 {
|
||
return -1
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func (l *Logic) CompareFive(c, cs [5]int) int {
|
||
a := l.GetType(c[:])
|
||
b := l.GetType(cs[:])
|
||
if a < b {
|
||
return 1
|
||
} else if a > b {
|
||
return -1
|
||
}
|
||
|
||
// 牌型相同,五张牌相比
|
||
switch a {
|
||
case PokersTypeFive:
|
||
_, c1 := FindMaxFive(c[:], l.LaiZi)
|
||
_, c2 := FindMaxFive(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypeStraightFlush:
|
||
_, c1 := FindMaxSameColorFlush(c[:], l.LaiZi)
|
||
_, c2 := FindMaxSameColorFlush(cs[:], l.LaiZi)
|
||
// 比点数
|
||
// 5 4 3 2 A
|
||
ch1, ch2 := false, false
|
||
if ToPoint(c1[0]) == 5 {
|
||
ch1 = true
|
||
}
|
||
if ToPoint(c2[0]) == 5 {
|
||
ch2 = true
|
||
}
|
||
if ch1 && ch2 {
|
||
// 比花色
|
||
//n := CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
} else if !ch1 && !ch2 {
|
||
n := CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
} else {
|
||
if ch1 {
|
||
return -1
|
||
}
|
||
return 1
|
||
}
|
||
|
||
case PokersTypeFour:
|
||
r1, c1 := FindMaxFourAAAA(c[:], l.LaiZi)
|
||
r2, c2 := FindMaxFourAAAA(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
re1 := DelCards(c[:], r1)
|
||
l.laiZiTo51(re1)
|
||
c1 = append(c1, re1...)
|
||
re2 := DelCards(cs[:], r2)
|
||
l.laiZiTo51(re2)
|
||
c2 = append(c2, re2...)
|
||
n = CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypeFullHouse:
|
||
_, c1 := FindMaxGourdCards(c[:], l.LaiZi)
|
||
_, c2 := FindMaxGourdCards(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
n = CompareFirstLogic(c1[3:], c2[3:])
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypeFlush:
|
||
_, c1 := FindMaxSameColors(c[:], l.LaiZi)
|
||
_, c2 := FindMaxSameColors(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypeStraight:
|
||
_, c1 := FindMaxFlush(c[:], l.LaiZi)
|
||
_, c2 := FindMaxFlush(cs[:], l.LaiZi)
|
||
// 比点数
|
||
// 5 4 3 2 A
|
||
ch1, ch2 := false, false
|
||
if ToPoint(c1[0]) == 5 {
|
||
ch1 = true
|
||
}
|
||
if ToPoint(c2[0]) == 5 {
|
||
ch2 = true
|
||
}
|
||
if ch1 && ch2 {
|
||
// 比花色
|
||
//n := CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
} else if !ch1 && !ch2 {
|
||
n := CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
} else {
|
||
if ch1 {
|
||
return -1
|
||
}
|
||
return 1
|
||
}
|
||
|
||
case PokersTypeThree:
|
||
r1, c1 := FindMaxThreeAAA(c[:], l.LaiZi)
|
||
r2, c2 := FindMaxThreeAAA(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
re1 := DelCards(c[:], r1)
|
||
l.laiZiTo51(re1)
|
||
c1 = append(c1, re1...)
|
||
re2 := DelCards(cs[:], r2)
|
||
l.laiZiTo51(re2)
|
||
c2 = append(c2, re2...)
|
||
n = CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypeTwoPairs:
|
||
r1, c1 := FindMaxPairs(c[:], l.LaiZi)
|
||
r2, c2 := FindMaxPairs(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
r12, c12 := FindMaxPairs(DelCards(c[:], r1), l.LaiZi)
|
||
r22, c22 := FindMaxPairs(DelCards(cs[:], r2), l.LaiZi)
|
||
n = CompareFirstLogic(c12, c22)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
|
||
c1 = append(c1, c12...)
|
||
c2 = append(c2, c22...)
|
||
|
||
re1 := DelCards(c[:], append(r1, r12...))
|
||
l.laiZiTo51(re1)
|
||
c1 = append(c1, re1...)
|
||
re2 := DelCards(cs[:], append(r2, r22...))
|
||
l.laiZiTo51(re2)
|
||
c2 = append(c2, re2...)
|
||
n = CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypePair:
|
||
r1, c1 := FindMaxPairs(c[:], l.LaiZi)
|
||
r2, c2 := FindMaxPairs(cs[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
re1 := DelCards(c[:], r1)
|
||
l.laiZiTo51(re1)
|
||
c1 = append(c1, re1...)
|
||
re2 := DelCards(cs[:], r2)
|
||
l.laiZiTo51(re2)
|
||
c2 = append(c2, re2...)
|
||
n = CompareLogic(c1, c2)
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, c2)
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
|
||
case PokersTypeOne:
|
||
// 乌龙不会有癞子
|
||
// 比点数
|
||
n := CompareLogic(c[:], cs[:])
|
||
if n != 0 {
|
||
return n
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c[:], cs[:])
|
||
//if n != 0 {
|
||
// return n
|
||
//}
|
||
return 0
|
||
}
|
||
|
||
// 比癞子数
|
||
z1, z2 := l.LaiZiCount(c[:]), l.LaiZiCount(cs[:])
|
||
if z1 < z2 {
|
||
return 1
|
||
}
|
||
if z1 > z2 {
|
||
return -1
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func (l *Logic) IsDP(head [3]int, mid, end [5]int) bool {
|
||
if l.CompareFive(mid, end) > 0 {
|
||
return true
|
||
}
|
||
|
||
h := l.GetType(head[:])
|
||
m := l.GetType(mid[:])
|
||
if h < m {
|
||
return true
|
||
}
|
||
|
||
if h == m { // 牌型相同,比点数,比癞子
|
||
switch h {
|
||
case PokersTypeThree: // 如果有癞子,癞子一定在三条里
|
||
r1, c1 := FindMaxThreeAAA(head[:], l.LaiZi)
|
||
r2, c2 := FindMaxThreeAAA(mid[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n == 1
|
||
}
|
||
// 比最大牌点数
|
||
changeMid := append(DelCards(mid[:], r2), c2...)
|
||
n = CompareLogic(c1, changeMid)
|
||
if n != 0 {
|
||
return n == 1
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, changeMid)
|
||
//if n != 0 {
|
||
// return n == 1
|
||
//}
|
||
// 比癞子数
|
||
z1, z2 := l.LaiZiCount(r1), l.LaiZiCount(r2)
|
||
if z1 < z2 {
|
||
return true
|
||
}
|
||
if z1 > z2 {
|
||
return false
|
||
}
|
||
|
||
case PokersTypePair: // 如果有癞子,癞子一定在对子中
|
||
r1, c1 := FindMaxPairs(head[:], l.LaiZi)
|
||
r2, c2 := FindMaxPairs(mid[:], l.LaiZi)
|
||
// 比点数
|
||
n := CompareFirstLogic(c1, c2)
|
||
if n != 0 {
|
||
return n == 1
|
||
}
|
||
// 比最大牌点数
|
||
changeMid := append(DelCards(mid[:], r2), c2...)
|
||
n = CompareLogic(c1, changeMid)
|
||
if n != 0 {
|
||
return n == 1
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(c1, changeMid)
|
||
//if n != 0 {
|
||
// return n == 1
|
||
//}
|
||
// 比癞子数
|
||
z1, z2 := l.LaiZiCount(r1), l.LaiZiCount(r2)
|
||
if z1 < z2 {
|
||
return true
|
||
}
|
||
if z1 > z2 {
|
||
return false
|
||
}
|
||
|
||
case PokersTypeOne: // 乌龙不会有癞子
|
||
// 比点数
|
||
n := CompareLogic(head[:], mid[:])
|
||
if n != 0 {
|
||
return n == 1
|
||
}
|
||
// 比花色
|
||
//n = CompareColorByLogic(head[:], mid[:])
|
||
//if n != 0 {
|
||
// return n == 1
|
||
//}
|
||
}
|
||
}
|
||
|
||
return false
|
||
}
|