package thirteen

import (
	"fmt"
	"sort"
	"strings"
)

func getIndex(a []int, e int) int {
	for k, v := range a {
		if v < 0 {
			continue
		}
		if v == e {
			return k
		}
	}
	return -1
}

func compareLine(a, b []int, getFunc, cmpFunc func(int) int) (int, int, int) {
	ac := make([]int, len(a))
	copy(ac, a)
	sort.Sort(sort.Reverse(sort.IntSlice(ac)))
	bc := make([]int, len(b))
	copy(bc, b)
	sort.Sort(sort.Reverse(sort.IntSlice(bc)))
	var maxA, maxB int
	for i := 0; i < 15; i++ {
		if len(ac) == 0 || len(bc) == 0 {
			return 0, -1, -1
		}
		maxA = -1
		for _, v := range ac {
			if v < 0 {
				continue
			}
			if getFunc(v) > getFunc(maxA) {
				maxA = v
			}
		}
		if maxA < 0 {
			break
		}

		maxB = -1
		for _, v := range bc {
			if v < 0 {
				continue
			}
			if getFunc(v) > getFunc(maxB) {
				maxB = v
			}
		}
		if maxB < 0 {
			break
		}

		ca, cb := cmpFunc(maxA), cmpFunc(maxB)
		if ca > cb {
			return 1, getIndex(a, maxA), getIndex(b, maxB)
		}
		if ca < cb {
			return -1, getIndex(a, maxA), getIndex(b, maxB)
		}
		ac = DelCards(ac, []int{maxA})
		bc = DelCards(bc, []int{maxB})
	}
	return 0, -1, -1
}

// CompareColorByLogic 依次比最大逻辑点数牌的花色大小
func CompareColorByLogic(a, b []int) int {
	n, _, _ := compareLine(a, b, ToLogic, ToColor)
	return n
}

func IndexCompareColorByLogic(a, b []int) (int, int, int) {
	return compareLine(a, b, ToLogic, ToColor)
}

// CompareLogic 依次比逻辑点数大小
func CompareLogic(a, b []int) int {
	n, _, _ := compareLine(a, b, ToLogic, ToLogic)
	return n
}

func IndexCompareLogic(a, b []int) (int, int, int) {
	return compareLine(a, b, ToLogic, ToLogic)
}

func CompareFirstLogic(a, b []int) int {
	if len(a) != 0 && len(b) != 0 {
		if ToLogic(a[0]) > ToLogic(b[0]) {
			return 1
		} else if ToLogic(a[0]) < ToLogic(b[0]) {
			return -1
		}
	}
	return 0
}

// Group 出牌组合
type Group struct {
	Head      [3]int
	Mid       [5]int
	End       [5]int
	PokerType int
}

func (p *Group) String() string {
	buf := strings.Builder{}
	buf.WriteString("\tHead:")
	buf.WriteString(PokerName(p.Head[0]))
	for _, v := range p.Head[1:] {
		buf.WriteString(",")
		buf.WriteString(PokerName(v))
	}
	buf.WriteString("\tMid:")
	buf.WriteString(PokerName(p.Mid[0]))
	for _, v := range p.Mid[1:] {
		buf.WriteString(",")
		buf.WriteString(PokerName(v))
	}
	buf.WriteString("\tEnd:")
	buf.WriteString(PokerName(p.End[0]))
	for _, v := range p.End[1:] {
		buf.WriteString(",")
		buf.WriteString(PokerName(v))
	}
	buf.WriteString(fmt.Sprintf("\tPokerType:%v", SpecialTypeName[p.PokerType]))
	return buf.String()
}

func thanT(c, cs []int) bool {
	num := 0
	for k, v := range c {
		if cs[k] == v {
			num++
		}
	}
	if len(c) == 3 && len(cs) == 3 && num == 3 {
		return true
	}
	if len(c) == 5 && len(cs) == 5 && num == 5 {
		return true
	}
	return false
}

