game_sync/gamerule/tienlen/cardAi.go

3061 lines
92 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 tienlen
import (
"math"
tienlenApi "mongo.games.com/game/api3th/smart/tienlen"
"mongo.games.com/goserver/core/logger"
"sort"
)
// 新tienlenAI 获取牌型
func GetCardsType(myCards []int32, isYuLe bool) map[int]map[int32][]int32 {
cards := make([]int32, len(myCards))
copy(cards, myCards)
cardsTypeMap := make(map[int]map[int32][]int32)
//先找炸弹
bombMap := GetBomb(cards)
if len(bombMap) > 0 {
cardsTypeMap[Four_Bomb] = bombMap
}
cards = DelCards(cards, bombMap)
//找连对5连对>4连对>3连队>2连队
pair, pairMap := GetPair(cards)
//再找连对
pairStraightMap := GetConsecutivePairs(cards, pair)
if len(pairStraightMap) > 0 {
cardsTypeMap[Straight_Twin] = pairStraightMap
}
for i, pairStraight := range pairStraightMap {
if len(pairStraight)/2 <= 2 {
//先删除2连对 去找顺子和三条
delete(cardsTypeMap[Straight_Twin], i)
}
}
//先排除2连对
//排除3连对以上的连对
for _, pairStraight := range pairStraightMap {
if isYuLe {
//娱乐模式 如果3连对以上则删除3连对以上的连对
if len(pairStraight)/2 >= 3 {
delMap := make(map[int32][]int32)
delMap[int32(len(delMap)+1)] = pairStraight
cards = DelCards(cards, delMap)
}
} else {
delMap := make(map[int32][]int32)
delMap[int32(len(delMap)+1)] = pairStraight
cards = DelCards(cards, delMap)
}
}
//娱乐模式先找三张
//连队和三条有冲突 既能组成连对 也是三条 这个时候要判断是不是娱乐模式 娱乐模式保留三条拆连对,不是娱乐模式保留连对 拆三条
if isYuLe {
threeMap := GetThreeOfkind(cards)
if len(threeMap) > 0 {
cardsTypeMap[Triple] = threeMap
}
//娱乐模式三张不拆 删除掉三张的牌找顺子
cards = DelCards(cards, threeMap)
//判断获取到的三条在不在连对中
for _, three := range threeMap {
for i, pairStraight := range pairStraightMap {
if len(pairStraight)/2 >= 3 {
continue
}
for _, data := range pairStraight {
if Value(data) == Value(three[0]) {
//删除连对
delete(cardsTypeMap[Straight_Twin], i)
break
}
}
}
}
cards = DelCards(cards, threeMap)
}
//找顺子(同花顺>杂色顺子)
straightMap := findStraights(cards)
if len(straightMap) > 0 {
cardsTypeMap[Straight] = straightMap
cards = DelCards(cards, straightMap)
}
//找三张
if !isYuLe {
threeMap := GetThreeOfkind(cards)
if len(threeMap) > 0 {
cardsTypeMap[Triple] = threeMap
}
//不是娱乐模式删除三条
for i, three := range threeMap {
for _, pairStraight := range pairStraightMap {
if len(pairStraight)/2 >= 3 {
continue
}
for _, data := range pairStraight {
if Value(data) == Value(three[0]) {
//删除连对
delete(cardsTypeMap[Triple], i)
break
}
}
}
}
cards = DelCards(cards, threeMap)
}
//找三顺
var arr []int32
for _, three := range cardsTypeMap[Triple] {
for _, value := range three {
arr = append(arr, value)
}
}
StraightTripleMap := GetStraightTriple(arr)
if len(StraightTripleMap) > 0 {
cardsTypeMap[Straight_Triple] = StraightTripleMap
}
//剩余的牌再找对子
pair, pairMap = GetPair(cards)
//再找连队
pairStraightMap = GetConsecutivePairs(cards, pair)
for _, pairStraight := range pairStraightMap {
cardsTypeMap[Straight_Twin][int32(len(cardsTypeMap[Straight_Twin])+1)] = pairStraight
}
cards = DelCards(cards, pairStraightMap)
pair, pairMap = GetPair(cards)
if len(pairMap) > 0 {
cardsTypeMap[Twin] = pairMap
}
//找单张 移除上面所有牌型的牌,剩余的牌就是单张
cards = DelCards(cards, pairMap)
if len(cards) > 0 {
cardsTypeMap[Single] = make(map[int32][]int32)
for i := 0; i < len(cards); i++ {
cardsTypeMap[Single][int32(i)] = []int32{cards[i]}
}
}
return cardsTypeMap
}
// 找炸弹
func GetBomb(cards []int32) map[int32][]int32 {
cardCount := make(map[int32]int)
cardMap := make(map[int32][]int32)
// 统计每张牌的数量
for _, card := range cards {
cardCount[int32(Value(card))]++
cardMap[int32(Value(card))] = append(cardMap[int32(Value(card))], card)
}
// 查找炸弹组合
bombMap := make(map[int32][]int32)
for card, count := range cardCount {
if count == 4 {
bombMap[card] = cardMap[card]
}
}
return bombMap
}
// 找连对
func GetConsecutivePairs(cards, pair []int32) map[int32][]int32 {
// 对切片进行排序
sort.Slice(pair, func(i, j int) bool {
return pair[i] < pair[j]
})
// 存储顺子的 map
straightMap := make(map[int32][]int32)
for i := 0; i < len(pair); i++ {
// 如果当前数字与前一个数字相同,则跳过
if i > 0 && pair[i] == pair[i-1] {
continue
}
// 初始值为当前数字
current := pair[i]
straight := []int32{current}
// 检查是否连续递增
num := i
for j := i + 1; j < len(pair); j++ {
if pair[j] == current+1 && pair[j] < 12 {
straight = append(straight, pair[j])
current = pair[j]
num = j
}
}
i = num
if len(straight) >= 2 {
straightMap[int32(len(straightMap)+1)] = straight
}
}
//找原牌
cardsMap := make(map[int32][]int32)
for i, v := range straightMap {
for _, v1 := range v {
num := 0
for _, v2 := range cards {
if v1 == int32(Value(v2)) {
num += 1
cardsMap[i] = append(cardsMap[i], v2)
if num == 2 {
break
}
}
}
}
}
return cardsMap
}
// 找顺子
func GetAllStraight(cards []int32, length int) map[int32][]int32 {
// 对切片进行排序
sort.Slice(cards, func(i, j int) bool {
return cards[i] < cards[j]
})
// 存储顺子的 map
straightMap := make(map[int32][]int32)
for i := 0; i < len(cards); i++ {
// 如果当前数字与前一个数字相同,则跳过
if i > 0 && Value(cards[i]) == Value(cards[i-1]) {
continue
}
// 初始值为当前数字
current := cards[i]
straight := []int32{current}
// 检查是否连续递增
for j := i + 1; j < len(cards); j++ {
if Value(cards[j]) == Value(current)+1 && Value(cards[j]) < 12 {
straight = append(straight, cards[j])
current = cards[j]
if len(straight) >= length {
straightMap[int32(len(straightMap)+1)] = straight
}
}
}
}
return straightMap
}
// 1.先找到所有长度为3的顺子
// 2.剩余的牌再和已经取出来的顺子组合,知道组合成更大的牌,
// 3.合并顺子
// 4.最后再确定单顺,剩余的牌和三条连对进行组合 看看能不能组成新的顺子娱乐版不拆三条拆连队只能拆长度等于2的连对
// 找出所有长度为3的顺子
func findStraights(cards []int32) map[int32][]int32 {
straights := [][]int32{}
length := len(cards)
if length < 3 {
return make(map[int32][]int32)
}
sort.Slice(cards, func(i, j int) bool {
return Value(cards[i]) < Value(cards[j])
})
for i := 0; i <= length-3; {
if Value(cards[i]) == Value(cards[i+1]) || Value(cards[i]) >= 10 {
i++
continue
}
if i+2 < length {
arr := []int32{}
value := cards[i]
arr = append(arr, cards[i])
for j := i + 1; j <= length-1; j++ {
if Value(cards[j]) == Value(value) || Value(cards[j]) >= 12 {
continue
}
arr = append(arr, cards[j])
value = cards[j]
if len(arr) == 3 {
break
}
}
if isStraight(arr) {
straights = append(straights, arr)
// 从牌组中移除当前顺子的牌
cards = removeCards(cards, arr)
length = len(cards) // 更新牌组长度
} else {
i++
}
} else {
break
}
}
sort.Slice(straights, func(i, j int) bool {
return Value(straights[i][0]) < Value(straights[j][0])
})
//2.剩余的牌再和已经取出来的顺子组合,知道组合成更大的牌,
removeCard := []int32{}
for _, card := range cards {
for i, straight := range straights {
if Value(card) == Value(straight[len(straight)-1]+1) && Value(card) < 12 {
straight = append(straight, card)
removeCard = append(removeCard, card)
straights[i] = straight
break
}
}
}
cards = removeCards(cards, removeCard)
//3.合并顺子
for i := 0; i < len(straights)-1; i++ {
if Value(straights[i][len(straights[i])-1]) == Value(straights[i+1][0])-1 {
straights[i] = append(straights[i], straights[i+1]...)
straights = append(straights[:i+1], straights[i+2:]...)
i -= 1
}
}
//转正map
straightsMap := make(map[int32][]int32)
for i, straight := range straights {
straightsMap[int32(i)] = straight
}
return straightsMap
}
// 暂时不做 现在的找牌顺序可以兼容这种 拆三条 二连对组顺子
func TwoFindStraights(cards []int32, isYuLe bool, cardsType map[int]map[int32][]int32, straights [][]int32) {
//4.剩余的牌和三条连对进行组合 看看能不能组成新的顺子娱乐版不拆三条拆连队只能拆长度等于2的连对
//找相邻的两张牌
twoCards := [][]int32{}
for i := 0; i < len(cards)-1; i++ {
if cards[i] == cards[i+1]-1 || cards[i] == cards[i+1]-2 {
twoCards = append(twoCards, []int32{cards[i], cards[i+1]})
i += 1
}
}
if len(twoCards) > 0 {
indexesToRemove := []int{}
for _, twoCard := range twoCards {
value := twoCard
//添加三条 和连对的牌进去再找顺子
if !isYuLe {
threeCards := cardsType[Triple]
for i, three := range threeCards {
//logger.Logger.Tracef("开始拆三条组顺子 three = %d \n", three)
value = append(value, three[0])
sort.Slice(value, func(i, j int) bool {
return value[i] < value[j]
})
//判断是不是顺子
if isStraight(value) {
//找到顺子了 移除三张
cards = removeCards(cards, value)
delete(cardsType[Triple], i)
straights = append(straights, value)
indexesToRemove = append(indexesToRemove, int(i))
cards = append(cards, three[1], three[2])
break
}
}
}
}
// 根据索引从切片中删除元素
for i := len(indexesToRemove) - 1; i >= 0; i-- {
twoCards = append(twoCards[:indexesToRemove[i]], twoCards[indexesToRemove[i]+1:]...)
}
//添加二连对组顺子
//最后在合并一下顺子
for i := 0; i < len(straights)-1; i++ {
if straights[i][len(straights[i])-1] == straights[i+1][0]-1 {
straights[i] = append(straights[i], straights[i+1]...)
straights = append(straights[:i+1], straights[i+2:]...)
i -= 1
}
}
}
}
func removeCards(cards []int32, toRemove []int32) []int32 {
newCards := []int32{}
removed := make([]bool, len(cards))
for _, card := range toRemove {
for i, c := range cards {
if c == card && !removed[i] {
removed[i] = true
break
}
}
}
for i, card := range cards {
if !removed[i] {
newCards = append(newCards, card)
}
}
return newCards
}
func isStraight(cards []int32) bool {
if len(cards) < 3 {
return false
}
return Value(cards[1])-Value(cards[0]) == 1 && Value(cards[2])-Value(cards[1]) == 1
}
// 找三张
func GetThreeOfkind(cards []int32) map[int32][]int32 {
cardCount := make(map[int32]int)
var three []int32
cardMap := make(map[int32][]int32)
// 统计每张牌的数量
for _, card := range cards {
cardCount[int32(Value(card))]++
cardMap[int32(Value(card))] = append(cardMap[int32(Value(card))], card)
}
// 查找炸弹组合
threeMap := make(map[int32][]int32)
for card, count := range cardCount {
if count >= 3 {
three = append(three, card)
threeMap[card] = cardMap[card]
}
}
return threeMap
}
// 找三顺
func GetStraightTriple(cards []int32) map[int32][]int32 {
sort.Slice(cards, func(i, j int) bool {
if Value(cards[i]) == Value(cards[j]) {
return cards[i] < cards[j]
}
return Value(cards[i]) < Value(cards[j])
})
result := make(map[int32][]int32)
for i := 0; i < len(cards)-3; {
num := 1
for j := i + 3; j < len(cards); {
if Value(cards[i]) == Value(cards[j])-num && Value(cards[j]) < 12 {
num += 1
}
j += 3
}
if num >= 2 {
arr := cards[i : i+num*3]
result[int32(Value(arr[len(arr)-1]))] = arr
}
i += 3
}
return result
}
// 找对子
func GetPair(cards []int32) ([]int32, map[int32][]int32) {
cardCount := make(map[int32]int)
cardMap := make(map[int32][]int32)
// 统计每张牌的数量
for _, card := range cards {
cardCount[int32(Value(card))]++
cardMap[int32(Value(card))] = append(cardMap[int32(Value(card))], card)
}
// 查找对子组合
pairMap := make(map[int32][]int32)
var pair []int32
for card, count := range cardCount {
if count >= 2 {
//logger.Logger.Tracef("\n找到所有的对子%d \n", card)
pair = append(pair, card)
pairMap[card] = cardMap[card]
}
}
return pair, pairMap
}
// 牌型转换
func CardsChange(cards []int32) []int {
//map key-相同牌数量 value-key:
var cardChange []int
for _, card := range cards {
cardChange = append(cardChange, Value(card))
}
sort.Ints(cardChange)
return cardChange
}
// 删除牌
func DelCards(cards []int32, delCards map[int32][]int32) []int32 {
// 创建一个新的切片,用于存储不需要删除的元素
newCards := make([]int32, 0, len(cards))
// 遍历 cards 中的元素
for _, card := range cards {
// 检查当前元素是否需要删除
shouldDelete := false
for _, delCard := range delCards {
for _, del := range delCard {
if card == del {
shouldDelete = true
break
}
}
}
// 如果不需要删除,则将元素添加到新的切片中
if !shouldDelete {
newCards = append(newCards, card)
}
}
return newCards
}
// 获取牌型分计算
func GetCardTypeScore(cardsType map[int]map[int32][]int32, isYuLe bool, cards []int32) (int, int) {
//计算每张牌的牌值
cardValues := []int{
-0, -100, -80, -60, -40, -20, 0, 20, 50, 90, 140, 200, 300,
-115, -95, -75, -55, -35, -15, 5, 25, 55, 95, 145, 205, 325,
-110, -90, -70, -50, -30, -10, 10, 30, 60, 100, 150, 210, 350,
-105, -85, -65, -45, -25, -5, 15, 35, 65, 105, 155, 215, 400,
}
//logger.Logger.Trace("计算牌型分 cardsType = ", cardsType)
//计算牌型分值
var score int
//炸弹
if len(cardsType[Four_Bomb]) > 0 {
if isYuLe {
score += len(cardsType[Four_Bomb]) * 1000
} else {
score += len(cardsType[Four_Bomb]) * 700
}
}
//连队
if len(cardsType[Straight_Twin]) > 0 {
for _, twin := range cardsType[Straight_Twin] {
switch len(twin) / 2 {
case 5:
score += 500
case 4:
score += 400
case 3:
score += 300
case 2:
score += 200
}
}
}
//顺子
if len(cardsType[Straight]) > 0 {
for _, straight := range cardsType[Straight] {
score += len(straight)*100 + (len(straight)-3)*(cardValues[straight[len(straight)-1]]/3)
}
}
//三张
if len(cardsType[Triple]) > 0 {
for _, triples := range cardsType[Triple] {
if Value(triples[0]) < 7 {
score += int(math.Abs(float64(250 + cardValues[triples[2]])))
} else {
score += cardValues[triples[0]] + cardValues[triples[1]] + cardValues[triples[2]]
}
}
if isYuLe {
score += len(cardsType[Triple]) * 300
}
}
//两对
if len(cardsType[Twin]) > 0 {
for _, twins := range cardsType[Twin] {
if Value(twins[0]) < 7 {
score += cardValues[twins[1]] / 2
} else {
score += cardValues[twins[0]] + cardValues[twins[1]]
}
}
}
//删除三连对以上且三连对小于10的牌
copyCards := make([]int32, len(cards))
copy(copyCards, cards)
copyCards = DelCards(copyCards, cardsType[Four_Bomb])
for _, straightTwin := range cardsType[Straight_Twin] {
delMap := make(map[int32][]int32)
if len(straightTwin)/2 >= 3 && Value(straightTwin[len(straightTwin)-1]) < 10 {
delMap[int32(len(delMap)+1)] = straightTwin
copyCards = DelCards(copyCards, delMap)
}
}
for _, card := range copyCards {
score += cardValues[card]
}
handCardnum := len(cardsType[Four_Bomb]) + len(cardsType[Straight_Twin]) + len(cardsType[Straight]) + len(cardsType[Triple]) + len(cardsType[Twin]) + len(cardsType[Single])
if isYuLe {
handCardnum -= (len(cardsType[Triple]) * 2)
}
if handCardnum <= 1 {
handCardnum = 1
if isYuLe && handCardnum == 1 {
if len(cardsType[Triple]) > 0 {
if len(cards) > 5 {
handCardnum = 2
}
}
}
}
if Have6StraightTwin(cards) ||
Have12Straight(cards) ||
Have2FourBomb(cards) {
return 9999, 1
}
return score - (handCardnum-5)*150, handCardnum
}
// 压牌 isWin-是否胜利
func GetPressCards(cards, lastCards []int32, data *tienlenApi.PredictRequest, pos int32) []int32 {
logger.Logger.Tracef("---------------压牌开始-------------------")
sort.Slice(cards, func(i, j int) bool {
if Value(cards[i]) == Value(cards[j]) {
return cards[i] < cards[j]
}
return Value(cards[i]) < Value(cards[j])
})
isWin := data.IsWin
//测试代码
isWin = true
logger.Logger.Trace("压牌 调控输赢 isWin = ", isWin)
outCards := []int32{}
//压牌测试代码
// cards = []int32{6, 19, 2, 28, 41, 43, 12, 25}
// lastCards = []int32{14, 27}
// pos = 0
// data.Cards_left_2 = []int32{45, 32}
// data.Cards_left_3 = nil
// data.Cards_left_1 = nil
// data.Last_pos = 2
lastPos := data.Last_pos //上家出牌人的位置
logger.Logger.Tracef(" 上家出牌人的位置%d,出的牌:%v\n", lastPos, lastCards)
isYuLe := data.IsTienLenYule
isEnd := data.IsEnd
winSnids := data.WinSnids
logger.Logger.Trace("当前模式是否是打到底%v\n当前获胜玩家%v\n", isEnd, winSnids)
//获取牌型
cardsTypeMap := GetCardsType(cards, isYuLe)
score, handCardnum := GetCardTypeScore(cardsTypeMap, isYuLe, cards)
logger.Logger.Tracef("压牌 获取牌型:%v\n,分值:%d\n手牌%d、n,我的位置:%d\n", cardsTypeMap, score, handCardnum, pos)
//获取出牌人的 手数
otherCards := getOtherPlayerCards(pos, lastPos, data)
otherCardsTypeMap := GetCardsType(otherCards, isYuLe)
lastScore, lastHandCardnum := GetCardTypeScore(otherCardsTypeMap, isYuLe, otherCards)
logger.Logger.Tracef("压牌,获取出牌玩家的剩余牌的牌型:", otherCardsTypeMap, "分值:", lastScore, "手牌:", lastHandCardnum, "\n")
//获取下一家的位置和剩余的牌
nextPos, nextCards := GetNextPos(pos, data)
logger.Logger.Tracef("我的位置:%d\n,获取下家牌和位置nextPos = %d\n,nextCards := %v\n", pos, nextPos, nextCards)
isRule, ruleType := RulePopEnable_yl(lastCards)
if isRule {
switch ruleType {
case Single:
//单张
cardsMap := cardsTypeMap[Single]
//转成数组
singleArr := []int32{}
for _, single := range cardsMap {
singleArr = append(singleArr, single[0])
}
if isEnd && !isYuLe {
sort.Slice(singleArr, func(i, j int) bool {
if Value(singleArr[i]) == Value(singleArr[j]) {
return singleArr[i] < singleArr[j]
}
return Value(singleArr[i]) < Value(singleArr[j])
})
}
//如果我的下一家剩余一张牌 出比他大的牌
if len(singleArr) > 0 {
if len(singleArr) == 2 && len(cards) == 2 {
for _, mycard := range singleArr {
if getMaxCardTypeNum(Single, []int32{mycard}, pos, data) {
outCards = []int32{mycard}
}
}
} else {
for _, card := range singleArr {
if Value(card) >= Value(lastCards[0]) {
if Value(card) == Value(lastCards[0]) {
if Color(card) < Color(lastCards[0]) {
continue
}
}
if len(nextCards) == 1 {
if Value(card) >= Value(nextCards[0]) {
if Value(card) == Value(nextCards[0]) {
if Color(card) > Color(nextCards[0]) {
outCards = []int32{card}
break
}
} else {
outCards = []int32{card}
break
}
}
} else {
outCards = []int32{card}
break
}
}
}
}
} else {
//找顺子交集 返回值[][]int32
result := FindIntersection(cardsTypeMap[Straight])
if len(result) > 0 {
sort.Slice(cards, func(i, j int) bool {
if Value(cards[i]) == Value(cards[j]) {
return cards[i] < cards[j]
}
return Value(cards[i]) < Value(cards[j])
})
for _, arr := range result {
for _, card := range arr {
if Value(card) >= Value(lastCards[0]) {
if Value(card) == Value(lastCards[0]) {
if Color(card) < Color(lastCards[0]) {
continue
}
}
if len(nextCards) == 1 {
if Value(card) >= Value(nextCards[0]) {
if Value(card) == Value(nextCards[0]) {
if Color(card) > Color(nextCards[0]) {
outCards = []int32{card}
break
//return card
}
} else {
outCards = []int32{card}
break
}
}
} else {
outCards = []int32{card}
break
}
}
}
if len(outCards) > 0 {
break
}
}
}
}
if isWin {
//拆牌 先找顺子的交集 拆对子 拆2 拆长度大于3的顺子 最后找大于这张出牌的牌除了炸弹 出牌这家只剩一首牌了
if len(outCards) == 0 && len(cardsTypeMap[Twin]) > 0 {
logger.Logger.Trace("拆对子")
twinMap := cardsTypeMap[Twin]
//拆小于2的对子
for _, card := range twinMap {
if Value(card[0]) == 12 {
//排除掉对2
continue
}
//先拆小于2的对子
if Value(card[0]) >= Value(lastCards[0]) {
if Value(card[0]) == Value(lastCards[0]) {
if Color(card[0]) < Color(lastCards[0]) {
continue
}
}
if len(nextCards) == 1 {
if Value(card[0]) >= Value(nextCards[0]) {
if Value(card[0]) == Value(nextCards[0]) {
if Color(card[0]) > Color(nextCards[0]) {
outCards = []int32{card[0]}
break
}
} else {
outCards = []int32{card[0]}
break
}
}
} else {
//玩家出完这张牌 还剩一张 剩余的牌比我现在出的牌大
if len(otherCards) == 1 && Value(otherCards[0]) >= Value(card[0]) {
continue
}
outCards = []int32{card[0]}
break
}
}
}
//判断一下下一家剩1张牌比我的大的情况
if len(outCards) > 0 {
break
}
}
//直接拆2上
if len(outCards) == 0 &&
(lastHandCardnum <= 4 || handCardnum <= 3 ||
(len(nextCards) == 1 && Value(nextCards[0]) >= Value(lastCards[0]))) {
for _, card := range cards {
if Value(card) == 12 && Value(card) >= Value(lastCards[0]) {
if Value(card) == Value(lastCards[0]) {
if Color(card) > Color(lastCards[0]) {
outCards = []int32{card}
break
} else {
continue
}
} else {
outCards = []int32{card}
break
}
}
}
if len(outCards) > 0 && len(otherCards) == 1 && Value(otherCards[0]) >= Value(outCards[0]) {
if Value(outCards[0]) == Value(otherCards[0]) {
if Color(outCards[0]) < Color(otherCards[0]) {
if Value(cards[len(cards)-1]) >= Value(lastCards[0]) {
outCards = []int32{cards[len(cards)-1]}
}
}
} else {
if Value(cards[len(cards)-1]) >= Value(lastCards[0]) {
outCards = []int32{cards[len(cards)-1]}
}
}
}
}
//拆连对 map[int32][]int32
if len(outCards) == 0 && len(cardsTypeMap[Straight_Twin]) > 0 {
for _, straightTwin := range cardsTypeMap[Straight_Twin] {
if len(straightTwin)/2 == 2 || lastHandCardnum == 1 {
for _, twin := range straightTwin {
if Value(twin) > Value(lastCards[0]) {
outCards = []int32{twin}
break
}
}
if len(outCards) > 0 {
break
}
}
}
}
if !isYuLe {
//拆三条
if len(outCards) == 0 && len(cardsTypeMap[Triple]) > 0 {
tripleMap := cardsTypeMap[Triple]
for _, card := range tripleMap {
if Value(card[0]) >= Value(lastCards[0]) {
if Value(card[0]) == Value(lastCards[0]) {
if Color(card[0]) < Color(lastCards[0]) {
continue
}
}
if len(nextCards) == 1 {
if Value(card[0]) >= Value(nextCards[0]) {
if Value(card[0]) == Value(nextCards[0]) {
if Color(card[0]) > Color(nextCards[0]) {
outCards = []int32{card[0]}
break
}
} else {
outCards = []int32{card[0]}
break
}
}
} else {
outCards = []int32{card[0]}
break
}
}
}
}
}
//拆长度>3的顺子
if len(outCards) == 0 && len(cardsTypeMap[Straight]) > 0 {
straightMap := cardsTypeMap[Straight]
for _, card := range straightMap {
if len(card) <= 3 && lastHandCardnum != 1 {
continue
}
if Value(card[len(card)-1]) >= Value(lastCards[0]) {
if Value(card[0]) == Value(lastCards[0]) {
if Color(card[0]) < Color(lastCards[0]) {
continue
}
}
if len(nextCards) == 1 {
if Value(card[0]) >= Value(nextCards[0]) {
if Value(card[0]) == Value(nextCards[0]) {
if Color(card[0]) > Color(nextCards[0]) {
outCards = []int32{card[len(card)-1]}
break
}
} else {
outCards = []int32{card[len(card)-1]}
break
}
}
} else {
outCards = []int32{card[len(card)-1]}
break
}
}
}
}
}
if len(outCards) == 0 && Value(lastCards[0]) == 12 {
//找三连对 >四连对 >五连对 > 炸弹
straightTwinMap := cardsTypeMap[Straight_Twin]
//找最小长度的key
if len(straightTwinMap) > 0 {
for _, straightTwin := range straightTwinMap {
if len(straightTwin)/2 >= 3 {
outCards = straightTwin
logger.Logger.Trace("-----------------单张压牌 找到连对!", outCards)
break
//return straightTwin
}
}
}
//找炸弹
if !isYuLe {
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 && Value(lastCards[0]) == 12 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
}
if isYuLe {
//找炸弹
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 && (lastHandCardnum <= 2 || handCardnum <= 2) {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
if len(outCards) > 0 {
if Value(lastCards[0]) == 12 && Value(outCards[0]) == 12 && lastHandCardnum != 1 {
//如果出牌玩家剩余手数大于2 或者我的剩余手数小于等于3
//存在一种情况 上家剩余1张牌 其他人出单张 上家不要 这个时候我执行了这个判断 没有出2去接牌 && 我的上家单张数量>=2 ||上家剩余1张牌了 我要跑牌了
_, myLastCards := GetLastPos(pos, data)
if ((lastHandCardnum > 2 && len(otherCardsTypeMap[Single]) > 2) || (handCardnum > 3 && len(cardsTypeMap[Single]) >= 2)) && len(myLastCards) >= 2 {
if lastHandCardnum > 3 {
logger.Logger.Tracef("上家出2剩余的手数%d,我的手数:%d\n让一手", lastHandCardnum, handCardnum)
outCards = []int32{}
}
}
}
}
if len(outCards) == 0 {
if len(nextCards) == 1 && Value(lastCards[0]) < Value(nextCards[0]) {
if Value(cards[len(cards)-1]) >= Value(nextCards[0]) {
outCards = []int32{cards[len(cards)-1]}
}
}
}
//强压
if len(outCards) == 0 && (len(lastCards) == 1 || len(nextCards) == 1) {
if Value(cards[len(cards)-1]) >= Value(lastCards[0]) {
outCards = []int32{cards[len(cards)-1]}
}
}
//打到底 最后一首牌判断
if len(otherCards) == 1 && (!isYuLe && isEnd) && (winSnids == nil || len(winSnids) == 0) && len(outCards) != 0 && nextPos != lastPos {
if Value(outCards[0]) == Value(cards[len(cards)-1]) && handCardnum > 2 {
if Value(outCards[0]) <= Value(otherCards[0]) {
if Value(outCards[0]) == Value(otherCards[0]) {
if Color(outCards[0]) < Color(otherCards[0]) {
logger.Logger.Tracef("判断我的最大牌小于上家剩余的牌,不出!")
outCards = []int32{}
}
} else {
logger.Logger.Trace("打到底最后一手牌牌,让一手!")
outCards = []int32{}
}
}
}
}
if isEnd && len(otherCards) == 0 && len(outCards) > 0 {
if len(nextCards) == 1 {
//在这加一道防线
if Value(outCards[0]) < Value(nextCards[0]) {
//出最大牌
if Value(cards[len(cards)-1]) >= Value(lastCards[0]) && Value(cards[len(cards)-1]) >= Value(nextCards[0]) {
outCards = []int32{cards[len(cards)-1]}
}
}
}
}
if len(outCards) == 0 && len(lastCards) == 1 && nextPos == lastPos {
//出最大的牌
if Value(cards[len(cards)-1]) >= Value(lastCards[0]) {
outCards = []int32{cards[len(cards)-1]}
}
}
//打到底 出牌人打完了
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Single) {
logger.Logger.Trace("出牌人打完牌了,我过一手!!!!", lastCards)
outCards = []int32{}
}
logger.Logger.Tracef("--------------单张压牌完毕,出的牌:", outCards)
return outCards
case Twin:
//对子
cardsMap := cardsTypeMap[Twin]
if len(cardsMap) > 0 {
for _, card := range cardsMap {
if lastHandCardnum == 1 && len(otherCards) == 2 && Value(otherCards[len(otherCards)-1]) >= Value(card[1]) {
if Value(otherCards[len(otherCards)-1]) == Value(card[1]) {
if Color(otherCards[len(otherCards)-1]) > Color(card[1]) {
continue
}
} else {
continue
}
}
if Value(card[1]) >= Value(lastCards[1]) {
if Value(card[1]) == 12 {
//判断能不能直接出对2
if handCardnum > 3 && lastHandCardnum > 3 {
continue
}
}
if Value(card[1]) == Value(lastCards[1]) {
//判断花色
if Color(card[1]) > Color(lastCards[1]) {
outCards = card
break
}
} else {
outCards = card
break
}
}
}
//再找一遍
if len(outCards) == 0 {
for _, card := range cardsMap {
if Value(card[1]) >= Value(lastCards[1]) {
if Value(card[1]) == 12 {
//判断能不能直接出对2
if handCardnum > 3 && lastHandCardnum > 3 {
continue
}
}
if Value(card[1]) == Value(lastCards[1]) {
//判断花色
if Color(card[1]) > Color(lastCards[1]) {
outCards = card
break
}
} else {
outCards = card
break
}
}
}
}
}
logger.Logger.Trace("找到对子-------------------outCards =", outCards)
//拆连对
if isWin {
straightTwinMap := cardsTypeMap[Straight_Twin]
if len(outCards) == 0 {
if Value(lastCards[0]) == 12 {
if len(straightTwinMap) > 0 {
for _, straightTwin := range straightTwinMap {
if len(straightTwin)/2 >= 4 {
outCards = straightTwin
break
}
}
}
} else {
//拆连对
if len(straightTwinMap) > 0 {
for _, straightTwin := range straightTwinMap {
if len(straightTwin)/2 >= 2 {
//判断第一个和最后一位
if Value(straightTwin[0]) >= Value(lastCards[0]) {
if Color(straightTwin[1]) > Color(lastCards[1]) {
outCards = []int32{straightTwin[0], straightTwin[1]}
break
}
} else {
//判断最后一位
if Value(straightTwin[3]) >= Value(lastCards[0]) {
if Color(straightTwin[3]) > Color(lastCards[1]) {
outCards = []int32{straightTwin[2], straightTwin[3]}
break
}
}
}
}
}
}
}
}
//拆三条
//找最大的三条拆
if !isYuLe {
if len(outCards) == 0 && len(cardsTypeMap[Triple]) > 0 {
for _, triple := range cardsTypeMap[Triple] {
if Value(triple[0]) > Value(lastCards[0]) {
outCards = []int32{triple[0], triple[1]}
logger.Logger.Trace("拆三条压对子 outCards = ", outCards)
break
}
}
}
} else {
if len(outCards) == 0 && len(cardsTypeMap[Triple]) > 0 && (lastHandCardnum <= 2 || handCardnum <= 3) {
for _, triple := range cardsTypeMap[Triple] {
if Value(triple[0]) > Value(lastCards[0]) {
outCards = []int32{triple[0], triple[1]}
logger.Logger.Trace("拆三条压对子 outCards = ", outCards)
break
}
}
}
}
}
//找炸弹
if isYuLe {
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 && (lastHandCardnum <= 2 || handCardnum <= 2) {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
} else {
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 && Value(lastCards[0]) == 12 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
if len(outCards) > 0 {
if Value(lastCards[0]) == 12 && Value(outCards[0]) == 12 {
//如果出牌玩家剩余手数大于2 或者我的剩余手数小于等于3
if lastHandCardnum > 3 && (len(otherCardsTypeMap[Twin]) > 2 || len(otherCardsTypeMap[Single]) > 2) || (handCardnum > 3 && len(cardsTypeMap[Single]) > 2) {
if lastHandCardnum > 1 {
logger.Logger.Tracef("上家出2剩余的手数%d,我的手数:%d\n让一手", lastHandCardnum, handCardnum)
outCards = []int32{}
}
}
}
}
if len(outCards) == 0 && lastHandCardnum <= 2 {
//重组对子 找大对子
_, pairMap := GetPair(cards)
if len(pairMap) > 0 {
maxkey := int32(-1)
for key, pairs := range pairMap {
if Value(pairs[0]) >= Value(lastCards[0]) {
if key > maxkey {
maxkey = key
}
}
}
if maxkey != -1 {
outCards = append(outCards, pairMap[maxkey][0], pairMap[maxkey][1])
}
}
}
if len(otherCards) == 2 && lastHandCardnum == 1 && (!isYuLe && isEnd) && (winSnids == nil || len(winSnids) == 0) && len(outCards) != 0 && nextPos != lastPos {
if Value(outCards[0]) == Value(cards[len(cards)-1]) && handCardnum > 2 {
if Value(outCards[0]) <= Value(otherCards[0]) {
if Value(outCards[0]) == Value(otherCards[0]) {
if Color(outCards[0]) < Color(otherCards[0]) {
outCards = []int32{}
}
} else {
outCards = []int32{}
}
}
}
}
//打到底 出牌人打完了
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Twin) {
outCards = []int32{}
}
logger.Logger.Trace("--------------压牌完毕,出的牌:", outCards)
return outCards
case Straight:
//顺子
cardsMap := cardsTypeMap[Straight]
//获取顺子长度
for _, card := range cardsMap {
if len(card) == len(lastCards) {
if Value(card[len(card)-1]) >= Value(lastCards[len(lastCards)-1]) {
if Value(card[len(card)-1]) == Value(lastCards[len(lastCards)-1]) {
//比较花色
if Color(card[len(card)-1]) > Color(lastCards[len(lastCards)-1]) {
outCards = card
break
//return card
}
} else {
outCards = card
break
//return card
}
}
} else if len(card) > len(lastCards) && Value(card[len(card)-1]) >= Value(lastCards[len(lastCards)-1]) && (lastHandCardnum <= 2 || isEnd) {
//拆顺子
if Value(card[len(card)-1]) == Value(lastCards[len(lastCards)-1]) {
//比较花色
if Color(card[len(card)-1]) < Color(lastCards[len(lastCards)-1]) {
//截取
//return []int32{}
}
}
outCards = card[len(card)-len(lastCards):]
logger.Logger.Tracef("拆顺子 outCards = %d\n,lastCard = %d\n", outCards, lastCards)
}
}
//
if len(outCards) == 0 && lastHandCardnum <= 2 {
//找顺子
allStraight := GetAllStraight(cards, len(lastCards))
logger.Logger.Trace("allStraight = ", allStraight)
if len(allStraight) > 0 {
for _, straight := range allStraight {
if len(straight) >= len(lastCards) {
if Value(straight[len(straight)-1]) >= Value(lastCards[len(lastCards)-1]) {
if Value(straight[len(straight)-1]) == Value(lastCards[len(lastCards)-1]) {
if Color(straight[len(straight)-1]) > Color(lastCards[len(lastCards)-1]) {
outCards = straight[len(straight)-len(lastCards):]
break
}
} else {
outCards = straight[len(straight)-len(lastCards):]
break
}
logger.Logger.Tracef("找所有顺子来压牌 outCards = ", outCards)
}
}
}
}
}
if isYuLe {
//找炸弹
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 && lastHandCardnum <= 2 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
//打到底 出牌人打完了
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Straight) {
outCards = []int32{}
}
logger.Logger.Trace("--------------顺子压牌完毕,出的牌:", outCards)
return outCards
case ColorStraight:
//同花顺
if len(cardsTypeMap[Straight]) > 0 {
straightMap := cardsTypeMap[Straight]
for _, straight := range straightMap {
if len(straight) >= len(lastCards) {
//判断是不是同花顺
if IsColorStraight(straight) {
if Value(straight[len(straight)-1]) >= Value(lastCards[len(lastCards)-1]) {
if Value(straight[len(straight)-1]) == Value(lastCards[len(lastCards)-1]) {
if Color(straight[len(straight)-1]) > Color(lastCards[len(lastCards)-1]) {
return straight[len(straight)-len(lastCards):]
}
} else {
return straight[len(straight)-len(lastCards):]
}
}
}
}
}
}
//找炸弹
if isYuLe && ((len(cardsTypeMap[Four_Bomb]) > 0 && lastHandCardnum <= 2) || handCardnum <= 2) {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
logger.Logger.Trace("--------------同花顺压牌完毕,出的牌:", outCards)
return cardsTypeMap[Four_Bomb][minKey]
}
//打到底 出牌人打完了
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, ColorStraight) {
outCards = []int32{}
}
case Straight_Twin:
//连对
//获取连对长度
lastCardNum := len(lastCards) / 2
lastMaxCard := Value(lastCards[len(lastCards)-1])
cardsMap := cardsTypeMap[Straight_Twin]
for _, card := range cardsMap {
if len(card) >= len(lastCards) {
if len(card) == len(lastCards) {
if Value(card[len(card)-1]) >= lastMaxCard {
if Value(card[len(card)-1]) == lastMaxCard {
//比较花色
if Color(card[len(card)-1]) > Color(lastCards[len(lastCards)-1]) {
//截取
outCards = card
break
}
} else {
outCards = card
break
}
}
} else {
outCards = card
break
}
}
}
if isYuLe {
//找炸弹
if len(outCards) == 0 && (len(cardsTypeMap[Four_Bomb]) > 0 && lastHandCardnum <= 2 && lastCardNum <= 3) || handCardnum <= 2 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
} else {
if lastCardNum == 3 {
//找炸弹
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
}
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Straight_Twin) {
outCards = []int32{}
}
logger.Logger.Tracef("--------------连对压牌完毕,出的牌:", outCards)
return outCards
case Triple:
//三张
cardsMap := cardsTypeMap[Triple]
for _, card := range cardsMap {
if Value(card[len(card)-1]) > Value(lastCards[len(lastCards)-1]) {
if Value(card[0]) == 12 && lastHandCardnum > 2 {
continue
}
outCards = card
break
//return card
}
}
if isYuLe {
//找炸弹
if len(outCards) == 0 && ((len(cardsTypeMap[Four_Bomb]) > 0 && lastHandCardnum <= 2) || handCardnum <= 2) {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Triple) {
outCards = []int32{}
}
logger.Logger.Trace("--------------三张压牌完毕,出的牌:", outCards)
return outCards
case Four_Bomb:
//炸弹
cardsMap := cardsTypeMap[Four_Bomb]
for _, card := range cardsMap {
if Value(card[0]) > Value(lastCards[0]) {
logger.Logger.Trace("--------------炸弹压牌,找到的牌:", outCards)
if isYuLe && (lastHandCardnum <= 2 || handCardnum <= 2) {
return card
}
if !isYuLe {
return card
}
}
}
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Four_Bomb) {
outCards = []int32{}
}
case Straight_Triple:
//三顺
cardsMap := cardsTypeMap[Straight_Triple]
if len(cardsMap) > 0 {
for _, card := range cardsMap {
if Value(card[0]) > Value(lastCards[0]) && len(card) == len(lastCards) {
outCards = card
break
}
}
}
if isYuLe {
//找炸弹
if (len(outCards) == 0 || len(outCards) != len(lastCards)) && len(cardsTypeMap[Four_Bomb]) > 0 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minKey]
}
}
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Straight_Triple) {
outCards = []int32{}
}
logger.Logger.Trace("--------------三顺压牌完毕,出的牌:", outCards)
return outCards
case Plane_Single:
//三代单 --不用考虑 只有最后一首才会出三代单
singleHand, singleLen := FindPlaneSingleHead(lastCards)
logger.Logger.Trace("飞机找带双 singleHand = ", singleHand, "singleLen = ", singleLen)
if singleLen > 1 && len(cards) >= len(lastCards) {
//333 444 5 6 7 8
//找相同长度三顺
straightTripleMap := cardsTypeMap[Straight_Triple]
if len(straightTripleMap) > 0 {
for _, straightTriple := range straightTripleMap {
if len(straightTriple)/3 >= singleLen {
if Value(straightTriple[len(straightTriple)-1]) > int(singleHand) {
outCards = straightTriple[len(straightTriple)-singleLen*3:]
}
}
}
}
}
if len(outCards) != 0 {
copyCards := make([]int32, len(cards))
copy(copyCards, cards)
delCard := make(map[int32][]int32)
delCard[0] = outCards
copyCards = DelCards(copyCards, delCard)
copyCards = DelCards(copyCards, cardsTypeMap[Four_Bomb])
num := len(cards) - len(lastCards)
if num == 1 {
//留最大牌
outCards = []int32{}
maxCard := copyCards[len(copyCards)-1:]
for _, card := range cards {
if card == maxCard[0] {
continue
}
outCards = append(outCards, card)
}
} else if num == 2 {
//留对子
_, pairMap := GetPair(copyCards)
if len(pairMap) > 0 {
outCards = []int32{}
maxPair := -1
maxKey := int32(0)
for i, pair := range pairMap {
if Value(pair[0]) > maxPair {
maxPair = Value(pair[0])
maxKey = i
}
}
for _, card := range cards {
if card == pairMap[maxKey][0] || card == pairMap[maxKey][1] {
continue
}
outCards = append(outCards, card)
}
} else {
//留最后两张大牌
outCards = []int32{}
maxCard := copyCards[len(copyCards)-2:]
for _, card := range cards {
if card == maxCard[0] || card == maxCard[1] {
continue
}
outCards = append(outCards, card)
}
}
} else if num == 3 {
//留顺子
straights := cardsTypeMap[Straight]
if len(straights) > 0 {
outCards = []int32{}
straight := straights[int32(len(straights)-1)]
saveCards := straight[len(straight)-3:]
for _, card := range cards {
if card == saveCards[0] || card == saveCards[1] || card == saveCards[2] {
continue
}
outCards = append(outCards, card)
}
} else {
//留最后三张大牌
outCards = []int32{}
maxCard := copyCards[len(copyCards)-3:]
for _, card := range cards {
if card == maxCard[0] || card == maxCard[1] || card == maxCard[2] {
continue
}
outCards = append(outCards, card)
}
}
} else {
for _, value := range cards {
status := true
for _, straight := range outCards {
if value == straight || Value(value) == Value(straight) {
status = false
break
}
}
if status {
outCards = append(outCards, value)
}
if len(outCards) == len(lastCards) {
break
}
}
}
}
if isYuLe {
//找炸弹
if (len(outCards) == 0 || len(outCards) != len(lastCards)) && len(cardsTypeMap[Four_Bomb]) > 0 {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
return cardsTypeMap[Four_Bomb][minKey]
}
}
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Plane_Single) {
outCards = []int32{}
}
logger.Logger.Trace("--------------飞机带单压牌完毕,出的牌:", outCards)
return outCards
case Plane_Twin:
outCards = []int32{}
twinHand, twinLen := FindPlaneTwinHead(lastCards)
logger.Logger.Trace("飞机找带双 twinHand = ", twinHand, "twinLen = ", twinLen)
if twinLen == 1 {
//三代双
cardsMap := cardsTypeMap[Triple]
key := int32(999)
for i, data1 := range cardsMap {
if Value(data1[len(data1)-1]) > int(twinHand) {
if i < key {
//card = data1
key = i
}
break
}
}
if key != 999 {
outCards = cardsTypeMap[Triple][key]
}
if len(outCards) > 0 {
minSingleKey := findMinKey(cardsTypeMap[Single])
minTwinKey := findMinKey(cardsTypeMap[Twin])
if len(cardsTypeMap[Single]) >= 2 && Value(cardsTypeMap[Single][minSingleKey][0]) < 12 {
//三代2单
if len(cardsTypeMap[Single]) >= 2 {
minValue := FindSmallestTwoValues(cardsTypeMap[Single])
//logger.Logger.Trace("找出最小两张单排的值:", minValue)
outCards = append(outCards, minValue[0], minValue[1])
}
} else if len(cardsTypeMap[Twin]) >= 1 && Value(cardsTypeMap[Twin][minTwinKey][0]) < 11 {
//三代一对
outCards = append(outCards, cardsTypeMap[Twin][minTwinKey][0], cardsTypeMap[Twin][minTwinKey][1])
//logger.Logger.Trace("压牌,三代一对: ", card)
} else {
//直接找最小的两张牌
if len(cards) >= 5 {
for _, value := range cards {
if Value(value) != Value(outCards[0]) {
outCards = append(outCards, value)
if len(outCards) == 5 {
return outCards
}
}
}
}
}
}
} else {
//333 444 555
//找相同长度三顺
if len(cards) >= len(lastCards) {
straightTripleMap := cardsTypeMap[Straight_Triple]
if len(straightTripleMap) > 0 {
for _, straightTriple := range straightTripleMap {
if len(straightTriple)/3 >= twinLen {
if Value(straightTriple[len(straightTriple)-1]) > int(twinHand) {
outCards = straightTriple[len(straightTriple)-twinLen*3:]
}
}
}
}
if len(outCards) != 0 {
copyCards := make([]int32, len(cards))
copy(copyCards, cards)
delCard := make(map[int32][]int32)
delCard[0] = outCards
copyCards = DelCards(copyCards, delCard)
copyCards = DelCards(copyCards, cardsTypeMap[Four_Bomb])
num := len(cards) - len(lastCards)
if num == 1 {
//留最大牌
outCards = []int32{}
maxCard := copyCards[len(copyCards)-1:]
for _, card := range cards {
if card == maxCard[0] {
continue
}
outCards = append(outCards, card)
}
} else if num == 2 {
//留对子
_, pairMap := GetPair(copyCards)
if len(pairMap) > 0 {
maxPair := -1
maxKey := int32(0)
for i, pair := range pairMap {
if Value(pair[0]) > maxPair {
maxPair = Value(pair[0])
maxKey = i
}
}
outCards = []int32{}
for _, card := range cards {
if card == pairMap[maxKey][0] || card == pairMap[maxKey][1] {
continue
}
outCards = append(outCards, card)
}
} else {
//留最后两张大牌
maxCard := copyCards[len(copyCards)-2:]
for _, card := range cards {
if card == maxCard[0] || card == maxCard[1] {
continue
}
outCards = append(outCards, card)
}
}
} else if num == 3 {
//留顺子
straights := cardsTypeMap[Straight]
if len(straights) > 0 {
outCards = []int32{}
straight := straights[int32(len(straights)-1)]
saveCards := straight[len(straight)-3:]
for _, card := range cards {
if card == saveCards[0] || card == saveCards[1] || card == saveCards[2] {
continue
}
outCards = append(outCards, card)
}
} else {
//留最后三张大牌
maxCard := copyCards[len(copyCards)-3:]
outCards = []int32{}
for _, card := range cards {
if card == maxCard[0] || card == maxCard[1] || card == maxCard[2] {
continue
}
outCards = append(outCards, card)
}
}
} else {
for _, value := range cards {
status := true
for _, straight := range outCards {
if value == straight || Value(value) == Value(straight) {
status = false
break
}
}
if status {
outCards = append(outCards, value)
}
if len(outCards) == len(lastCards) {
break
}
}
}
}
}
}
if isYuLe {
//找炸弹
if len(outCards) == 0 && len(cardsTypeMap[Four_Bomb]) > 0 && (lastHandCardnum <= 2 || handCardnum <= 2) {
minKey := findMinKey(cardsTypeMap[Four_Bomb])
return cardsTypeMap[Four_Bomb][minKey]
}
}
if !IsPressed(isYuLe, isEnd, otherCards, lastCards, data, pos, lastPos, nextPos, handCardnum, Plane_Twin) {
outCards = []int32{}
}
logger.Logger.Trace("--------------三代双压牌完毕,出的牌:", outCards)
return outCards
default:
logger.Logger.Trace("--------------default压牌完毕出的牌", outCards)
return outCards
}
}
logger.Logger.Trace("--------------压牌完毕,出的牌:", outCards)
return outCards
}
// 出牌 isMin是否先手出最小的牌
func GetOutCards(cards []int32, data *tienlenApi.PredictRequest, pos int32) []int32 {
logger.Logger.Trace("---------------出牌开始-------------------")
sort.Slice(cards, func(i, j int) bool {
if Value(cards[i]) == Value(cards[j]) {
return cards[i] < cards[j]
}
return Value(cards[i]) < Value(cards[j])
})
isWin := data.IsWin
//测试代码
isWin = true
logger.Logger.Trace("出牌 调控输赢 isWin = ", isWin)
//测试代码
//cards = []int32{51, 4, 5}
//pos = 0
//data.Cards_left_2 = []int32{0, 1, 2, 3}
//data.Cards_left_3 = nil
//data.Cards_left_1 = nil
//data.Last_pos = 2
isYuLe := data.IsTienLenYule
isMin := data.IsFirstHand
isEnd := data.IsEnd
winSnids := data.WinSnids
//获取牌型
cardsTypeMap := GetCardsType(cards, isYuLe) //map[int]map[int32][]int32
cardsTypeMap = reloadcardsType(cardsTypeMap, pos, data, isYuLe)
logger.Logger.Trace("出牌 获取我的牌型:", cardsTypeMap, "\n")
score, handNum := GetCardTypeScore(cardsTypeMap, isYuLe, cards)
logger.Logger.Tracef("出牌 获取当前手牌的牌型分数:%v, 手牌数量:%v\n,我的位置:%d \n", score, handNum, pos)
if handNum <= 1 {
logger.Logger.Trace("只剩最后一手牌 直接全出了", cards)
return cards
}
//出牌逻辑
outCards := []int32{}
cardValue := -1
if isMin {
outCards = GetMinCardType(cards[0], cardsTypeMap, isYuLe)
logger.Logger.Trace("先出第一手,当前出牌只能出最小的牌!", outCards)
return outCards
}
//判断其他玩家剩余的牌的牌型是否能压过当前出牌的牌型
//出牌顺序
//出单张 判断下一家剩余1张牌且剩余的牌比我出的牌大 不出
otherMinHandNum, otherMinCardsNum, otherPos, otherCardsType := getOtherMinCards(pos, data, isYuLe)
logger.Logger.Tracef("玩家出牌,获取其他玩家最小剩余手数 和剩余牌数及位置剩余的牌型 otherMinHandNum=%d otherMinCardsNum=%d otherPos=%d cardsType=%d", otherMinHandNum, otherMinCardsNum, otherPos, otherCardsType)
//优先出三张 如果是娱乐模式 直接带单张 或者最小的对子
if isYuLe {
outCards, cardValue = getTriple(cardsTypeMap, cards, isYuLe, otherMinHandNum, pos, int32(otherPos), data)
logger.Logger.Tracef("出三张 cardValue = %d ,outCards = %d", cardValue, outCards)
}
//出单张
if len(outCards) == 0 && handNum > 2 {
straightNum := len(cardsTypeMap[Straight])
//测试一下
//if isYuLe {
if len(cardsTypeMap[Straight]) > 0 {
straightNum = len(cardsTypeMap[Straight])*2 + 1
}
//}
if len(cardsTypeMap[Single]) > straightNum && len(cardsTypeMap[Single]) > (len(cardsTypeMap[Twin])+len(cardsTypeMap[Straight_Twin])) {
outCards = getSingle(cardsTypeMap, cards, isYuLe)
if len(outCards) > 0 && isWin {
if otherMinHandNum == 1 && otherMinCardsNum <= 1 && otherCardsType == Single {
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
if Value(cards[0]) < Value(otherCards[0]) {
logger.Logger.Trace("出单张,其他玩家只剩一首牌 且剩余的牌比我出的牌大 不出!outCards = ", outCards)
outCards = []int32{}
} else if Value(cards[0]) == Value(otherCards[0]) {
//判断花色
if Color(cards[0]) < Color(otherCards[0]) {
logger.Logger.Trace("出单张牌值相同花色小不出outCards = ", outCards)
outCards = []int32{}
}
}
otherCardsMap := getOtherCards(pos, data)
for _, single := range cardsTypeMap[Single] {
status := true
for _, other := range otherCardsMap {
if len(other) == 1 {
if Value(single[0]) <= Value(other[0]) {
if Value(single[0]) == Value(other[0]) && Color(single[0]) > Color(other[0]) {
continue
}
status = false
}
}
}
if status {
outCards = single
break
}
}
}
//如果是全场最大的单张 不出
if len(outCards) > 0 && (otherMinCardsNum != 1) {
if Value(outCards[0]) == 12 && handNum > 2 {
outCards = []int32{}
}
}
}
}
}
//出对子 判断下一家剩余2张牌且剩余的牌比我出的牌大 不出
if len(outCards) == 0 {
straightNum := len(cardsTypeMap[Straight])
if isYuLe {
//straightNum = len(cardsTypeMap[Straight])
if len(cardsTypeMap[Straight]) > 0 {
straightNum = len(cardsTypeMap[Straight])*2 + 1
}
}
if len(cardsTypeMap[Twin]) > straightNum {
outCards = getTwin(cardsTypeMap, cards, isYuLe)
if len(outCards) > 0 && isWin {
logger.Logger.Tracef("------首牌出对子 outcards = %d\n,所有的对子:%d\n", outCards, cardsTypeMap[Twin])
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
if otherMinHandNum == 1 && otherMinCardsNum == 2 && otherCardsType == Twin {
if Value(outCards[1]) < Value(otherCards[1]) {
logger.Logger.Trace("出对子,其他玩家只剩一首牌 且剩余的牌比我出的牌大 不出!outCards = ", outCards)
outCards = []int32{}
} else if Value(outCards[1]) == Value(otherCards[1]) {
//判断花色
if Color(outCards[1]) < Color(otherCards[1]) {
logger.Logger.Trace("出对子牌值相同花色小不出outCards = ", outCards)
outCards = []int32{}
}
}
}
otherCardsMap := getOtherCards(pos, data)
for _, twin := range cardsTypeMap[Twin] {
if Value(twin[0]) == 12 && handNum > 2 {
continue
}
for _, other := range otherCardsMap {
_, otherRuleType := RulePopEnable(other)
if len(other) == 2 && otherRuleType == Twin {
if Value(twin[1]) >= Value(other[1]) {
if Value(twin[1]) == Value(other[1]) {
if Color(twin[0]) > Color(other[0]) {
outCards = twin
break
} else {
continue
}
}
outCards = twin
break
}
}
}
}
}
}
}
//出三张
if isYuLe {
if len(outCards) == 0 {
outCards, cardValue = getTriple(cardsTypeMap, cards, isYuLe, otherMinHandNum, pos, int32(otherPos), data)
if len(outCards) > 0 {
if otherMinHandNum == 1 && otherMinCardsNum >= 3 && otherCardsType == Triple {
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
//获取牌型
otherCardsTypeMap := GetCardsType(otherCards, isYuLe)
otherTriple := otherCardsTypeMap[Triple]
//找最小key
if len(otherTriple) > 0 {
otherMinKey := findMinKey(otherTriple)
if cardValue < Value(otherTriple[otherMinKey][0]) {
logger.Logger.Trace("出三张,其他玩家只剩一首牌 且剩余的牌比我出的牌大 不出!outCards = ", outCards)
outCards = []int32{}
}
}
}
}
}
}
//顺子
if len(outCards) == 0 {
outCards = getStraight(cardsTypeMap, cards, isYuLe)
if len(outCards) > 0 && isWin {
if otherMinHandNum == 1 && otherMinCardsNum == len(outCards) && otherCardsType == Straight {
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
if Value(outCards[len(outCards)-1]) < Value(otherCards[len(otherCards)-1]) {
logger.Logger.Trace("出顺子,其他玩家只剩一首牌 且剩余的牌比我出的牌大 不出!outCards = ", outCards)
outCards = []int32{}
} else if Value(outCards[len(outCards)-1]) == Value(otherCards[len(otherCards)-1]) {
//判断花色
if Color(outCards[len(outCards)-1]) < Color(otherCards[len(otherCards)-1]) {
logger.Logger.Trace("出顺子牌值相同花色小不出outCards = ", outCards)
outCards = []int32{}
}
}
}
//如果其他玩家剩余牌全是顺子 并且比我的大 我不出顺子了 (后续没牌型可出了!!!!
}
}
if !isYuLe {
if len(outCards) == 0 {
outCards, cardValue = getTriple(cardsTypeMap, cards, isYuLe, otherMinHandNum, pos, int32(otherPos), data)
if len(outCards) > 0 && isWin {
if otherMinHandNum == 1 && otherMinCardsNum >= 3 && otherCardsType == Triple {
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
//获取牌型
otherCardsTypeMap := GetCardsType(otherCards, isYuLe)
otherTriple := otherCardsTypeMap[Triple]
//找最小key
if len(otherTriple) > 0 {
otherMinKey := findMinKey(otherTriple)
if cardValue < Value(otherTriple[otherMinKey][0]) {
logger.Logger.Trace("出三张,其他玩家只剩一首牌 且剩余的牌比我出的牌大 不出!outCards = ", outCards)
outCards = []int32{}
}
}
}
}
}
}
//连对
if len(outCards) == 0 {
outCards = getStraightTwin(cardsTypeMap, cards, isYuLe)
if len(outCards) > 0 && isWin {
if otherMinHandNum == 1 && otherMinCardsNum == len(outCards) && otherCardsType == Straight_Twin {
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
if Value(outCards[len(outCards)-1]) < Value(otherCards[len(otherCards)-1]) {
logger.Logger.Trace("出连对,其他玩家只剩一首牌 且剩余的牌比我出的牌大 不出!outCards = ", outCards)
outCards = []int32{}
} else if Value(outCards[len(outCards)-1]) == Value(otherCards[len(otherCards)-1]) {
//判断花色
if Color(outCards[len(outCards)-1]) < Color(otherCards[len(otherCards)-1]) {
logger.Logger.Trace("出连队牌值相同花色小不出outCards = ", outCards)
outCards = []int32{}
}
}
}
}
if len(outCards)/2 >= 3 && handNum > 2 {
outCards = []int32{}
}
}
//炸弹 这个就不用检查了
if len(outCards) == 0 && handNum <= 2 {
if isYuLe {
if len(cardsTypeMap[Triple]) < 2 && len(cards) < 13 {
outCards = getBomb(cardsTypeMap, cards, isYuLe)
}
} else {
//出炸弹
outCards = getBomb(cardsTypeMap, cards, isYuLe)
}
}
//额外判断
//获取下一家的位置和剩余的牌
if isWin {
if handNum <= 2 {
//判断我的剩余牌型中有没有全场最大的牌型
for cardType, myCards := range cardsTypeMap { //map[int]map[int32][]int32
for _, mycard := range myCards {
if getMaxCardTypeNum(cardType, mycard, pos, data) {
logger.Logger.Trace("最后两手牌找到最大牌型mycard", mycard)
if cardType == Triple {
//出三代二
outCards, cardValue = getTriple(cardsTypeMap, cards, isYuLe, otherMinHandNum, pos, int32(otherPos), data)
if len(outCards) > 0 {
return outCards
} else {
continue
}
}
return mycard
}
}
}
}
if (handNum <= 3 && isYuLe && len(cardsTypeMap[Triple]) == 0) || (handNum <= 3 && !isYuLe) {
myMaxCardStatus, maxCardNum, maxCardsArr := getMaxCards(cards, data, pos)
if len(outCards) == 1 {
//判断当前最大牌在不在我手
if !myMaxCardStatus {
//找最长的牌
for cardType, myCards := range cardsTypeMap { //map[int]map[int32][]int32
for _, mycard := range myCards {
if (cardType == Straight_Twin && len(mycard)/2 >= 3) || cardType == Four_Bomb {
//手里有连炸
continue
}
if len(mycard) > len(outCards) {
if cardType == Triple {
//出三代二
outCards, cardValue = getTriple(cardsTypeMap, cards, isYuLe, otherMinHandNum, pos, int32(otherPos), data)
if len(outCards) > 0 {
return outCards
} else {
break
}
}
if cardType != Single && cardType != Twin {
outCards = mycard
} else {
if Value(mycard[0]) != Value(cards[len(cards)-1]) {
outCards = mycard
}
}
}
}
}
}
}
//获取我最大牌的
if myMaxCardStatus {
if otherMinCardsNum > 1 {
//这个时候我应该出单牌
//找单张 - 对子- 和最大牌数量相等的顺子长度+1的顺子
status := false
if len(cardsTypeMap[Single]) > 0 {
card := getSingle(cardsTypeMap, cards, isYuLe)
if card[0] != maxCardsArr[len(maxCardsArr)-1] {
status = true
}
}
if len(cardsTypeMap[Single]) > 0 && status {
card := getSingle(cardsTypeMap, cards, isYuLe)
if len(card) > 0 {
outCards = card
}
} else if len(cardsTypeMap[Twin]) > 0 {
minKey := findMinKey(cardsTypeMap[Twin])
//map[int]map[int32][]int32
if cardsTypeMap[Twin][minKey] != nil {
outCards = []int32{cardsTypeMap[Twin][minKey][0]}
}
logger.Logger.Trace("对子拆单张出!")
} else {
if maxCardNum > 1 {
//先找顺子的交集
result := FindIntersection(cardsTypeMap[Straight])
if len(result) > 0 {
sort.Slice(cards, func(i, j int) bool {
if Value(cards[i]) == Value(cards[j]) {
return cards[i] < cards[j]
}
return Value(cards[i]) < Value(cards[j])
})
if len(result) > 0 {
for _, arr := range result {
outCards = arr
break
}
}
} else if len(cardsTypeMap[Straight]) > 0 {
minLength := 13
minKey := int32(0)
for i, straight := range cardsTypeMap[Straight] {
if len(straight) < minLength {
minKey = i
}
}
if len(cardsTypeMap[Straight][minKey]) <= maxCardNum+1 {
outCards = []int32{cardsTypeMap[Straight][minKey][0]}
logger.Logger.Trace("拆顺子出单张outCards = ", outCards)
}
}
}
}
}
}
}
}
//最后直接出最小牌型的牌
if len(outCards) == 0 {
//直接出最大的单牌
if otherMinHandNum == 1 {
//先找其他牌型
for cardType, card := range cardsTypeMap {
if len(card) > 0 {
if cardType != Single {
minKey := findMinKey(card)
outCards = card[minKey]
logger.Logger.Trace("最后直接先出其他牌型的牌 outCards = ", outCards)
break
} else if cardType == Triple && isYuLe {
//找两张单张
minSingleKey := findMinKey(cardsTypeMap[Single])
minTwinKey := findMinKey(cardsTypeMap[Twin])
if len(cardsTypeMap[Single]) >= 2 && Value(cardsTypeMap[Single][minSingleKey][0]) < 12 {
//三代2单
if len(cardsTypeMap[Single]) >= 2 {
minValue := FindSmallestTwoValues(cardsTypeMap[Single])
outCards = append(outCards, minValue[0], minValue[1])
}
} else if len(cardsTypeMap[Twin]) >= 1 && Value(cardsTypeMap[Twin][minTwinKey][0]) < 11 {
//三代一对
outCards = append(outCards, cardsTypeMap[Twin][minTwinKey][0], cardsTypeMap[Twin][minTwinKey][1])
}
}
}
}
if len(outCards) == 0 {
nextPos, nextCards := GetNextPos(pos, data)
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
if nextPos != int32(otherPos) && Value(nextCards[len(nextCards)-1]) > Value(otherCards[0]) {
//找最小牌型的牌
outCards = GetMinCardType(cards[0], cardsTypeMap, isYuLe)
logger.Logger.Trace("最后直接找最小牌型的牌,让下一家顶上 outCards = ", outCards)
} else {
lastPos, _ := GetLastPos(pos, data)
if isEnd && len(winSnids) == 0 && nextPos != lastPos {
//找最小牌型的牌
outCards = GetMinCardType(cards[0], cardsTypeMap, isYuLe)
logger.Logger.Trace("打到底模式 最后直接找最小牌型的牌, outCards = ", outCards)
} else {
if otherMinHandNum > 2 {
//找最小牌型的牌
outCards = GetMinCardType(cards[0], cardsTypeMap, isYuLe)
logger.Logger.Trace("打到底模式 最后直接找最小牌型的牌, outCards = ", outCards)
} else {
outCards = []int32{cards[len(cards)-1]}
logger.Logger.Trace("最后直接出最大的牌 outCards = ", outCards)
}
}
}
}
} else {
//找最小牌型的牌
outCards = GetMinCardType(cards[0], cardsTypeMap, isYuLe)
logger.Logger.Trace("最后直接找最小牌型的牌 outCards = ", outCards)
}
}
logger.Logger.Trace("---------------------------出牌结束 出的牌:", outCards)
return outCards
}
// 判断牌型是否全场最大
func getMaxCardTypeNum(cardsType int, cards []int32, pos int32, data *tienlenApi.PredictRequest) bool {
//map[int][]int32
status := true
otherCardsMap := getOtherCards(pos, data)
for _, otherCards := range otherCardsMap {
if len(otherCards) == 0 {
continue
}
sort.Slice(otherCards, func(i, j int) bool {
if Value(otherCards[i]) == Value(otherCards[j]) {
return otherCards[i] < otherCards[j]
}
return Value(otherCards[i]) < Value(otherCards[j])
})
if cardsType == Single {
if len(otherCards) > 0 && len(cards) > 0 {
if Value(otherCards[len(otherCards)-1]) >= Value(cards[0]) {
if Value(otherCards[len(otherCards)-1]) == Value(cards[0]) {
if Color(otherCards[len(otherCards)-1]) > Color(cards[0]) {
return false
}
} else {
return false
}
}
}
} else if cardsType == Twin {
_, pairMap := GetPair(otherCards)
if len(pairMap) > 0 {
for _, pair := range pairMap {
if Value(pair[len(pair)-1]) >= Value(cards[0]) {
if Value(pair[len(pair)-1]) == Value(cards[0]) {
if Color(pair[len(pair)-1]) > Color(cards[0]) {
return false
}
} else {
return false
}
}
}
}
}
otherCardsTypeMap := GetCardsType(otherCards, data.IsTienLenYule) //map[int]map[int32][]int32
if otherCardsTypeMap[cardsType] != nil && len(otherCardsTypeMap[cardsType]) > 0 {
for _, cardsArr := range otherCardsTypeMap[cardsType] {
if len(cardsArr) < len(cards) {
continue
}
if Value(cardsArr[len(cardsArr)-1]) > Value(cards[len(cards)-1]) {
status = false
break
} else if Value(cardsArr[len(cardsArr)-1]) == Value(cards[len(cards)-1]) {
if Color(cardsArr[len(cardsArr)-1]) > Color(cards[len(cards)-1]) {
status = false
break
}
}
}
if !status {
break
}
}
}
return status
}
// 出单张
func getSingle(cardsTypeMap map[int]map[int32][]int32, cards []int32, isYuLe bool) []int32 {
outCards := []int32{}
if isYuLe {
if len(cardsTypeMap[Triple]) == 0 {
minKey := findMinKey(cardsTypeMap[Single])
outCards = cardsTypeMap[Single][minKey]
}
} else {
minKey := findMinKey(cardsTypeMap[Single])
outCards = cardsTypeMap[Single][minKey]
}
return outCards
}
// 出对子
func getTwin(cardsTypeMap map[int]map[int32][]int32, cards []int32, isYuLe bool) []int32 {
outCards := []int32{}
_, handNum := GetCardTypeScore(cardsTypeMap, isYuLe, cards)
if len(cardsTypeMap[Twin]) > len(cardsTypeMap[Straight]) {
minKey := findMinKey(cardsTypeMap[Twin])
if isYuLe {
if len(cardsTypeMap[Triple]) == 0 {
if Value(cardsTypeMap[Twin][minKey][0]) < 11 || (handNum <= 2 && len(cardsTypeMap[Triple]) == 0) {
outCards = cardsTypeMap[Twin][minKey]
}
}
} else {
if Value(cardsTypeMap[Twin][minKey][0]) < 11 || (handNum <= 2 && len(cardsTypeMap[Triple]) == 0) {
outCards = cardsTypeMap[Twin][minKey]
}
}
}
return outCards
}
// 出三张 cardValue三张的值 value(card)
func getTriple(cardsTypeMap map[int]map[int32][]int32, cards []int32, isYuLe bool, otherMinHandNum int, mypos, otherPos int32, data *tienlenApi.PredictRequest) ([]int32, int) {
outCards := []int32{}
cardValue := 0
_, handNum := GetCardTypeScore(cardsTypeMap, isYuLe, cards)
if isYuLe && len(cardsTypeMap[Straight_Triple]) > 0 {
//AI机器人三顺的长度只能是2 大于2的直接拆成连对炸弹了
outCards = []int32{}
if len(cards) <= 10 && len(cardsTypeMap[Four_Bomb]) == 0 {
return cards, cardValue
} else {
copyCards := make([]int32, len(cards))
copy(copyCards, cards)
copyCards = DelCards(copyCards, cardsTypeMap[Straight_Triple])
copyCards = DelCards(copyCards, cardsTypeMap[Four_Bomb])
sort.Slice(copyCards, func(i, j int) bool {
if Value(copyCards[i]) == Value(copyCards[j]) {
return copyCards[i] < copyCards[j]
}
return Value(copyCards[i]) < Value(copyCards[j])
})
num := len(cards) - 10
if num == 1 {
//留最大牌
maxCard := copyCards[len(copyCards)-1:]
for _, card := range cards {
if card == maxCard[0] {
continue
}
outCards = append(outCards, card)
}
} else if num == 2 {
//留对子
_, pairMap := GetPair(copyCards)
if len(pairMap) > 0 {
maxPair := -1
maxKey := int32(0)
for i, pair := range pairMap {
if Value(pair[0]) > maxPair {
maxPair = Value(pair[0])
maxKey = i
}
}
for _, card := range cards {
if card == pairMap[maxKey][0] || card == pairMap[maxKey][1] {
continue
}
outCards = append(outCards, card)
}
} else {
//留最后两张大牌
maxCard := copyCards[len(copyCards)-2:]
for _, card := range cards {
if card == maxCard[0] || card == maxCard[1] {
continue
}
outCards = append(outCards, card)
}
}
} else if num == 3 {
//留顺子
straights := cardsTypeMap[Straight]
if len(straights) > 0 {
straight := straights[int32(len(straights)-1)]
saveCards := straight[len(straight)-3:]
for _, card := range cards {
if card == saveCards[0] || card == saveCards[1] || card == saveCards[2] {
continue
}
outCards = append(outCards, card)
}
} else {
//留最后三张大牌
maxCard := copyCards[len(copyCards)-3:]
for _, card := range cards {
if card == maxCard[0] || card == maxCard[1] || card == maxCard[2] {
continue
}
outCards = append(outCards, card)
}
}
} else {
//直接出三顺
straightTripleMap := cardsTypeMap[Straight_Triple]
for _, straightTriple := range straightTripleMap {
outCards = straightTriple
break
}
}
}
logger.Logger.Trace("-----------出三顺--------------------", outCards)
return outCards, cardValue
}
if len(cardsTypeMap[Triple]) > 0 {
minSingleKey := findMinKey(cardsTypeMap[Single])
minTwinKey := findMinKey(cardsTypeMap[Twin])
minTripleKey := findMinKey(cardsTypeMap[Triple])
if len(cardsTypeMap[Triple]) == 2 && len(cards) <= 9 {
//先出大的三条
minTripleKey = findMaxKey(cardsTypeMap[Triple])
}
if len(cardsTypeMap[Triple]) >= 2 && len(cards) <= 8 && isYuLe {
//判断单张数量
if len(cardsTypeMap[Single]) < 2 {
//判断是不是三顺
var arr []int32
for _, three := range cardsTypeMap[Triple] {
for _, value := range three {
arr = append(arr, value)
}
}
StraightTripleMap := GetStraightTriple(arr)
if len(StraightTripleMap) > 0 {
//娱乐场 小于11张牌可以一首扔
return cards, cardValue
}
}
}
if isYuLe {
//出三代2 或三带一小对 单张小于12 三顺小于等于7
otherCard := getOtherPlayerCards(mypos, otherPos, data)
if len(cardsTypeMap[Single]) >= 2 && (Value(cardsTypeMap[Single][minSingleKey][0]) < 12 || handNum <= 2 || (otherMinHandNum == 1 && len(otherCard) == 1 && len(cardsTypeMap[Single]) >= 3)) {
//三代2单
if Value(cardsTypeMap[Triple][minTripleKey][0]) <= 9 || handNum <= 2 || (otherMinHandNum == 1 && len(otherCard) == 1 && len(cardsTypeMap[Single]) >= 3) {
outCards = cardsTypeMap[Triple][minTripleKey]
minValue := FindSmallestTwoValues(cardsTypeMap[Single])
if len(minValue) < 2 {
logger.Logger.Tracef("找出最小两张单排的值,没找出来minValue = %v,cardsTypeMap[Single]= %v", minValue, cardsTypeMap[Single])
} else {
outCards = append(outCards, minValue[0], minValue[1])
}
}
} else if len(cardsTypeMap[Twin]) >= 1 && (Value(cardsTypeMap[Twin][minTwinKey][0]) < 11 || handNum <= 3) {
//三代一对
outCards = cardsTypeMap[Triple][minTripleKey]
outCards = append(outCards, cardsTypeMap[Twin][minTwinKey][0], cardsTypeMap[Twin][minTwinKey][1])
} else {
if len(cards) > 5 {
outCards = cardsTypeMap[Triple][minTripleKey]
if len(cardsTypeMap[Single]) > 0 {
for _, single := range cardsTypeMap[Single] {
outCards = append(outCards, single[0])
}
}
if len(outCards) < 5 {
//找顺子交集
result := FindIntersection(cardsTypeMap[Straight])
if len(result) > 0 {
sort.Slice(cards, func(i, j int) bool {
if Value(cards[i]) == Value(cards[j]) {
return cards[i] < cards[j]
}
return Value(cards[i]) < Value(cards[j])
})
}
for _, cardArr := range result {
for _, card := range cardArr {
outCards = append(outCards, card)
if len(outCards) == 5 {
break
}
}
if len(outCards) == 5 {
break
}
}
//找顺子
if len(outCards) < 5 {
if len(cardsTypeMap[Straight]) > 0 {
for _, straights := range cardsTypeMap[Straight] {
//剩余俩个三张 一共8张牌
if len(straights)-(5-len(outCards)) >= 3 || (len(cards) == 10 && len(cardsTypeMap[Triple]) == 2) {
for i := 0; i < 5-len(outCards); i++ {
outCards = append(outCards, straights[i])
if len(outCards) == 5 {
break
}
}
if len(outCards) == 5 {
break
}
}
}
}
}
}
if len(outCards) != 5 {
//直接出三张
outCards = cardsTypeMap[Triple][minTripleKey]
}
} else {
//直接出三张
outCards = cardsTypeMap[Triple][minTripleKey]
}
}
//出三张拦截 下面三手牌会判断牌型出 这里直接不让出三个2
if Value(cardsTypeMap[Triple][minTripleKey][0]) == 12 && handNum <= 3 && handNum != 1 && len(cards) >= 10 {
logger.Logger.Trace("出三张 拦截 三个2 ")
outCards = []int32{}
return outCards, 0
}
} else {
outCards = cardsTypeMap[Triple][minTripleKey]
if isYuLe {
if len(cards) <= 5 {
//最后4张牌 出三带1
outCards = cards
}
}
}
cardValue = Value(cardsTypeMap[Triple][minTripleKey][0])
}
return outCards, cardValue
}
// 出顺子
func getStraight(cardsTypeMap map[int]map[int32][]int32, cards []int32, isYuLe bool) []int32 {
outCards := []int32{}
_, handNum := GetCardTypeScore(cardsTypeMap, isYuLe, cards)
if len(cardsTypeMap[Straight]) >= 1 {
//出顺子
//如果只剩两手牌 先出最长的顺子
if handNum <= 2 {
//找长度最大的顺子
maxLength := 0
maxKey := int32(0)
for i, straight := range cardsTypeMap[Straight] {
if len(straight) > maxLength {
maxKey = i
}
}
outCards = cardsTypeMap[Straight][maxKey]
} else {
//找小顺子
outCards = cardsTypeMap[Straight][0]
}
}
return outCards
}
// 出连对
func getStraightTwin(cardsTypeMap map[int]map[int32][]int32, cards []int32, isYuLe bool) []int32 {
outCards := []int32{}
if len(cardsTypeMap[Straight_Twin]) > 0 {
//找长度最小的连对
length := 0
key := int32(0)
for i, straight := range cardsTypeMap[Straight_Twin] {
if len(straight) < length && len(straight) > 0 {
key = i
}
}
outCards = cardsTypeMap[Straight_Twin][key]
}
return outCards
}
// 出炸弹
func getBomb(cardsTypeMap map[int]map[int32][]int32, cards []int32, isYuLe bool) []int32 {
outCards := []int32{}
//炸弹
if len(cardsTypeMap[Four_Bomb]) > 0 {
//出炸弹
minTripleKey := findMinKey(cardsTypeMap[Four_Bomb])
outCards = cardsTypeMap[Four_Bomb][minTripleKey]
}
return outCards
}
// ---------------------------------------------//
// 找手里最小的牌的组合
func GetMinCardType(minCard int32, cardsType map[int]map[int32][]int32, isYuLe bool) []int32 {
for cardType, cards := range cardsType {
for _, cardArr := range cards {
for i, card := range cardArr {
if Value(card) == Value(minCard) {
if card == minCard {
if cardType == Triple && isYuLe {
//找两张单张
minSingleKey := findMinKey(cardsType[Single])
minTwinKey := findMinKey(cardsType[Twin])
if len(cardsType[Single]) >= 2 && Value(cardsType[Single][minSingleKey][0]) < 12 {
//三代2单
if len(cardsType[Single]) >= 2 {
minValue := FindSmallestTwoValues(cardsType[Single])
cardArr = append(cardArr, minValue[0], minValue[1])
}
} else if len(cardsType[Twin]) >= 1 && Value(cardsType[Twin][minTwinKey][0]) < 11 {
//三代一对
cardArr = append(cardArr, cardsType[Twin][minTwinKey][0], cardsType[Twin][minTwinKey][1])
}
}
return cardArr
} else {
//替换牌
cardArr[i] = minCard
if cardType == Triple && isYuLe {
//找两张单张 变成三代二
minSingleKey := findMinKey(cardsType[Single])
minTwinKey := findMinKey(cardsType[Twin])
if len(cardsType[Single]) >= 2 && Value(cardsType[Single][minSingleKey][0]) < 12 {
//三代2单
if len(cardsType[Single]) >= 2 {
minValue := FindSmallestTwoValues(cardsType[Single])
cardArr = append(cardArr, minValue[0], minValue[1])
}
} else if len(cardsType[Twin]) >= 1 && Value(cardsType[Twin][minTwinKey][0]) < 11 {
//三代一对
cardArr = append(cardArr, cardsType[Twin][minTwinKey][0], cardsType[Twin][minTwinKey][1])
}
}
return cardArr
}
}
}
}
}
//直接返回单张
return []int32{minCard}
}
// 获取下一家的位置和剩余的牌
func GetNextPos(pos int32, data *tienlenApi.PredictRequest) (int32, []int32) {
for i := 1; i < 4; i++ {
nextPos := pos + int32(i)
if nextPos > 3 {
nextPos -= 4
}
//判断这个位置有没有剩余牌
if nextPos == 0 && len(data.Cards_left_0) > 0 {
return nextPos, data.Cards_left_0
} else if nextPos == 1 && len(data.Cards_left_1) > 0 {
return nextPos, data.Cards_left_1
} else if nextPos == 2 && len(data.Cards_left_2) > 0 {
return nextPos, data.Cards_left_2
} else if nextPos == 3 && len(data.Cards_left_3) > 0 {
return nextPos, data.Cards_left_3
}
}
return -1, nil
}
// 获取上家的位置和剩余的牌
func GetLastPos(pos int32, data *tienlenApi.PredictRequest) (int32, []int32) {
for i := 1; i < 4; i++ {
nextPos := (pos - int32(i) + 4) % 4
//判断这个位置有没有剩余牌
if nextPos == 0 && len(data.Cards_left_0) > 0 {
return nextPos, data.Cards_left_0
} else if nextPos == 1 && len(data.Cards_left_1) > 0 {
return nextPos, data.Cards_left_1
} else if nextPos == 2 && len(data.Cards_left_2) > 0 {
return nextPos, data.Cards_left_2
} else if nextPos == 3 && len(data.Cards_left_3) > 0 {
return nextPos, data.Cards_left_3
}
}
return -1, nil
}
// 获取指定玩家的牌
func getOtherPlayerCards(mypos, otherPos int32, data *tienlenApi.PredictRequest) []int32 {
otherCardsMap := getOtherCards(mypos, data)
sort.Slice(otherCardsMap[int(otherPos)], func(i, j int) bool {
if otherCardsMap[int(otherPos)][i] == otherCardsMap[int(otherPos)][j] {
return otherCardsMap[int(otherPos)][i] < otherCardsMap[int(otherPos)][j]
}
return Value(otherCardsMap[int(otherPos)][i]) < Value(otherCardsMap[int(otherPos)][j])
})
return otherCardsMap[int(otherPos)]
}
// 判断自己手里有没有最大的牌
func getMaxCards(myCards []int32, data *tienlenApi.PredictRequest, mypos int32) (bool, int, []int32) {
sort.Slice(myCards, func(i, j int) bool {
if Value(myCards[i]) == Value(myCards[j]) {
return myCards[i] < myCards[j]
}
return Value(myCards[i]) < Value(myCards[j])
})
//getOtherCards()
otherCardsMap := getOtherCards(mypos, data)
var otherCards []int32
for _, otherCard := range otherCardsMap {
otherCards = append(otherCards, otherCard...)
}
sort.Slice(otherCards, func(i, j int) bool {
if Value(otherCards[i]) == Value(otherCards[j]) {
return otherCards[i] < otherCards[j]
}
return Value(otherCards[i]) < Value(otherCards[j])
})
maxCardNum := 0
status := false
maxCardsArr := []int32{}
for _, mycard := range myCards {
if Value(mycard) >= Value(otherCards[len(otherCards)-1]) {
if Value(mycard) == Value(otherCards[len(otherCards)-1]) {
if Color(mycard) < Color(otherCards[len(otherCards)-1]) {
continue
}
}
maxCardNum += 1
status = true
maxCardsArr = append(maxCardsArr, mycard)
}
}
//排序返回
sort.Slice(maxCardsArr, func(i, j int) bool {
if Value(maxCardsArr[i]) == Value(maxCardsArr[j]) {
return maxCardsArr[i] < maxCardsArr[j]
}
return Value(maxCardsArr[i]) < Value(maxCardsArr[j])
})
return status, maxCardNum, maxCardsArr
}
func findMinKey(data map[int32][]int32) int32 {
minValue := int32(math.MaxInt32)
minKey := int32(-1)
for i, value := range data {
if int32(Value(value[0])) < minValue {
minValue = int32(Value(value[0]))
minKey = i
}
}
return minKey
}
func findMaxKey(data map[int32][]int32) int32 {
maxKey := int32(-1)
for key := range data {
if key > maxKey {
maxKey = key
}
}
return maxKey
}
// 获取其他玩家的牌
func getOtherCards(myPos int32, data *tienlenApi.PredictRequest) map[int][]int32 {
otherCards := make(map[int][]int32)
for i := 0; i < 4; i++ {
if i == int(myPos) {
continue
}
if i == 0 {
otherCards[i] = data.Cards_left_0
} else if i == 1 {
otherCards[i] = data.Cards_left_1
} else if i == 2 {
otherCards[i] = data.Cards_left_2
} else if i == 3 {
otherCards[i] = data.Cards_left_3
}
}
return otherCards
}
// 获取其他玩家最小剩余手数 和剩余牌数及位置剩余的牌型
func getOtherMinCards(myPos int32, data *tienlenApi.PredictRequest, isYuLe bool) (int, int, int, int) {
otherCards := getOtherCards(myPos, data)
otherMinHandNum := 100
otherMinCardsNum := 13
otherPos := -1
cardsType := -1
maxCards := []int32{}
for i, other := range otherCards {
//获取牌型
if len(other) > 0 {
cardsTypeMap := GetCardsType(other, isYuLe)
//剩余手数
_, handNum := GetCardTypeScore(cardsTypeMap, isYuLe, other)
if handNum <= otherMinHandNum && len(other) <= otherMinCardsNum {
if handNum == otherMinHandNum && len(other) <= otherMinHandNum {
_, ruleType := RulePopEnable(other)
if ruleType == cardsType {
//相同牌型找最大的牌
if Value(other[len(other)-1]) < Value(maxCards[len(maxCards)-1]) {
continue
}
}
}
otherMinHandNum = handNum
otherMinCardsNum = len(other)
otherPos = i
maxCards = other
if handNum <= 1 {
isRule, ruleType := RulePopEnable(other)
if isRule {
cardsType = ruleType
} else {
//三张 三带一 三带二
cardsType = Triple
}
}
}
}
}
return otherMinHandNum, otherMinCardsNum, otherPos, cardsType
}
// 找到最小的两个值
func FindSmallestTwoValues(m map[int32][]int32) []int32 {
// 创建一个切片存储map的键值对
pairs := make([][2]int32, 0)
// 将map的键值对存储在切片中
for key := range m {
pairs = append(pairs, [2]int32{key, key})
}
// 对切片按照键值进行排序
sort.Slice(pairs, func(i, j int) bool {
return pairs[i][0] < pairs[j][0]
})
// 取出最小的两个值
var smallestTwo []int32
if len(pairs) >= 2 {
smallestTwo = append(smallestTwo, m[pairs[0][0]]...)
if len(m[pairs[1][0]]) > 0 {
smallestTwo = append(smallestTwo, m[pairs[1][0]]...)
}
} else if len(pairs) == 1 {
smallestTwo = m[pairs[0][0]]
}
return smallestTwo
}
// 找交集
func FindIntersection(arrays map[int32][]int32) [][]int32 {
var result [][]int32
// 获取 map 中的键,并按顺序进行迭代
keys := make([]int32, 0, len(arrays))
for key := range arrays {
keys = append(keys, key)
}
sort.Slice(keys, func(i, j int) bool {
return keys[i] < keys[j]
})
// 检查相邻的数组之间的交集
for i := 0; i < len(keys)-1; i++ {
currentKey := keys[i]
nextKey := keys[i+1]
currentArray := arrays[currentKey]
nextArray := arrays[nextKey]
intersection := GetArrayIntersection(currentArray, nextArray)
if intersection != nil {
result = append(result, intersection)
}
}
return result
}
// 获取两个切片的交集
func GetArrayIntersection(arr1, arr2 []int32) []int32 {
// 创建一个 map 用于存储第一个切片中的元素
elements := make(map[int32]bool)
for _, num := range arr1 {
elements[num] = true
}
// 检查第二个切片中的元素是否在第一个切片中出现,如果是,则添加到结果中
var result []int32
for _, num := range arr2 {
if elements[num] {
result = append(result, num)
}
}
return result
}
// 是否压牌
func IsPressed(isYuLe, isEnd bool, otherCards, lastCards []int32, data *tienlenApi.PredictRequest, pos, lastPos, nextPos int32, handCardnum, cardsType int) bool {
if (!isYuLe && isEnd) && len(otherCards) == 0 {
lastNextPos, _ := GetNextPos(lastPos, data)
if lastNextPos == pos && nextPos != lastPos {
if getMaxCardTypeNum(cardsType, lastCards, pos, data) && handCardnum > 2 {
return false
}
if len(lastCards) > 0 {
if Value(lastCards[0]) == 2 && handCardnum > 2 {
return false
}
}
}
}
return true
}
// 重组牌型
func reloadcardsType(cardsTypeMap map[int]map[int32][]int32, pos int32, data *tienlenApi.PredictRequest, isYuLe bool) map[int]map[int32][]int32 {
//其他玩家只剩一张牌了
otherMinHandNum, otherMinCardsNum, otherPos, otherCardsType := getOtherMinCards(pos, data, isYuLe)
//otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
//剩余两手 全是单牌
status := false
allOtherCards := getOtherCards(pos, data)
for _, otherCards := range allOtherCards {
if len(otherCards) == 2 {
otherType := GetCardsType(otherCards, isYuLe)
//剩余手数
_, handNum := GetCardTypeScore(otherType, isYuLe, otherCards)
if handNum == 2 {
otherMaxCard := otherCards[0]
if Value(otherCards[0]) < Value(otherCards[1]) {
otherMaxCard = otherCards[1]
}
if getMaxCardTypeNum(Single, []int32{otherMaxCard}, pos, data) {
logger.Logger.Trace("玩家剩余2张牌且有一张全场最大的牌重组牌型otherCards = ", otherCards)
status = true
}
}
}
}
if (otherMinHandNum == 1 && otherMinCardsNum <= 1 && otherCardsType == Single) || status {
//lastPos, _ := GetLastPos(pos, data)
//nextPos, _ := GetNextPos(pos, data)
//只考虑剩2人的情况下
//if nextPos == int32(otherPos) {
//判断我手里的单牌 组对子
if len(cardsTypeMap[Single]) >= 2 {
//判断如果单牌有2张以上小于其他玩家的牌开始组对子
otherCards := getOtherPlayerCards(pos, int32(otherPos), data)
minCards := map[int32]int32{}
for i, card := range cardsTypeMap[Single] {
if Value(card[0]) <= Value(otherCards[0]) {
//判断花色
if Value(card[0]) == Value(otherCards[0]) {
if Color(card[0]) < Color(otherCards[0]) {
//minCards = append(minCards, card[0])
minCards[i] = card[0]
continue
}
} else {
//minCards = append(minCards, card[0])
minCards[i] = card[0]
}
}
}
//有超过两张的单牌小于其他玩家的牌,开始组对子
if len(minCards) >= 2 {
//开始拆顺子 组对子
if len(cardsTypeMap[Straight]) > 0 {
straightMap := cardsTypeMap[Straight]
for delKey, minCard := range minCards {
for straightKey, straight := range straightMap {
if len(straight) <= 3 {
continue
}
//先找最小的牌
if Value(straight[0]) == Value(minCard) {
if cardsTypeMap[Twin] == nil {
cardsTypeMap[Twin] = map[int32][]int32{}
}
cardsTypeMap[Twin][int32(Value(minCard))] = append(cardsTypeMap[Twin][int32(Value(minCard))], minCard, straight[0])
cardsTypeMap[Straight][straightKey] = cardsTypeMap[Straight][straightKey][1:]
//删除单张
delete(cardsTypeMap[Single], delKey)
break
} else if Value(straight[len(straight)-1]) == Value(minCard) {
if cardsTypeMap[Twin] == nil {
cardsTypeMap[Twin] = map[int32][]int32{}
}
cardsTypeMap[Twin][int32(Value(minCard))] = append(cardsTypeMap[Twin][int32(Value(minCard))], minCard, straight[len(straight)-1])
cardsTypeMap[Straight][straightKey] = cardsTypeMap[Straight][straightKey][:len(straight)-1]
//删除单张
delete(cardsTypeMap[Single], delKey)
break
} else {
//找中间 暂时不做 情况太复杂了 需要考虑的太多
}
}
}
}
}
}
//}
if len(cardsTypeMap[Single]) == 0 {
delete(cardsTypeMap, Single)
}
if len(cardsTypeMap[Straight]) == 0 {
delete(cardsTypeMap, Straight)
}
}
return cardsTypeMap
}
// 获取所有玩家剩余的牌型
func GetAllOtherCardsType(data *tienlenApi.PredictRequest, pos int32, isYuLe bool) map[int]map[int]map[int32][]int32 {
allOtherCardsType := map[int]map[int]map[int32][]int32{}
for i := 1; i < 4; i++ {
if i == int(pos) {
continue
}
//判断这个位置有没有剩余牌
if i == 0 && len(data.Cards_left_0) > 0 {
cardsTypeMap0 := GetCardsType(data.Cards_left_0, isYuLe)
allOtherCardsType[i] = cardsTypeMap0
} else if i == 1 && len(data.Cards_left_1) > 0 {
cardsTypeMap1 := GetCardsType(data.Cards_left_1, isYuLe)
allOtherCardsType[i] = cardsTypeMap1
} else if i == 2 && len(data.Cards_left_2) > 0 {
cardsTypeMap2 := GetCardsType(data.Cards_left_2, isYuLe)
allOtherCardsType[i] = cardsTypeMap2
} else if i == 3 && len(data.Cards_left_3) > 0 {
cardsTypeMap3 := GetCardsType(data.Cards_left_3, isYuLe)
allOtherCardsType[i] = cardsTypeMap3
}
}
return allOtherCardsType
}
// 判断能不能出顺子
func IsOutStraight(data *tienlenApi.PredictRequest, pos int32, isYuLe bool, mycards []int32) (bool, int) {
allOtherCardsType := GetAllOtherCardsType(data, pos, isYuLe)
copyMap := make(map[int]map[int]map[int32][]int32)
for k1, v1 := range allOtherCardsType {
copyMap[k1] = make(map[int]map[int32][]int32)
for k2, v2 := range v1 {
copyMap[k1][k2] = make(map[int32][]int32)
for k3, v3 := range v2 {
copyMap[k1][k2][k3] = make([]int32, len(v3))
copy(copyMap[k1][k2][k3], v3)
}
}
}
for i, OtherCardsType := range copyMap {
if len(OtherCardsType[Straight]) > 0 {
for _, otherStraight := range OtherCardsType[Straight] {
if len(otherStraight) >= len(mycards) {
if len(otherStraight)-len(mycards) <= 2 {
//说明要拆牌多出来2张我可以出
}
if Value(otherStraight[len(otherStraight)-1]) <= Value(mycards[len(mycards)-1]) {
//判断花色
if Value(otherStraight[len(otherStraight)-1]) == Value(mycards[len(mycards)-1]) {
if Color(otherStraight[len(otherStraight)-1]) < Color(mycards[len(mycards)-1]) {
continue
}
} else {
continue
}
}
}
}
//判断剩余的牌是不是全是顺子
delete(OtherCardsType, Straight)
if len(OtherCardsType) <= 1 {
logger.Logger.Trace("全是顺子啊,还比我的大!!!!不能打顺子!")
return false, i
}
}
}
return true, -1
}