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{
		-120, -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 = false
	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 = false
	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
}
