946 lines
19 KiB
Go
946 lines
19 KiB
Go
package samloc
|
|
|
|
import (
|
|
"sort"
|
|
)
|
|
|
|
const (
|
|
Pass int = iota //0 nil
|
|
Single //1 单张
|
|
Twin //2 对子
|
|
Triple //3 三张
|
|
Straight //4 顺子
|
|
Four //5 四张
|
|
TwinFour //6 两组四张
|
|
StraightFiveTriple //7 五连对
|
|
ThreeTriple //8 三个三张
|
|
ColorSame //9 同色
|
|
Four2 //10 四张二
|
|
TenStraight //11 一条龙
|
|
)
|
|
|
|
const (
|
|
POKER_3 int32 = iota // 0
|
|
POKER_4 // 1
|
|
POKER_5 // 2
|
|
POKER_6 // 3
|
|
POKER_7 // 4
|
|
POKER_8 // 5
|
|
POKER_9 // 6
|
|
POKER_10 // 7
|
|
POKER_J // 8
|
|
POKER_Q // 9
|
|
POKER_K // 10
|
|
POKER_A // 11
|
|
POKER_2 // 12
|
|
)
|
|
|
|
const (
|
|
Club int = iota //0,黑桃
|
|
Spade //1,梅花
|
|
Diamond //2,方块
|
|
Heart //3,红桃
|
|
)
|
|
|
|
const (
|
|
Score2 int32 = 15 //4张 压2
|
|
ScoreFour int32 = 20 //4张 压4张
|
|
ScoreBaoSam int32 = 20 //baosam
|
|
ScoreLore int32 = 20 // 通杀
|
|
Baopei2 int32 = 10 // 包赔
|
|
Treo int32 = 15 // 结束游戏后而不打出任何牌
|
|
)
|
|
|
|
const (
|
|
BaosamNot int = 1 // 0 非baosam 正常结算
|
|
BaosamWin int = 2 // 1 baosam赢
|
|
BaosamLose int = 4 // 2 baosam输
|
|
SamLore int = 8 // 2 通杀
|
|
)
|
|
|
|
// KindOfCard 牌型
|
|
type KindOfCard struct {
|
|
kind int //牌型
|
|
// cards []int32 //出牌
|
|
min int32 //最小牌
|
|
max int32 //最大牌
|
|
len int32 //牌的长度
|
|
same int32 //同牌数量 33 -> 2
|
|
num int32 //牌的数量
|
|
ktype int //牌的权重
|
|
}
|
|
|
|
func (this *KindOfCard) GetKind() int { return this.kind }
|
|
func (this *KindOfCard) GetLen() int32 { return this.len }
|
|
func (this *KindOfCard) GetMin() int32 { return this.min }
|
|
func (this *KindOfCard) GetSame() int32 { return this.same }
|
|
func (this *KindOfCard) GetNum() int32 { return this.num }
|
|
|
|
type Kds struct {
|
|
kd []*KindOfCard
|
|
}
|
|
|
|
func (this *Kds) Len() int { return len(this.kd) }
|
|
func (this *Kds) Swap(i, j int) { this.kd[i], this.kd[j] = this.kd[j], this.kd[i] }
|
|
func (this *Kds) Less(i, j int) bool {
|
|
if this.kd[i].ktype > this.kd[j].ktype { // 大到小
|
|
return true
|
|
} else if this.kd[i].ktype < this.kd[j].ktype {
|
|
return false
|
|
}
|
|
if this.kd[i].len > this.kd[j].len {
|
|
return true
|
|
}
|
|
if this.kd[i].min < this.kd[j].min {
|
|
if this.kd[i].min < 0 { // A 2做连 往后放
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
return false // 小到大
|
|
}
|
|
|
|
//func (this *KindOfCard) GetCards() []int32 { return this.cards }
|
|
func (this *KindOfCard) OutPokers(poker []int32) []int32 {
|
|
pok := make([]int32, len(poker))
|
|
copy(pok, poker)
|
|
var ret []int32
|
|
if this != nil && this.num != 0 {
|
|
|
|
for i := this.min; i <= this.max; {
|
|
va := i
|
|
if va < 0 {
|
|
va = va + POKER_2 + 1
|
|
}
|
|
for j := 0; j != int(this.same); j++ {
|
|
for k, v := range pok {
|
|
if Value32(v) == va {
|
|
ret = append(ret, v)
|
|
pok = append(pok[:k], pok[k+1:]...) // del
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if this.same > 3 && i != this.max {
|
|
i = this.max
|
|
} else {
|
|
i++
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return ret
|
|
}
|
|
|
|
// SortInt32 []int32
|
|
type SortInt32 []int32
|
|
|
|
func (a SortInt32) Len() int { return len(a) }
|
|
func (a SortInt32) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
func (a SortInt32) Less(i, j int) bool {
|
|
|
|
b := Value(a[i])
|
|
c := Value(a[j])
|
|
|
|
if b == c {
|
|
return b < c
|
|
}
|
|
return b < c
|
|
}
|
|
|
|
// Color 黑桃0 梅花1 方片2 紅桃3
|
|
func Color(c int32) int {
|
|
return int(c) / PER_CARD_COLOR_MAX
|
|
}
|
|
|
|
func RedColor(c int32) int { // Heart 红色 Club 黑色
|
|
if (int(c) / PER_CARD_COLOR_MAX) > Spade {
|
|
return Heart
|
|
}
|
|
return Club
|
|
}
|
|
|
|
func Value(c int32) int {
|
|
return int(c) % PER_CARD_COLOR_MAX
|
|
}
|
|
|
|
func Value32(c int32) int32 {
|
|
return c % PER_CARD_COLOR_MAX
|
|
}
|
|
|
|
func ValueStr(c int32) int {
|
|
if int(c+3)%PER_CARD_COLOR_MAX == 0 {
|
|
return PER_CARD_COLOR_MAX
|
|
}
|
|
return int(c+3) % PER_CARD_COLOR_MAX
|
|
}
|
|
|
|
func IsSingle(cards []int32) bool { //单张
|
|
if len(cards) == 1 {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IsContainPOKER2(cards []int32) bool { //全是2
|
|
for _, v := range cards {
|
|
if Value32(v) == POKER_2 {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IsHavePOKER2(cards []int32) bool { //全是2
|
|
for _, v := range cards {
|
|
if v == InvalideCard {
|
|
continue
|
|
}
|
|
if Value32(v) != POKER_2 {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func DelOtherPOKER2(cards []int32, del []int32) bool { //全是2
|
|
cpcards := append([]int32{}, cards...)
|
|
for _, v := range del {
|
|
for i, k := range cpcards {
|
|
if v == k {
|
|
cpcards[i] = InvalideCard
|
|
}
|
|
}
|
|
}
|
|
num := 0
|
|
for _, v := range cpcards {
|
|
if v == InvalideCard {
|
|
num++
|
|
continue
|
|
}
|
|
if Value32(v) != POKER_2 {
|
|
return false
|
|
}
|
|
}
|
|
if num == Hand_CardNum {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func GetMaxCard(cards []int32) int32 { //单张
|
|
max := int32(0)
|
|
for _, v := range cards {
|
|
if v != InvalideCard {
|
|
vv := Value32(v)
|
|
if vv > max {
|
|
max = vv
|
|
}
|
|
}
|
|
}
|
|
return max
|
|
}
|
|
|
|
func IsTwin(cards []int32) bool { //对子
|
|
if len(cards) == 2 {
|
|
if Value(cards[0]) == Value(cards[1]) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IsValueStraight(tmpCards []int32) bool { //顺子
|
|
if IsContainPOKER2(tmpCards) { // 包含2 单连要
|
|
|
|
for i := range tmpCards {
|
|
if tmpCards[i] > POKER_K {
|
|
tmpCards[i] = tmpCards[i] - POKER_2 - 1
|
|
}
|
|
}
|
|
sort.Sort(SortInt32(tmpCards))
|
|
}
|
|
if len(tmpCards) < 3 || len(tmpCards) > 12 {
|
|
return false
|
|
}
|
|
|
|
for i := 0; i < len(tmpCards)-1; i++ {
|
|
card := tmpCards[i]
|
|
nextCard := tmpCards[i+1]
|
|
if nextCard-card != 1 { // 不相邻
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func IsTriple(cards []int32) bool { //三张
|
|
if len(cards)%3 != 0 {
|
|
return false
|
|
}
|
|
if Value(cards[0]) != Value(cards[1]) {
|
|
return false
|
|
}
|
|
if Value(cards[1]) != Value(cards[2]) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func IsFour(cards []int32) bool { //四张
|
|
if len(cards) != 4 {
|
|
return false
|
|
}
|
|
if Value(cards[0]) != Value(cards[1]) {
|
|
return false
|
|
}
|
|
if Value(cards[1]) != Value(cards[2]) {
|
|
return false
|
|
}
|
|
if Value(cards[2]) != Value(cards[3]) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func IsDouFour(cards []int32) bool { //两 四张
|
|
if len(cards) != 8 {
|
|
return false
|
|
}
|
|
tmpCards := []int32{}
|
|
for _, card := range cards {
|
|
|
|
tmpCards = append(tmpCards, int32(Value(card)))
|
|
}
|
|
sort.Sort(SortInt32(tmpCards))
|
|
// fmt.Println(tmpCards[:4], tmpCards[4:], IsFour(tmpCards[:4]), IsFour(tmpCards[4:]))
|
|
if IsFour(tmpCards[:4]) && IsFour(tmpCards[4:]) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IsColorSame(cards []int32) bool { // 同色
|
|
|
|
c := RedColor(cards[0])
|
|
for _, card := range cards {
|
|
if c != RedColor(card) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func pt32m(cards []int32) map[int32]int32 {
|
|
m := make(map[int32]int32)
|
|
for _, v := range cards {
|
|
m[Value32(v)]++
|
|
}
|
|
return m
|
|
}
|
|
|
|
func ptstr32m(cards []int32) map[int32]int32 {
|
|
m := make(map[int32]int32)
|
|
for _, v := range cards {
|
|
vl := Value32(v)
|
|
m[vl]++
|
|
}
|
|
if m[POKER_2] != 0 {
|
|
m[POKER_2-POKER_2-1] = m[POKER_2]
|
|
m[POKER_A-POKER_2-1] = m[POKER_A]
|
|
}
|
|
return m
|
|
}
|
|
|
|
/*func findcardCommon(m map[int]int32, n int32) (res [][]int32) {
|
|
max := int(POKER_2)
|
|
|
|
for i := 0; i <= max; i++ {
|
|
if m[i] >= n {
|
|
res = append(res, []int32{}...)
|
|
}
|
|
}
|
|
return
|
|
}*/
|
|
|
|
// 通杀
|
|
func CardLore(cards []int32) (int, int32) {
|
|
|
|
if int32(len(cards)) != HandCardNum {
|
|
return Pass, -3
|
|
}
|
|
for _, v := range cards {
|
|
if v == -1 {
|
|
return Pass, -3
|
|
}
|
|
}
|
|
max := POKER_2
|
|
smap := pt32m(cards)
|
|
|
|
tmpCards := []int32{}
|
|
for _, card := range cards {
|
|
|
|
tmpCards = append(tmpCards, int32(Value(card)))
|
|
}
|
|
sort.Sort(SortInt32(tmpCards))
|
|
|
|
// 一条龙>四张2>10张颜色相同>三个三张>五连对
|
|
|
|
if IsValueStraight(tmpCards) { // 一条龙
|
|
return TenStraight, tmpCards[HandCardNum-1]
|
|
}
|
|
|
|
if smap[POKER_2] == 4 { // 四张
|
|
return Four2, tmpCards[HandCardNum-1]
|
|
}
|
|
|
|
if IsColorSame(cards) { // 同色
|
|
return ColorSame, tmpCards[HandCardNum-1]
|
|
}
|
|
|
|
threenum := 0
|
|
for i := int32(0); i <= max; i++ {
|
|
v, _ := smap[i]
|
|
if v > 2 {
|
|
threenum++
|
|
}
|
|
if threenum == 3 {
|
|
return ThreeTriple, int32(i)
|
|
}
|
|
|
|
}
|
|
freenum := 0
|
|
for i := int32(0); i <= max; i++ {
|
|
v, _ := smap[i]
|
|
if v == 0 && freenum == 0 {
|
|
continue
|
|
}
|
|
if v != 2 {
|
|
return Pass, -3
|
|
}
|
|
if i == POKER_2 {
|
|
return Pass, -3
|
|
}
|
|
freenum += 1
|
|
if freenum == 5 {
|
|
return StraightFiveTriple, int32(i)
|
|
}
|
|
|
|
}
|
|
|
|
return Pass, -3
|
|
}
|
|
|
|
func GetCardKind(cards []int32) *KindOfCard { // cardType 类型 // 最小
|
|
|
|
count := int32(len(cards))
|
|
ret := &KindOfCard{
|
|
num: count,
|
|
kind: Pass,
|
|
//cards: append([]int32{}, cards...),
|
|
}
|
|
if count <= 0 {
|
|
return ret
|
|
}
|
|
tmpCards := []int32{}
|
|
for _, card := range cards {
|
|
|
|
tmpCards = append(tmpCards, int32(Value(card)))
|
|
}
|
|
sort.Sort(SortInt32(tmpCards))
|
|
|
|
// fmt.Printf("GetCardKind %x %x\n", cards, tmpCards)
|
|
switch count {
|
|
case 1: //单牌
|
|
ret.min = tmpCards[0]
|
|
ret.max = tmpCards[0]
|
|
ret.len = 1
|
|
ret.same = 1
|
|
ret.kind = Single
|
|
ret.ktype = GetCardType(ret)
|
|
return ret
|
|
case 2: //对牌
|
|
if IsTwin(cards) {
|
|
ret.min = tmpCards[0]
|
|
ret.max = tmpCards[0]
|
|
ret.kind = Twin
|
|
ret.len = 1
|
|
ret.same = 2
|
|
ret.ktype = GetCardType(ret)
|
|
}
|
|
return ret
|
|
}
|
|
|
|
return analysCardKind(cards, tmpCards, ret, count)
|
|
}
|
|
|
|
func analysCardKind(cards []int32, tmpCards []int32, ret *KindOfCard, count int32) *KindOfCard { // cardType 类型 // 最小
|
|
|
|
switch count {
|
|
case 3:
|
|
if (tmpCards[0] == tmpCards[1]) && IsTriple(tmpCards) {
|
|
ret.min = tmpCards[0]
|
|
ret.max = tmpCards[0]
|
|
ret.kind = Triple
|
|
ret.len = 1
|
|
ret.same = 3
|
|
ret.ktype = GetCardType(ret)
|
|
return ret // 三张
|
|
}
|
|
case 4:
|
|
if (tmpCards[0] == tmpCards[1]) && IsFour(tmpCards) {
|
|
ret.min = tmpCards[0]
|
|
ret.max = tmpCards[0]
|
|
ret.kind = Four
|
|
ret.len = 1
|
|
ret.same = 4
|
|
ret.ktype = GetCardType(ret)
|
|
return ret // 四张
|
|
}
|
|
case 8:
|
|
if (tmpCards[0] == tmpCards[1]) && IsDouFour(tmpCards) {
|
|
ret.min = tmpCards[0]
|
|
ret.max = tmpCards[7]
|
|
ret.kind = TwinFour
|
|
ret.len = 2
|
|
ret.same = 4
|
|
ret.ktype = GetCardType(ret)
|
|
return ret //6 两组四张
|
|
}
|
|
}
|
|
|
|
if IsValueStraight(tmpCards) {
|
|
ret.min = tmpCards[0]
|
|
ret.max = tmpCards[len(tmpCards)-1]
|
|
ret.kind = Straight
|
|
ret.len = int32(len(tmpCards))
|
|
ret.same = 1
|
|
ret.ktype = GetCardType(ret)
|
|
return ret // 顺子
|
|
}
|
|
return ret
|
|
}
|
|
|
|
// 首出提示
|
|
func HeadHintOut(card []int32) [][]int32 { // 按照单 双 三张 四张 顺子 双四出~
|
|
|
|
return nil
|
|
}
|
|
|
|
// 压牌
|
|
func PressOut(beforeKind *KindOfCard, cards []int32, f bool) (retkind *KindOfCard) {
|
|
p := pt32m(cards)
|
|
var kds []*KindOfCard
|
|
switch beforeKind.kind {
|
|
case Single: //1 单张
|
|
retkind = GetSingle(cards, beforeKind, f)
|
|
if beforeKind.min == POKER_2 {
|
|
kds = findKindCommon(p, 4)
|
|
for _, kd := range kds {
|
|
if CompareCardKind(beforeKind, kd) {
|
|
retkind = kd
|
|
break
|
|
}
|
|
}
|
|
}
|
|
case Twin: //2 对子
|
|
kds = findKindCommon(p, 2)
|
|
if beforeKind.min == POKER_2 {
|
|
kds = findKindTwinFour(p, 4)
|
|
}
|
|
for _, kd := range kds {
|
|
if CompareCardKind(beforeKind, kd) {
|
|
retkind = kd
|
|
break
|
|
}
|
|
}
|
|
case Straight: //4 顺子
|
|
kds := findStraight(p, 1, beforeKind.num)
|
|
for _, kd := range kds {
|
|
if CompareCardKind(beforeKind, kd) {
|
|
retkind = kd
|
|
break
|
|
}
|
|
}
|
|
case Triple: //3 三张
|
|
kds := findKindCommon(p, 3)
|
|
for _, kd := range kds {
|
|
if CompareCardKind(beforeKind, kd) {
|
|
retkind = kd
|
|
break
|
|
}
|
|
}
|
|
case Four: //5 四张
|
|
kds := findKindCommon(p, 4)
|
|
for _, kd := range kds {
|
|
if CompareCardKind(beforeKind, kd) {
|
|
retkind = kd
|
|
break
|
|
}
|
|
}
|
|
case TwinFour: //6 两组四张
|
|
}
|
|
return
|
|
}
|
|
|
|
// CompareCardKind 对比
|
|
func CompareCardKind(beforeKind *KindOfCard, kind *KindOfCard) bool {
|
|
|
|
if beforeKind.kind == kind.kind && beforeKind.num == kind.num && beforeKind.kind != TwinFour {
|
|
|
|
return beforeKind.min < kind.min
|
|
}
|
|
|
|
if beforeKind.min == POKER_2 {
|
|
if beforeKind.kind == Single && kind.kind == Four {
|
|
return true
|
|
} else if beforeKind.kind == Twin && kind.kind == TwinFour {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// CompareCard 对比
|
|
func CompareCard(beforeKind *KindOfCard, cards []int32) bool { // cards 大 返回true
|
|
cnum := int32(len(cards))
|
|
tmpCards := []int32{}
|
|
for _, card := range cards {
|
|
|
|
tmpCards = append(tmpCards, int32(Value(card)))
|
|
}
|
|
sort.Sort(SortInt32(tmpCards))
|
|
switch beforeKind.kind {
|
|
case Single: //1 单张
|
|
if cnum == 1 {
|
|
if beforeKind.min < tmpCards[0] {
|
|
return true
|
|
}
|
|
} else if beforeKind.min == POKER_2 && IsFour(tmpCards) { // 能压一个2
|
|
return true
|
|
}
|
|
|
|
case Twin: //2 对子
|
|
if cnum == 2 {
|
|
if IsTwin(tmpCards) && beforeKind.min < tmpCards[0] {
|
|
return true
|
|
}
|
|
} else if beforeKind.min == POKER_2 && IsDouFour(tmpCards) { // 能压一对2
|
|
return true
|
|
}
|
|
case Straight: //4 顺子
|
|
//fmt.Println("IsValueStraight(tmpCards)", IsValueStraight(tmpCards), beforeKind.len, cnum, beforeKind.min, tmpCards[0])
|
|
if beforeKind.len == cnum && IsValueStraight(tmpCards) && (beforeKind.min < tmpCards[0]) {
|
|
return true
|
|
}
|
|
case Triple: //3 三张
|
|
if IsTriple(tmpCards) && (beforeKind.min < tmpCards[0]) {
|
|
return true
|
|
}
|
|
case Four: //5 四张
|
|
if IsFour(tmpCards) && (beforeKind.min < tmpCards[0]) {
|
|
return true
|
|
}
|
|
case TwinFour: //6 两组四张
|
|
}
|
|
return false
|
|
}
|
|
|
|
// RemoveCard 删除扑克
|
|
func RemoveCard(removePoker []int32, cardData *[]int32) bool {
|
|
|
|
deleteCount := 0
|
|
removeCount := len(removePoker)
|
|
pokerCount := len(*cardData)
|
|
tempPokerData := make([]int32, pokerCount)
|
|
if pokerCount > len(tempPokerData) {
|
|
return false
|
|
}
|
|
|
|
copy(tempPokerData[0:], (*cardData)[0:pokerCount])
|
|
|
|
for i := 0; i < removeCount; i++ {
|
|
for j := 0; j < pokerCount; j++ {
|
|
if removePoker[i] == tempPokerData[j] {
|
|
deleteCount++
|
|
// fmt.Printf("找到待删除扑克: %x\n", removePoker[i])
|
|
tempPokerData[j] = -1
|
|
break
|
|
}
|
|
}
|
|
}
|
|
if deleteCount != removeCount {
|
|
return false
|
|
}
|
|
|
|
//清理扑克
|
|
pos := 0
|
|
for i := 0; i < pokerCount; i++ {
|
|
if tempPokerData[i] != -1 {
|
|
(*cardData)[pos] = tempPokerData[i]
|
|
pos++
|
|
}
|
|
}
|
|
(*cardData) = (*cardData)[:pos] // 删除扑克 1244 delete 2 --> 144
|
|
return true
|
|
}
|
|
|
|
func GetCardType(kind *KindOfCard) int {
|
|
switch kind.same {
|
|
case 4:
|
|
// 四张
|
|
if kind.num != 8 {
|
|
// 双四张
|
|
return -1 // 不能首出
|
|
}
|
|
if kind.min > POKER_10 {
|
|
return 1
|
|
}
|
|
return 6
|
|
case 3:
|
|
// 三牌
|
|
if kind.min > POKER_10 {
|
|
return 1
|
|
}
|
|
return 4
|
|
case 2:
|
|
// 对牌
|
|
return 3
|
|
case 1:
|
|
|
|
if kind.num >= 3 {
|
|
// 单连
|
|
if kind.num > 5 {
|
|
return 8
|
|
}
|
|
if kind.min < POKER_7 && kind.min >= POKER_3 {
|
|
return 7
|
|
}
|
|
if kind.num == 3 && kind.min > POKER_10 { // 不先出
|
|
return 1
|
|
}
|
|
return 5
|
|
}
|
|
}
|
|
// 单牌
|
|
return 2
|
|
}
|
|
|
|
func MaxSingle(cpCards []int32, delCards []int32, f bool) (ret bool, retCards []int32) {
|
|
if DelOtherPOKER2(cpCards, delCards) || (f && len(delCards) == 1) {
|
|
for i := len(cpCards) - 1; i >= 0; i-- {
|
|
card := cpCards[i]
|
|
if card != InvalideCard {
|
|
retCards = append(retCards, card)
|
|
ret = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func GetSingle(cpCards []int32, kind *KindOfCard, f bool) (retkind *KindOfCard) {
|
|
var retCards []int32
|
|
if kind == nil || kind.num == 0 {
|
|
for _, card := range cpCards {
|
|
if card != InvalideCard {
|
|
retCards = append(retCards, card)
|
|
break
|
|
}
|
|
}
|
|
if ret, del := MaxSingle(cpCards, retCards, f); ret {
|
|
retCards = del
|
|
}
|
|
|
|
} else {
|
|
for _, card := range cpCards {
|
|
if card != InvalideCard && Value32(card) > kind.min {
|
|
retCards = append(retCards, card)
|
|
break
|
|
}
|
|
}
|
|
if ret, del := MaxSingle(cpCards, retCards, f); ret {
|
|
retCards = del
|
|
if Value32(retCards[0]) <= kind.min {
|
|
retCards = []int32{}
|
|
}
|
|
}
|
|
}
|
|
retkind = GetCardKind(retCards)
|
|
return
|
|
}
|
|
|
|
func findKindCommon(m map[int32]int32, n int32) (res []*KindOfCard) {
|
|
|
|
for i := int32(0); i <= POKER_2; i++ {
|
|
if m[i] >= n {
|
|
card := []int32{}
|
|
for num := int32(0); num < n; num++ {
|
|
card = append(card, i)
|
|
}
|
|
|
|
res = append(res, GetCardKind(card))
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 双四
|
|
func findKindTwinFour(m map[int32]int32, n int32) (res []*KindOfCard) {
|
|
card := []int32{}
|
|
k := 0
|
|
for i := int32(0); i <= POKER_2; i++ {
|
|
if m[i] >= n {
|
|
for num := int32(0); num < n; num++ {
|
|
card = append(card, i)
|
|
}
|
|
k++
|
|
}
|
|
if k == 2 {
|
|
res = append(res, GetCardKind(card))
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func haveStraightLine(m map[int32]int32, num int32, len int32, min int32) bool {
|
|
if min+len > POKER_2 { // 2不能带
|
|
return false
|
|
}
|
|
for i := min; i < min+len; i++ {
|
|
if m[i] < num {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// 连牌
|
|
func findStraight(m map[int32]int32, num int32, len int32) (res []*KindOfCard) {
|
|
|
|
max := 11 - len
|
|
min := int32(0)
|
|
if m[-2] > 0 {
|
|
min = -2
|
|
} else if m[-1] > 0 { // -1 ->2
|
|
min = -1
|
|
}
|
|
for ; min <= max; min++ {
|
|
if haveStraightLine(m, num, len, min) {
|
|
if min == -2 && len < 6 { // 没必要做连牌
|
|
continue
|
|
}
|
|
if min == -1 && len < 5 {
|
|
continue
|
|
}
|
|
card := []int32{}
|
|
for num := int32(0); num < len; num++ {
|
|
card = append(card, min+num)
|
|
}
|
|
res = append(res, GetCardKind(card))
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func allfindStraight(m map[int32]int32, num int32, len int32) (res []*KindOfCard) {
|
|
for ilen := len; ; ilen++ {
|
|
var flag bool // 默认false 单联判断成功就继续
|
|
max := 11 - ilen
|
|
min := int32(0)
|
|
|
|
if m[-2] > 0 {
|
|
min = -2
|
|
} else if m[-1] > 0 { // -1 ->2
|
|
min = -1
|
|
}
|
|
for ; min <= max; min++ {
|
|
if haveStraightLine(m, num, ilen, min) {
|
|
if min == -2 && len < 6 { // 没必要做连牌
|
|
continue
|
|
}
|
|
if min == -1 && len < 5 {
|
|
continue
|
|
}
|
|
card := []int32{}
|
|
for num := int32(0); num < ilen; num++ {
|
|
card = append(card, min+num)
|
|
}
|
|
res = append(res, GetCardKind(card))
|
|
flag = true
|
|
}
|
|
}
|
|
if !flag {
|
|
break
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 超时出牌 TODO
|
|
func TickOut(cards []int32, kind *KindOfCard, f bool) (delCards []int32) {
|
|
cpCards := append([]int32{}, cards...)
|
|
|
|
sort.Slice(cpCards, func(i, j int) bool {
|
|
v_i := Value(cpCards[i])
|
|
v_j := Value(cpCards[j])
|
|
c_i := Color(cpCards[i])
|
|
c_j := Color(cpCards[j])
|
|
if v_i > v_j {
|
|
return false
|
|
} else if v_i == v_j {
|
|
return c_i < c_j
|
|
}
|
|
return true
|
|
})
|
|
var retkind *KindOfCard
|
|
if kind == nil || kind.num == 0 {
|
|
retkind = GetSingle(cpCards, kind, f)
|
|
|
|
} else {
|
|
retkind = PressOut(kind, cpCards, f)
|
|
}
|
|
delCards = retkind.OutPokers(cpCards)
|
|
return
|
|
}
|
|
|
|
// 根据上家牌型是否需要额外延迟出牌时间(s)
|
|
func NeedExDelay(lastCards []int32) bool {
|
|
|
|
return false
|
|
}
|
|
|
|
// 计算输家输分数
|
|
func GetLoseScore(cards [HandCardNum]int32, baopei bool) (loseScore int32) {
|
|
|
|
//cpCards := []int32{}
|
|
num := int32(0)
|
|
flag := false
|
|
for _, card := range cards {
|
|
if card != InvalideCard {
|
|
if !flag && Value32(card) == POKER_2 {
|
|
flag = true
|
|
loseScore += Baopei2
|
|
}
|
|
//cpCards = append(cpCards, card)
|
|
num++
|
|
}
|
|
}
|
|
if num == HandCardNum {
|
|
loseScore += Treo
|
|
} else {
|
|
loseScore += num
|
|
}
|
|
if baopei { // 庄家赔付
|
|
loseScore -= Baopei2
|
|
}
|
|
|
|
return
|
|
}
|