type Logic struct {
	LaiZi []int
}

// GetType 获取牌型
// cards 牌
func (l *Logic) GetType(cards []int) int {
	return GetType(cards, l.LaiZi)
}

func (l *Logic) isLaiZi(c int) bool {
	if c < 0 {
		return false
	}
	for _, v := range l.LaiZi {
		if v < 0 {
			continue
		}
		if v == c {
			return true
		}
	}
	return false
}

func (l *Logic) SortMidAndEnd(cards *Group) *Group {
	if cards.Head[0] == -1 {
		return nil
	}
	a := l.GetType(cards.Head[:])
	b := l.GetType(cards.Mid[:])
	c := l.GetType(cards.End[:])
	if a < b || a < c {
		return nil // 牌型错了就不要了
	}

	if a == b {
		switch a {
		case PokersTypeThree:
			// 有癞子，癞子一定在三条中
			r1, c1 := FindMaxThreeAAA(cards.Head[:], l.LaiZi)
			r2, c2 := FindMaxThreeAAA(cards.Mid[:], l.LaiZi)
			if len(c1) > 0 && len(c2) > 0 {
				// 比三条
				n := CompareFirstLogic(c1, c2)
				if n == 1 {
					// 交换三条，结束
					var cp1 []int
					for k, v := range cards.Head {
						for i, n := range r1 {
							if v == n {
								cards.Head[k] = -1
								r1[i] = -1
								cp1 = append(cp1, n)
							}
						}
					}
					r1 = cp1
					var cp2 []int
					for k, v := range cards.Mid {
						for i, n := range r2 {
							if v == n {
								cards.Mid[k] = -1
								r2[i] = -1
								cp2 = append(cp2, n)
							}
						}
					}
					r2 = cp2
					for k, v := range cards.Head {
						if v == -1 {
							for m, n := range r2 {
								if n != -1 {
									cards.Head[k] = n
									r2[m] = -1
								}
							}
						}
					}
					for k, v := range cards.Mid {
						if v == -1 {
							for m, n := range r1 {
								if n != -1 {
									cards.Mid[k] = n
									r1[m] = -1
								}
							}
						}
					}
				} else if n == 0 { // 三条点数相同
					// 比逻辑点数
					changeMid := append(DelCards(cards.Mid[:], r2), c2...)
					n = CompareLogic(c1, changeMid)
					if n == 1 {
						// 不可能
					} else if n == 0 { // 逻辑点数相同
						// 比花色，比三条就行了
						//n, index1, index2 := IndexCompareColorByLogic(c1, c2)
						n = 0
						if n == 1 {
							// 花色交换，结束
							//if index1 >= 0 && index2 >= 0 {
							//	for k, v := range cards.Head {
							//		if v == r1[index1] {
							//			cards.Head[k] = -1
							//			break
							//		}
							//	}
							//	for k, v := range cards.Mid {
							//		if v == r2[index2] {
							//			cards.Mid[k] = -1
							//			break
							//		}
							//	}
							//	for k, v := range cards.Head {
							//		if v == -1 && r2[index2] >= 0 {
							//			cards.Head[k] = r2[index2]
							//			break
							//		}
							//	}
							//	for k, v := range cards.Mid {
							//		if v == -1 && r1[index1] >= 0 {
							//			cards.Mid[k] = r1[index1]
							//			break
							//		}
							//	}
							//}
						} else if n == 0 {
							// 比癞子数
							if l.LaiZiCount(r1) < l.LaiZiCount(r2) {
								// 中墩三条中的癞子和头墩三条中的非癞子牌交换一张，结束
								indexMid := -1
								indexHead := -1
								for k, v := range cards.Mid {
									if l.isLaiZi(v) {
										indexMid = k
										break
									}
								}
								for k, v := range cards.Head {
									if v >= 0 && !l.isLaiZi(v) {
										indexHead = k
										break
									}
								}
								if indexMid >= 0 && indexHead >= 0 {
									cards.Head[indexHead], cards.Mid[indexMid] = cards.Mid[indexMid], cards.Head[indexHead]
								}
							}
						}
					}
				}
			}

		case PokersTypePair: // 最多有一个癞子，并且癞子一定在对子中
			r1, c1 := FindMaxPairs(cards.Head[:], l.LaiZi)
			r2, c2 := FindMaxPairs(cards.Mid[:], l.LaiZi)
			if len(c1) > 0 && len(c2) > 0 {
				n := CompareFirstLogic(c1, c2)
				if n == 1 {
					// 交换对子，结束
					var cp1 []int
					for k, v := range cards.Head {
						for i, n := range r1 {
							if v == n {
								cards.Head[k] = -1
								r1[i] = -1
								cp1 = append(cp1, n)
							}
						}
					}
					r1 = cp1
					var cp2 []int
					for k, v := range cards.Mid {
						for i, n := range r2 {
							if v == n {
								cards.Mid[k] = -1
								r2[i] = -1
								cp2 = append(cp2, n)
							}
						}
					}
					r2 = cp2
					for k, v := range cards.Head {
						if v == -1 {
							for m, n := range r2 {
								if n != -1 {
									cards.Head[k] = n
									r2[m] = -1
								}
							}
						}
					}
					for k, v := range cards.Mid {
						if v == -1 {
							for m, n := range r1 {
								if n != -1 {
									cards.Mid[k] = n
									r1[m] = -1
								}
							}
						}
					}
				} else if n == 0 {
					// 比点数
					nHead := cards.Head
					nMid := cards.Mid
					for k, v := range nHead {
						if v < 0 {
							continue
						}
						if l.isLaiZi(v) {
							nHead[k] = ToLogic(c1[0]) + 13*3
							break
						}
					}
					for k, v := range nMid {
						if v < 0 {
							continue
						}
						if l.isLaiZi(v) {
							nHead[k] = ToLogic(c2[0]) + 13*3
							break
						}
					}
					n, index1, index2 := IndexCompareLogic(nHead[:], nMid[:])
					if n == 1 {
						// 最大逻辑点数牌交换，结束
						if index1 >= 0 && index2 >= 0 {
							cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
						}
					} else if n == 0 { // 点数相同
						// 比花色
						//n, index1, index2 := IndexCompareColorByLogic(nHead[:], nMid[:])
						n = 0
						if n == 1 {
							// 交换花色，结束
							//if index1 >= 0 && index2 >= 0 {
							//	cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
							//}
						} else if n == 0 {
							// 比癞子多少
							if l.LaiZiCount(r1) < l.LaiZiCount(r2) {
								// 中墩对子中有一个癞子，头墩没有癞子
								// 中墩对中的癞子和头墩对子中的非癞子牌交换一张，结束
								indexMid := -1
								indexHead := -1
								for k, v := range cards.Mid {
									if l.isLaiZi(v) {
										indexMid = k
										break
									}
								}
								for k, v := range cards.Head {
									if v >= 0 && v == r1[0] {
										indexHead = k
										break
									}
								}
								if indexMid >= 0 && indexHead >= 0 {
									cards.Head[indexHead], cards.Mid[indexMid] = cards.Mid[indexMid], cards.Head[indexHead]
								}
							}
						}
					}
				}
			}

		case PokersTypeOne:
			// 都不会有癞子
			n, index1, index2 := IndexCompareLogic(cards.Head[:], cards.Mid[:])
			if n == 1 {
				// 交换最大逻辑点数的牌
				if index1 >= 0 && index2 >= 0 {
					cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
				}
			} else if n == 0 {
				// 点数相同比花色
				//n, index1, index2 := IndexCompareColorByLogic(cards.Head[:], cards.Mid[:])
				//if n == 1 {
				//	// 交换最大花色的牌
				//	if index1 >= 0 && index2 >= 0 {
				//		cards.Head[index1], cards.Mid[index2] = cards.Mid[index2], cards.Head[index1]
				//	}
				//}
			}
		}
	}

	//换牌之后重新识别
	a = l.GetType(cards.Head[:])
	b = l.GetType(cards.Mid[:])
	c = l.GetType(cards.End[:])
	if a < b || a < c {
		return nil
	}

	if b < c {
		cards.Mid, cards.End = cards.End, cards.Mid
	} else if c == b {
		n := l.CompareFive(cards.Mid, cards.End)
		if n == 1 {
			cards.Mid, cards.End = cards.End, cards.Mid
		}
	}
	return cards
}

