game_sync/gamerule/thirteen/findspecial.go

486 lines
8.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}