486 lines
8.5 KiB
Go
486 lines
8.5 KiB
Go
package thirteen
|
||
|
||
import (
|
||
"fmt"
|
||
"sort"
|
||
)
|
||
|
||
const (
|
||
SpecialType_0 int = iota
|
||
CyanLongType // 清龙
|
||
ALongType // 一条龙
|
||
TwelveKingType //十二皇族
|
||
ThreeColorFlushType // 三同花顺
|
||
ThreeTheWorldType //三分天下
|
||
AllBigType //全大
|
||
AllSmallType //全小
|
||
SameColorType // 凑一色
|
||
FourThreeType //四套三条
|
||
FivePairsThreeType //五对三条
|
||
SixPairsHalfType // 六对半
|
||
ThreeContinuityType // 三顺子
|
||
ThreeColorsType //三同花
|
||
SpecialTypeMax
|
||
)
|
||
|
||
var SpecialTypeName = map[int]string{
|
||
SpecialType_0: "-",
|
||
CyanLongType: "清龙",
|
||
ALongType: "一条龙",
|
||
TwelveKingType: "十二皇族",
|
||
ThreeColorFlushType: "三同花顺",
|
||
ThreeTheWorldType: "三分天下",
|
||
AllBigType: "全大",
|
||
AllSmallType: "全小",
|
||
SameColorType: "凑一色",
|
||
FourThreeType: "四套三条",
|
||
FivePairsThreeType: "五对三条",
|
||
SixPairsHalfType: "六对半",
|
||
ThreeContinuityType: "三顺子",
|
||
ThreeColorsType: "三同花",
|
||
}
|
||
|
||
func SpecialName(n int) string {
|
||
if n <= 0 {
|
||
return "-"
|
||
}
|
||
return fmt.Sprintf("%v,%v,%v,%v", SpecialTypeName[n/1000000], PokersTypeName[n%1000000/10000], PokersTypeName[n%10000/100], PokersTypeName[n%100])
|
||
}
|
||
|
||
// CyanLong 找清龙
|
||
// 13张同花色
|
||
func CyanLong(cards [13]int, lai []int) bool {
|
||
getLaiZiCards(cards[:], lai) // 去掉癞子牌
|
||
// 找一个花色
|
||
color := -1
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
color = ToColor(v)
|
||
break
|
||
}
|
||
if color < 0 {
|
||
return false
|
||
}
|
||
// 除癞子牌,其余牌同花色
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if ToColor(v) != color {
|
||
return false
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// ALong 找一条龙
|
||
// 13张顺子
|
||
func ALong(cards [13]int, lai []int) bool {
|
||
_, laiZiCards, cardsCount := remainCards(cards[:], lai)
|
||
var n int
|
||
for i := 0; i < 13; i++ {
|
||
if cardsCount[i] == 0 {
|
||
n++
|
||
}
|
||
}
|
||
return n <= len(laiZiCards)
|
||
}
|
||
|
||
// 是不是顺子
|
||
// 没有牌的用癞子填充
|
||
func isFlush(cards []int) bool {
|
||
//fmt.Printf("isFlush: %v\n", PokersShow(cards))
|
||
if len(cards) != 3 && len(cards) != 5 {
|
||
return false
|
||
}
|
||
laiZiCount := 0
|
||
cardsCount := [20]int{}
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
laiZiCount++
|
||
continue
|
||
}
|
||
cardsCount[ToLogic(v)]++
|
||
}
|
||
//fmt.Printf("isFlush cardsCount: %v\n", cardsCount)
|
||
if len(cards) == 3 {
|
||
for i := 0; i < 10; i++ { // 排除QKA
|
||
var n int
|
||
for j := i; j < i+3; j++ {
|
||
if cardsCount[j] == 0 {
|
||
n++
|
||
}
|
||
}
|
||
if n <= laiZiCount {
|
||
return true
|
||
}
|
||
}
|
||
// 找 A 2 3
|
||
n := 0
|
||
if cardsCount[0] == 0 {
|
||
n++
|
||
}
|
||
if cardsCount[1] == 0 {
|
||
n++
|
||
}
|
||
if cardsCount[12] == 0 {
|
||
n++
|
||
}
|
||
if n <= laiZiCount {
|
||
return true
|
||
}
|
||
} else {
|
||
for i := 0; i < 9; i++ {
|
||
var n int
|
||
for j := i; j < i+5; j++ {
|
||
if cardsCount[j] == 0 {
|
||
n++
|
||
}
|
||
}
|
||
if n <= laiZiCount {
|
||
return true
|
||
}
|
||
}
|
||
// 找 A 2 3 4 5
|
||
n := 0
|
||
if cardsCount[0] == 0 {
|
||
n++
|
||
}
|
||
if cardsCount[1] == 0 {
|
||
n++
|
||
}
|
||
if cardsCount[2] == 0 {
|
||
n++
|
||
}
|
||
if cardsCount[3] == 0 {
|
||
n++
|
||
}
|
||
if cardsCount[12] == 0 {
|
||
n++
|
||
}
|
||
if n <= laiZiCount {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 是不是同花
|
||
// 没有牌的用癞子填充
|
||
func isSameColor(cards []int) bool {
|
||
color := -1
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if color < 0 {
|
||
color = ToColor(v)
|
||
} else {
|
||
if ToColor(v) != color {
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// ThreeColorFlush 找三同花顺
|
||
func ThreeColorFlush(cards [13]int, lai []int) bool {
|
||
l := FindAllSameColorFlush(cards[:], lai)
|
||
for _, v := range l {
|
||
c1 := DelCards(cards[:], v)
|
||
l1 := FindAllSameColorFlush(c1, lai)
|
||
//fmt.Printf("第1层:%v--%v\n", PokersShow(v), PokersShow(c1))
|
||
for _, vv := range l1 {
|
||
//fmt.Printf("第2层:%v\n", PokersShow(vv))
|
||
c2 := DelCards(c1, vv)
|
||
//fmt.Printf("第3层:%v\n", PokersShow(c2))
|
||
getLaiZiCards(c2, lai)
|
||
if isFlush(c2) && isSameColor(c2) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// SameColor 找凑一色
|
||
// 13张牌都是黑色或红色
|
||
func SameColor(cards [13]int, lai []int) bool {
|
||
getLaiZiCards(cards[:], lai)
|
||
|
||
color := -1 // 黑色0 红色1
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if ToColor(v) == 3 || ToColor(v) == 1 {
|
||
color = 0
|
||
} else {
|
||
color = 1
|
||
}
|
||
break
|
||
}
|
||
if color < 0 {
|
||
return false
|
||
}
|
||
|
||
for _, v := range cards {
|
||
if v < 0 {
|
||
continue
|
||
}
|
||
if ToColor(v) == 3 || ToColor(v) == 1 {
|
||
if color == 1 {
|
||
return false
|
||
}
|
||
} else {
|
||
if color == 0 {
|
||
return false
|
||
}
|
||
}
|
||
}
|
||
return true
|
||
}
|
||
|
||
// SixPairsHalf 找六对半
|
||
// 有六个对子就算
|
||
func SixPairsHalf(cards [13]int, lai []int) bool {
|
||
_, cardsLaiZi, cardsCount := remainCards(cards[:], lai)
|
||
n := 0
|
||
for k, v := range cardsCount { // 找对子
|
||
if v >= 2 {
|
||
n += v / 2
|
||
cardsCount[k] = v % 2
|
||
}
|
||
}
|
||
p := 0
|
||
for _, v := range cardsCount { // 找单张
|
||
if v > 0 {
|
||
p++
|
||
}
|
||
}
|
||
ln := len(cardsLaiZi)
|
||
if ln >= p {
|
||
ln -= p
|
||
n += p
|
||
p = 0
|
||
} else {
|
||
n += ln
|
||
p -= ln
|
||
ln = 0
|
||
}
|
||
n += ln / 2
|
||
if n == 6 {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
// ThreeContinuity 找三顺子
|
||
func ThreeContinuity(cards [13]int, lai []int) bool {
|
||
l := FindAllFlush(cards[:], lai)
|
||
for _, v := range l {
|
||
c := DelCards(cards[:], v)
|
||
l = FindAllFlush(c, lai)
|
||
for _, vv := range l {
|
||
c = DelCards(c, vv)
|
||
getLaiZiCards(c, lai)
|
||
if isFlush(c) {
|
||
return true
|
||
}
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// ThreeColors 找三同花
|
||
func ThreeColors(cards [13]int, lai []int) bool {
|
||
//sort.Sort(sort.Reverse(sort.IntSlice(cards[:])))
|
||
getLaiZiCards(cards[:], lai)
|
||
colorMap := make(map[int]int)
|
||
for _, v := range cards {
|
||
if v >= 0 {
|
||
colorMap[ToColor(v)]++
|
||
}
|
||
}
|
||
switch len(colorMap) {
|
||
case 0:
|
||
return false
|
||
case 1:
|
||
return false
|
||
case 2:
|
||
var c []int
|
||
for _, v := range colorMap {
|
||
c = append(c, v)
|
||
}
|
||
sort.Ints(c)
|
||
if c[0] <= 3 && c[1] <= 10 {
|
||
return true
|
||
}
|
||
if c[0] <= 5 && c[1] <= 8 {
|
||
return true
|
||
}
|
||
|
||
case 3:
|
||
var c []int
|
||
for _, v := range colorMap {
|
||
c = append(c, v)
|
||
}
|
||
sort.Ints(c)
|
||
if c[0] <= 3 && c[1] <= 5 && c[2] <= 5 {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// 找五对三条
|
||
//func FivePairsThree(cards [13]int) bool {
|
||
// valueMap := make(map[int]int)
|
||
// for _, v := range cards {
|
||
// valueMap[v%13]++
|
||
// }
|
||
// pairs := 0
|
||
// three := 0
|
||
// for _, v := range valueMap {
|
||
// if v == 2 {
|
||
// pairs++
|
||
// } else if v == 3 {
|
||
// three++
|
||
// }
|
||
// }
|
||
// if pairs == 5 && three == 1 {
|
||
// return true
|
||
// }
|
||
// return false
|
||
//}
|
||
|
||
// 找四套三条
|
||
//func FourThree(cards [13]int) bool {
|
||
// valueMap := make(map[int]int)
|
||
// for _, v := range cards {
|
||
// valueMap[v%13]++
|
||
// }
|
||
// three := 0
|
||
// for _, v := range valueMap {
|
||
// if v == 3 {
|
||
// three++
|
||
// }
|
||
// }
|
||
// if three == 4 {
|
||
// return true
|
||
// }
|
||
// return false
|
||
//}
|
||
|
||
// 找全小
|
||
//func AllSmall(cards [13]int) bool {
|
||
// for _, v := range cards {
|
||
// if v%13 > 6 {
|
||
// return false
|
||
// }
|
||
// }
|
||
// return true
|
||
//}
|
||
|
||
// 找全大
|
||
//func AllBig(cards [13]int) bool {
|
||
// for _, v := range cards {
|
||
// if v%13 < 6 {
|
||
// return false
|
||
// }
|
||
// }
|
||
// return true
|
||
//}
|
||
|
||
// 找三分天下
|
||
//func ThreeTheWorld(cards [13]int) bool {
|
||
// fourMap := make(map[int]int)
|
||
// for _, v := range cards {
|
||
// fourMap[v%13]++
|
||
// }
|
||
// i := 0
|
||
// for _, v := range fourMap {
|
||
// if v == 4 {
|
||
// i++
|
||
// }
|
||
// }
|
||
// if i == 3 {
|
||
// return true
|
||
// }
|
||
// return false
|
||
//}
|
||
|
||
// 找十二皇族
|
||
//func TwelveKing(cards [13]int) bool {
|
||
// for _, v := range cards {
|
||
// if v%13 < 9 {
|
||
// return false
|
||
// }
|
||
// }
|
||
// return true
|
||
//}
|
||
|
||
// GetSpecialType 找特殊牌型
|
||
// lai 癞子牌
|
||
func GetSpecialType(cards [13]int, lai []int) int {
|
||
// 清龙判定
|
||
if CyanLong(cards, lai) {
|
||
return CyanLongType
|
||
}
|
||
// 找一条龙
|
||
if ALong(cards, lai) {
|
||
return ALongType
|
||
}
|
||
////找十二皇族
|
||
//if TwelveKing(cards) {
|
||
// return TwelveKingType
|
||
//}
|
||
//找三同花顺
|
||
if ThreeColorFlush(cards, lai) {
|
||
return ThreeColorFlushType
|
||
}
|
||
////找三分天下
|
||
//if ThreeTheWorld(cards) {
|
||
// return ThreeTheWorldType
|
||
//}
|
||
////找全大
|
||
//if AllBig(cards) {
|
||
// return AllBigType
|
||
//}
|
||
////找全小
|
||
//if AllSmall(cards) {
|
||
// return AllSmallType
|
||
//}
|
||
// 找凑一色
|
||
if SameColor(cards, lai) {
|
||
return SameColorType
|
||
}
|
||
////找四套三条
|
||
//if FourThree(cards) {
|
||
// return FourThreeType
|
||
//}
|
||
////找五对三条
|
||
//if FivePairsThree(cards) {
|
||
// return FivePairsThreeType
|
||
//}
|
||
|
||
// 找六对半
|
||
if SixPairsHalf(cards, lai) {
|
||
return SixPairsHalfType
|
||
}
|
||
|
||
// 找三顺子
|
||
if ThreeContinuity(cards, lai) {
|
||
return ThreeContinuityType
|
||
}
|
||
|
||
// 找三同花
|
||
if ThreeColors(cards, lai) {
|
||
return ThreeColorsType
|
||
}
|
||
return 0
|
||
}
|