package thirteen import ( "sort" ) // DelCards 从cards里边删除arr func DelCards(cards []int, arr []int) []int { c := make([]int, len(cards)) s := make([]int, len(arr)) copy(c, cards) copy(s, arr) for i := 0; i < len(arr); i++ { for k, v := range c { a := false for m, n := range s { if v == n { a = true c = append(c[:k], c[k+1:]...) s = append(s[:m], s[m+1:]...) break } } if a { break } } if len(s) == 0 { break } } return c } func getLaiZiCards(cards []int, lai []int) []int { var ret []int for k, v := range cards { if v < 0 { continue } for _, vv := range lai { if vv < 0 { continue } if v == vv { ret = append(ret, v) cards[k] = -1 break } } } return ret } func remainCards(cards, lai []int) (remainCount int, cardsLaiZi []int, cardsCount [20]int) { ret := [20]int{} count := 0 cardsLaiZi = getLaiZiCards(cards, lai) for _, v := range cards { if v < 0 { continue } count++ ret[ToLogic(v)]++ } return count, cardsLaiZi, ret } func findCardByLogic(cards []int, logicValue, count int) []int { var ret []int for k, v := range cards { if v < 0 { continue } if ToLogic(v) == logicValue { ret = append(ret, v) cards[k] = -1 } if len(ret) >= count { break } } return ret } func findCardByLogic2(cards []int, logicValue, count int) []int { var ret []int for _, v := range cards { if v < 0 { continue } if ToLogic(v) == logicValue { ret = append(ret, v) //cards[k] = -1 } if len(ret) >= count { break } } return ret } // FindMaxPairs 找最大对子 func FindMaxPairs(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, cardsCount := remainCards(cs, lai) for i := 12; i >= 0; i-- { switch cardsCount[i] { case 0: if len(cardsLaiZi) >= 2 { ret = cardsLaiZi[:2] change = []int{51, 51} // AA return } case 1: if len(cardsLaiZi) > 0 { ret = append(findCardByLogic(cs, i, 1), cardsLaiZi[0]) change = []int{ret[0], i + 3*13} return } default: ret = findCardByLogic(cs, i, 2) change = []int{ret[0], ret[1]} return } } return } // FindMaxThreeAAA 找最大三条 func FindMaxThreeAAA(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, cardsCount := remainCards(cs, lai) for i := 12; i >= 0; i-- { switch cardsCount[i] { case 0: if len(cardsLaiZi) >= 3 { ret = cardsLaiZi[:3] change = []int{51, 51, 51} //AAA return } case 1: if len(cardsLaiZi) > 1 { ret = append(findCardByLogic(cs, i, 1), cardsLaiZi[:2]...) change = []int{ret[0], i + 3*13, i + 3*13} return } case 2: if len(cardsLaiZi) > 0 { ret = append(findCardByLogic(cs, i, 2), cardsLaiZi[0]) change = []int{ret[0], ret[1], i + 3*13} return } default: ret = findCardByLogic(cs, i, 3) change = []int{ret[0], ret[1], ret[2]} return } } return } // FindMaxFlush 找最大顺子 // 逆序返回,癞子填充 func FindMaxFlush(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, cardsCount := remainCards(cs, lai) for i := 12; i >= 4; i-- { // 起始顺子逻辑值 var a, b int for j := 0; j < 5; j++ { // 顺子都是5个 if cardsCount[i-j] > 0 { a++ } else { b++ } } if b <= len(cardsLaiZi) { // 癞子足够 r := [5]int{} r2 := [5]int{} l := 0 for j := 0; j < 5; j++ { if cardsCount[i-j] > 0 { r[j] = findCardByLogic(cs, i-j, 1)[0] r2[j] = r[j] } else { r[j] = cardsLaiZi[l] l++ r2[j] = i - j + 3*13 } } ret = r[:] change = r2[:] return } } // 找 A,2,3... var a, b int for i := 0; i < 4; i++ { if cardsCount[i] > 0 { a++ } else { b++ } } if cardsCount[12] > 0 { a++ } else { b++ } if b <= len(cardsLaiZi) { // 癞子足够 r := [5]int{} r2 := [5]int{} l := 0 for i := 3; i >= 0; i-- { if cardsCount[i] > 0 { r[3-i] = findCardByLogic(cs, i, 1)[0] r2[3-i] = r[3-i] } else { r[3-i] = cardsLaiZi[l] l++ r2[3-i] = i + 3*13 } } if cardsCount[12] > 0 { r[4] = findCardByLogic(cs, 12, 1)[0] r2[4] = r[4] } else { r[4] = cardsLaiZi[l] l++ r2[4] = 12 + 3*13 } ret = r[:] change = r2[:] return } return } // FindMaxSameColors 找最大同花 // 逆序返回,癞子追加 func FindMaxSameColors(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) //_, cardsLaiZi, _ := remainCards(cs, lai) cardsLaiZi := getLaiZiCards(cs, lai) m := [4][]int{} for _, v := range cs { if v >= 0 { m[ToColor(v)] = append(m[ToColor(v)], v) } } for i := 3; i >= 0; i-- { if len(m[i])+len(cardsLaiZi) >= 5 { if len(m[i]) >= 5 { ret = m[i][:5] change = make([]int, 5) copy(change, ret) return } ret = append(m[i], cardsLaiZi[:5-len(m[i])]...) change = make([]int, 5) copy(change, m[i]) for j := len(m[i]); j < 5; j++ { change[j] = 12 + i*13 } return } } return } // FindMaxGourdCards 找最大葫芦 // 三条在前对子在后 func FindMaxGourdCards(cards, lai []int) (ret []int, change []int) { // 找最大三条,再找最大对子 r, c := FindMaxThreeAAA(cards, lai) if len(r) == 0 { return } rr, cc := FindMaxPairs(DelCards(cards, r), lai) if len(rr) == 0 { return } return append(r, rr...), append(c, cc...) } // FindMaxFourAAAA 找最大铁支 func FindMaxFourAAAA(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, cardsCount := remainCards(cs, lai) for i := 12; i >= 0; i-- { switch cardsCount[i] { case 0: if len(cardsLaiZi) >= 4 { ret = cardsLaiZi[:4] change = []int{51, 51, 51, 51} return } case 1: if len(cardsLaiZi) >= 3 { ret = append(findCardByLogic(cs, i, 1), cardsLaiZi[:3]...) change = []int{ret[0], i + 3*13, i + 3*13, i + 3*13} return } case 2: if len(cardsLaiZi) > 1 { ret = append(findCardByLogic(cs, i, 2), cardsLaiZi[:2]...) change = []int{ret[0], ret[1], i + 3*13, i + 3*13} return } case 3: if len(cardsLaiZi) > 0 { ret = append(findCardByLogic(cs, i, 3), cardsLaiZi[0]) change = []int{ret[0], ret[1], ret[2], i + 3*13} return } default: ret = findCardByLogic(cs, i, 4) change = make([]int, 4) copy(change, ret) return } } return } // FindMaxSameColorFlush 找最大同花顺 func FindMaxSameColorFlush(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, _ := remainCards(cs, lai) m := [4][]int{} for _, v := range cs { if v >= 0 { m[ToColor(v)] = append(m[ToColor(v)], v) } } for i := 3; i >= 0; i-- { a := append(m[i], cardsLaiZi...) r, c := FindMaxFlush(a, lai) if len(r) > 0 { // 修改一下花色 for j := 0; j < 5; j++ { c[j] = ToLogic(c[j]) + i*13 } return r, c } } return } // FindAllFlush 找所有顺子 func FindAllFlush(cards []int, lai []int) [][]int { var ret [][]int cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, cardsCount := remainCards(cs, lai) for i := 12; i >= 4; i-- { // 起始顺子逻辑值 var a, b int for j := 0; j < 5; j++ { // 顺子都是5个 if cardsCount[i-j] > 0 { a++ } else { b++ } } if b <= len(cardsLaiZi) { // 癞子足够 r := [5]int{} //r2 := [5]int{} l := 0 for j := 0; j < 5; j++ { if cardsCount[i-j] > 0 { r[j] = findCardByLogic2(cs, i-j, 1)[0] //r2[j] = r[j] } else { r[j] = cardsLaiZi[l] l++ //r2[j] = i - j + 3*13 } } ret = append(ret, r[:]) } } // 找 A,2,3... var a, b int for i := 0; i < 4; i++ { if cardsCount[i] > 0 { a++ } else { b++ } } if cardsCount[12] > 0 { a++ } else { b++ } if b <= len(cardsLaiZi) { // 癞子足够 r := [5]int{} //r2 := [5]int{} l := 0 for i := 3; i >= 0; i-- { if cardsCount[i] > 0 { r[3-i] = findCardByLogic2(cs, i, 1)[0] //r2[3-i] = r[3-i] } else { r[3-i] = cardsLaiZi[l] l++ //r2[3-i] = i + 3*13 } } if cardsCount[12] > 0 { r[4] = findCardByLogic2(cs, 12, 1)[0] //r2[4] = r[4] } else { r[4] = cardsLaiZi[l] l++ //r2[4] = 12 + 3*13 } ret = append(ret, r[:]) } return ret } // FindAllSameColorFlush 找所有同花顺 func FindAllSameColorFlush(cards []int, lai []int) [][]int { var ret [][]int cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, _ := remainCards(cs, lai) m := [4][]int{} for _, v := range cs { if v >= 0 { m[ToColor(v)] = append(m[ToColor(v)], v) } } for i := 3; i >= 0; i-- { a := append(m[i], cardsLaiZi...) r := FindAllFlush(a, lai) ret = append(ret, r...) } return ret } // FindMaxFive 找最大五同 func FindMaxFive(cards, lai []int) (ret []int, change []int) { cs := make([]int, len(cards)) copy(cs, cards) sort.Sort(sort.Reverse(sort.IntSlice(cs))) _, cardsLaiZi, cardsCount := remainCards(cs, lai) for i := 12; i >= 0; i-- { switch cardsCount[i] { case 0: if len(cardsLaiZi) >= 5 { ret = cardsLaiZi[:5] change = []int{51, 51, 51, 51} return } case 1: if len(cardsLaiZi) >= 4 { ret = append(findCardByLogic(cs, i, 1), cardsLaiZi[:4]...) change = []int{ret[0], i + 3*13, i + 3*13, i + 3*13, i + 3*13} return } case 2: if len(cardsLaiZi) >= 3 { ret = append(findCardByLogic(cs, i, 2), cardsLaiZi[:3]...) change = []int{ret[0], ret[1], i + 3*13, i + 3*13, i + 3*13} return } case 3: if len(cardsLaiZi) >= 2 { ret = append(findCardByLogic(cs, i, 3), cardsLaiZi[:2]...) change = []int{ret[0], ret[1], ret[2], i + 3*13, i + 3*13} return } case 4: if len(cardsLaiZi) >= 1 { ret = append(findCardByLogic(cs, i, 3), cardsLaiZi[0]) change = []int{ret[0], ret[1], ret[2], ret[3], i + 3*13} return } default: ret = findCardByLogic(cs, i, 5) change = make([]int, 5) copy(change, ret) return } } return } func isType(cards []int, lai []int, n int) bool { if len(cards) < 3 { return false } switch n { case PokersTypeFive: //找五同 card, _ := FindMaxFive(cards, lai) if len(card) != 0 { return true } case PokersTypeStraightFlush: //找同花顺 card, _ := FindMaxSameColorFlush(cards, lai) if len(card) != 0 { return true } case PokersTypeFour: //找铁支 card, _ := FindMaxFourAAAA(cards, lai) if len(card) != 0 { return true } case PokersTypeFullHouse: //找葫芦 card, _ := FindMaxGourdCards(cards, lai) if len(card) != 0 { return true } case PokersTypeFlush: //找同花 card, _ := FindMaxSameColors(cards, lai) if len(card) != 0 { return true } case PokersTypeStraight: //找顺子 card, _ := FindMaxFlush(cards, lai) if len(card) != 0 { return true } case PokersTypeThree: //找三条 card, _ := FindMaxThreeAAA(cards, lai) if len(card) != 0 { return true } case PokersTypeTwoPairs: //找两对子 if len(cards) == 3 { return false } card, _ := FindMaxPairs(cards, lai) if len(card) != 0 { card1, _ := FindMaxPairs(DelCards(cards, card), lai) if len(card1) != 0 { return true } } case PokersTypePair: //找对子 card, _ := FindMaxPairs(cards, lai) if len(card) != 0 { return true } } return false } func GetType(cards []int, lai []int) int { if len(cards) < 3 { return 0 } b := PokersTypeFive if len(cards) == 3 { b = PokersTypeThree } for i := b; i < PokersTypeMax; i++ { if isType(cards, lai, i) { return i } } return PokersTypeOne }