func (l *Logic) delPokers(poker []*Group) []*Group {
	if len(poker) == 0 {
		return nil
	}
	//去重
	for _, v := range poker {
		num := 0
		s := 0
		for i := 0; i < len(poker); i++ {
			if poker[i].Head[0] == -1 {
				continue
			}
			if thanT(poker[i].Head[:], v.Head[:]) {
				num++
			}
			if thanT(poker[i].Mid[:], v.Mid[:]) {
				num++
			}
			if thanT(poker[i].End[:], v.End[:]) {
				num++
			}
			if num == 3 {
				s++
				if s > 1 {
					poker[i] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
				}
			}
			num = 0
		}
	}
	//修正
	for k, v := range poker {
		if v.Head[0] != -1 {
			a := l.SortMidAndEnd(v)
			if a != nil {
				poker[k] = a
			} else {
				poker[k] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
			}
		}
	}
	return poker
}

// 查找牌型 返回 (是否找到，找到的牌，找到牌之后剩余的牌)
func (l *Logic) getPokerTypeCards(cards []int, n int) (b bool, card, remainCards []int) {
	if len(cards) < 3 {
		return
	}
	switch n {
	case PokersTypeFive:
		card, _ := FindMaxFive(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeStraightFlush:
		//找同花顺
		card, _ := FindMaxSameColorFlush(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeFour:
		//找铁支
		card, _ := FindMaxFourAAAA(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeFullHouse:
		//找葫芦
		card, _ := FindMaxGourdCards(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeFlush:
		//找同花
		card, _ := FindMaxSameColors(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeStraight:
		//找顺子
		card, _ := FindMaxFlush(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeThree:
		//找三条
		card, _ := FindMaxThreeAAA(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	case PokersTypeTwoPairs:
		//找对子
		card, _ := FindMaxPairs(cards, l.LaiZi)
		if len(card) != 0 {
			return true, card, DelCards(cards, card)
		}
	}

	return false, card, remainCards
}

func (l *Logic) findAllCombine(cards [13]int) (pokers []*Group) {
	copyCards := make([]int, 13)
	copy(copyCards, cards[:])
	for i := 0; i < 8; i++ {
		pokers = append(pokers, &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}})
	}
	poker := &Group{}
	index := PokersTypeFive
	for zz := 0; zz < 10; zz++ {
		for _, v := range pokers {
			if v != nil && v.Head[0] == -1 {
				poker = v
				break
			}
		}
		// 从尾墩往前，从大到小牌型顺序获取组合
		for i := index; i < PokersTypePair; i++ {
			b, card, cards2 := l.getPokerTypeCards(copyCards, i)
			if b {
				//fmt.Printf("找到牌型%v----%v\n", PokersShow(card), PokersShow(cards2))
				copyCards = cards2
				if poker.End[0] == -1 {
					if i != PokersTypeTwoPairs {
						copy(poker.End[:], card)
					} else {
						if len(copyCards) == 11 { // 对子
							copy(poker.End[2:], card)
						} else if len(copyCards) == 9 { // 两对
							copy(poker.End[:], card)
						} else {
							copyCards = append(copyCards, card...)
							i++
						}
					}
					i--
				} else if poker.Mid[0] == -1 {
					if i == PokersTypeFive || i == PokersTypeStraightFlush || i == PokersTypeFullHouse || i == PokersTypeFlush || i == PokersTypeStraight {
						copy(poker.Mid[:], card)
					} else if i == PokersTypeFour {
						if len(copyCards) != 1 {
							copy(poker.Mid[:], card)
						} else {
							copyCards = append(copyCards, card...)
							i++
						}
					} else if i == PokersTypeThree {
						al := len(copyCards)
						if al == 5 || al == 6 || al == 7 {
							copy(poker.Mid[:], card)
						} else {
							copyCards = append(copyCards, card...)
							i++
						}
					} else if i == PokersTypeTwoPairs {
						al := len(copyCards)
						if al == 7 || al == 6 {
							copy(poker.Mid[2:], card)
						} else if al == 5 || al == 4 {
							copy(poker.Mid[:], card)
						} else if al == 8 {
							copy(poker.Mid[:], card)
						} else {
							copyCards = append(copyCards, card...)
							i++
						}
					} else {
						i++
					}
					i--
				} else {
					if i == PokersTypeTwoPairs {
						if len(copyCards) == 2 || len(copyCards) == 1 {
							copy(poker.Head[:], card)
						} else if len(copyCards) == 4 || len(copyCards) == 5 {
							copy(poker.Head[:], card)
							copyCards = DelCards(copyCards, card[:])
						} else {
							copyCards = append(copyCards, card...)
							i++
						}
					} else {
						copyCards = append(copyCards, card...)
						i++
					}
					i--
				}
				//fmt.Printf("填充后%v\n", poker)
			}
		}
		//fmt.Println("-->", poker)
		if poker.End[2] == -1 {
			for k, v := range pokers {
				if v.End[2] == -1 {
					pokers[k] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
				}
			}
			pokers = l.delPokers(pokers)
			return
		}
		//fmt.Println(poker)
		// 填充剩余位置的牌
		ci := 0
		for m, n := range poker.End {
			if n == -1 && ci < len(copyCards) {
				poker.End[m] = copyCards[ci]
				ci++
			}
		}
		for m, n := range poker.Mid {
			if n == -1 && ci < len(copyCards) {
				poker.Mid[m] = copyCards[ci]
				ci++
			}
		}
		for m, n := range poker.Head {
			if n == -1 && ci < len(copyCards) {
				poker.Head[m] = copyCards[ci]
				ci++
			}
		}
		//fmt.Println(poker)
		//fmt.Println()
		if index < PokersTypePair {
			index = l.GetType(poker.End[:]) + 1
			copyCards = make([]int, 13)
			copy(copyCards, cards[:])
			for k, v := range pokers {
				if l.GetType(v.End[:]) == 9 {
					pokers[k] = &Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
					break
				}
			}
		} else {
			break
		}
	}
	pokers = l.delPokers(pokers)
	return
}

// GetAllCombine 获取所有组合
// 特殊组合的 PokerType > 0，无牌数据，数据为 -1
// 普通组合的 PokerType = 0，有牌数据
func (l *Logic) GetAllCombine(cards [13]int) (pokers []*Group) {
	tp := l.GetSpecialType(cards)
	if tp != 0 {
		poker := Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}}
		poker.PokerType = tp
		pokers = append(pokers, &poker)
	}
	aps := l.findAllCombine(cards)
	if len(aps) != 0 {
		for _, v := range aps {
			pokers = append(pokers, v)
		}
	}
	return
}

// Suggest 获取所有组合，带牌型标记
func (l *Logic) Suggest(cards [13]int) map[int]*Group {
	m := make(map[int]*Group)
	pokers := l.GetAllCombine(cards)
	if pokers != nil {
		for _, v := range pokers {
			num := 0
			if v != nil && v.PokerType != 0 {
				m[v.PokerType*1000000] = v
			}
			if v != nil && v.PokerType == 0 && v.Head[0] != -1 && v.Head[1] != -1 && v.Head[2] != -1 {
				num += l.GetType(v.Head[:]) * 10000
				num += l.GetType(v.Mid[:]) * 100
				num += l.GetType(v.End[:])
				m[num] = v
			}
		}
	}
	return m
}

func (l *Logic) GetSpecialType(cards [13]int) int {
	return GetSpecialType(cards, l.LaiZi)
}

func (l *Logic) LaiZiCount(cards []int) int {
	var ret int
	for _, v := range cards {
		if v < 0 {
			continue
		}
		for _, vv := range l.LaiZi {
			if vv < 0 {
				continue
			}
			if v == vv {
				ret++
				break
			}
		}
	}
	return ret
}

// 将癞子牌变成 黑桃A
func (l *Logic) laiZiTo51(card []int) {
	for k, v := range card {
		if v < 0 {
			continue
		}
		for _, vv := range l.LaiZi {
			if vv < 0 {
				continue
			}
			if v == vv {
				card[k] = 51
				break
			}
		}
	}
}

func (l *Logic) CompareHead(c, cs [3]int) int {
	a := l.GetType(c[:])
	b := l.GetType(cs[:])
	if a < b {
		return 1
	} else if a > b {
		return -1
	}

	var r1, r2 []int
	var c1, c2 []int
	switch a {
	case PokersTypeThree:
		r1, c1 = FindMaxThreeAAA(c[:], l.LaiZi)
		r1, c2 = FindMaxThreeAAA(cs[:], l.LaiZi)

	case PokersTypePair:
		r1, c1 = FindMaxPairs(c[:], l.LaiZi)
		r2, c2 = FindMaxPairs(cs[:], l.LaiZi)

	case PokersTypeOne:
		// 乌龙肯定不会有癞子
		n := CompareLogic(c[:], cs[:])
		if n != 0 {
			return n
		}
		n = CompareColorByLogic(c[:], cs[:])
		if n != 0 {
			return n
		}
		return 0
	}

	// 比点数
	n := CompareFirstLogic(c1, c2)
	if n != 0 {
		return n
	}
	re1 := DelCards(c[:], r1)
	l.laiZiTo51(re1)
	c1 = append(c1, re1...)
	re2 := DelCards(cs[:], r2)
	l.laiZiTo51(re2)
	c2 = append(c2, re2...)
	n = CompareLogic(c1, c2)
	if n != 0 {
		return n
	}
	// 比花色
	//n = CompareColorByLogic(c1, c2)
	//if n != 0 {
	//	return n
	//}
	// 比癞子数
	z1, z2 := l.LaiZiCount(c[:]), l.LaiZiCount(cs[:])
	if z1 < z2 {
		return 1
	}
	if z1 > z2 {
		return -1
	}
	return 0
}

func (l *Logic) CompareFive(c, cs [5]int) int {
	a := l.GetType(c[:])
	b := l.GetType(cs[:])
	if a < b {
		return 1
	} else if a > b {
		return -1
	}

	// 牌型相同,五张牌相比
	switch a {
	case PokersTypeFive:
		_, c1 := FindMaxFive(c[:], l.LaiZi)
		_, c2 := FindMaxFive(cs[:], l.LaiZi)
		// 比点数
		n := CompareFirstLogic(c1, c2)
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypeStraightFlush:
		_, c1 := FindMaxSameColorFlush(c[:], l.LaiZi)
		_, c2 := FindMaxSameColorFlush(cs[:], l.LaiZi)
		// 比点数
		// 5 4 3 2 A
		ch1, ch2 := false, false
		if ToPoint(c1[0]) == 5 {
			ch1 = true
		}
		if ToPoint(c2[0]) == 5 {
			ch2 = true
		}
		if ch1 && ch2 {
			// 比花色
			//n := CompareColorByLogic(c1, c2)
			//if n != 0 {
			//	return n
			//}
		} else if !ch1 && !ch2 {
			n := CompareLogic(c1, c2)
			if n != 0 {
				return n
			}
			// 比花色
			//n = CompareColorByLogic(c1, c2)
			//if n != 0 {
			//	return n
			//}
		} else {
			if ch1 {
				return -1
			}
			return 1
		}

	case PokersTypeFour:
		r1, c1 := FindMaxFourAAAA(c[:], l.LaiZi)
		r2, c2 := FindMaxFourAAAA(cs[:], l.LaiZi)
		// 比点数
		n := CompareFirstLogic(c1, c2)
		if n != 0 {
			return n
		}
		re1 := DelCards(c[:], r1)
		l.laiZiTo51(re1)
		c1 = append(c1, re1...)
		re2 := DelCards(cs[:], r2)
		l.laiZiTo51(re2)
		c2 = append(c2, re2...)
		n = CompareLogic(c1, c2)
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypeFullHouse:
		_, c1 := FindMaxGourdCards(c[:], l.LaiZi)
		_, c2 := FindMaxGourdCards(cs[:], l.LaiZi)
		// 比点数
		n := CompareFirstLogic(c1, c2)
		if n != 0 {
			return n
		}
		n = CompareFirstLogic(c1[3:], c2[3:])
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypeFlush:
		_, c1 := FindMaxSameColors(c[:], l.LaiZi)
		_, c2 := FindMaxSameColors(cs[:], l.LaiZi)
		// 比点数
		n := CompareLogic(c1, c2)
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypeStraight:
		_, c1 := FindMaxFlush(c[:], l.LaiZi)
		_, c2 := FindMaxFlush(cs[:], l.LaiZi)
		// 比点数
		// 5 4 3 2 A
		ch1, ch2 := false, false
		if ToPoint(c1[0]) == 5 {
			ch1 = true
		}
		if ToPoint(c2[0]) == 5 {
			ch2 = true
		}
		if ch1 && ch2 {
			// 比花色
			//n := CompareColorByLogic(c1, c2)
			//if n != 0 {
			//	return n
			//}
		} else if !ch1 && !ch2 {
			n := CompareLogic(c1, c2)
			if n != 0 {
				return n
			}
			// 比花色
			//n = CompareColorByLogic(c1, c2)
			//if n != 0 {
			//	return n
			//}
		} else {
			if ch1 {
				return -1
			}
			return 1
		}

	case PokersTypeThree:
		r1, c1 := FindMaxThreeAAA(c[:], l.LaiZi)
		r2, c2 := FindMaxThreeAAA(cs[:], l.LaiZi)
		// 比点数
		n := CompareFirstLogic(c1, c2)
		if n != 0 {
			return n
		}
		re1 := DelCards(c[:], r1)
		l.laiZiTo51(re1)
		c1 = append(c1, re1...)
		re2 := DelCards(cs[:], r2)
		l.laiZiTo51(re2)
		c2 = append(c2, re2...)
		n = CompareLogic(c1, c2)
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypeTwoPairs:
		r1, c1 := FindMaxPairs(c[:], l.LaiZi)
		r2, c2 := FindMaxPairs(cs[:], l.LaiZi)
		// 比点数
		n := CompareFirstLogic(c1, c2)
		if n != 0 {
			return n
		}
		r12, c12 := FindMaxPairs(DelCards(c[:], r1), l.LaiZi)
		r22, c22 := FindMaxPairs(DelCards(cs[:], r2), l.LaiZi)
		n = CompareFirstLogic(c12, c22)
		if n != 0 {
			return n
		}

		c1 = append(c1, c12...)
		c2 = append(c2, c22...)

		re1 := DelCards(c[:], append(r1, r12...))
		l.laiZiTo51(re1)
		c1 = append(c1, re1...)
		re2 := DelCards(cs[:], append(r2, r22...))
		l.laiZiTo51(re2)
		c2 = append(c2, re2...)
		n = CompareLogic(c1, c2)
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypePair:
		r1, c1 := FindMaxPairs(c[:], l.LaiZi)
		r2, c2 := FindMaxPairs(cs[:], l.LaiZi)
		// 比点数
		n := CompareFirstLogic(c1, c2)
		if n != 0 {
			return n
		}
		re1 := DelCards(c[:], r1)
		l.laiZiTo51(re1)
		c1 = append(c1, re1...)
		re2 := DelCards(cs[:], r2)
		l.laiZiTo51(re2)
		c2 = append(c2, re2...)
		n = CompareLogic(c1, c2)
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c1, c2)
		//if n != 0 {
		//	return n
		//}

	case PokersTypeOne:
		// 乌龙不会有癞子
		// 比点数
		n := CompareLogic(c[:], cs[:])
		if n != 0 {
			return n
		}
		// 比花色
		//n = CompareColorByLogic(c[:], cs[:])
		//if n != 0 {
		//	return n
		//}
		return 0
	}

	// 比癞子数
	z1, z2 := l.LaiZiCount(c[:]), l.LaiZiCount(cs[:])
	if z1 < z2 {
		return 1
	}
	if z1 > z2 {
		return -1
	}
	return 0
}

func (l *Logic) IsDP(head [3]int, mid, end [5]int) bool {
	if l.CompareFive(mid, end) > 0 {
		return true
	}

	h := l.GetType(head[:])
	m := l.GetType(mid[:])
	if h < m {
		return true
	}

	if h == m { // 牌型相同，比点数，比癞子
		switch h {
		case PokersTypeThree: // 如果有癞子，癞子一定在三条里
			r1, c1 := FindMaxThreeAAA(head[:], l.LaiZi)
			r2, c2 := FindMaxThreeAAA(mid[:], l.LaiZi)
			// 比点数
			n := CompareFirstLogic(c1, c2)
			if n != 0 {
				return n == 1
			}
			// 比最大牌点数
			changeMid := append(DelCards(mid[:], r2), c2...)
			n = CompareLogic(c1, changeMid)
			if n != 0 {
				return n == 1
			}
			// 比花色
			//n = CompareColorByLogic(c1, changeMid)
			//if n != 0 {
			//	return n == 1
			//}
			// 比癞子数
			z1, z2 := l.LaiZiCount(r1), l.LaiZiCount(r2)
			if z1 < z2 {
				return true
			}
			if z1 > z2 {
				return false
			}

		case PokersTypePair: // 如果有癞子，癞子一定在对子中
			r1, c1 := FindMaxPairs(head[:], l.LaiZi)
			r2, c2 := FindMaxPairs(mid[:], l.LaiZi)
			// 比点数
			n := CompareFirstLogic(c1, c2)
			if n != 0 {
				return n == 1
			}
			// 比最大牌点数
			changeMid := append(DelCards(mid[:], r2), c2...)
			n = CompareLogic(c1, changeMid)
			if n != 0 {
				return n == 1
			}
			// 比花色
			//n = CompareColorByLogic(c1, changeMid)
			//if n != 0 {
			//	return n == 1
			//}
			// 比癞子数
			z1, z2 := l.LaiZiCount(r1), l.LaiZiCount(r2)
			if z1 < z2 {
				return true
			}
			if z1 > z2 {
				return false
			}

		case PokersTypeOne: // 乌龙不会有癞子
			// 比点数
			n := CompareLogic(head[:], mid[:])
			if n != 0 {
				return n == 1
			}
			// 比花色
			//n = CompareColorByLogic(head[:], mid[:])
			//if n != 0 {
			//	return n == 1
			//}
		}
	}

	return false
}
