600 lines
12 KiB
Go
600 lines
12 KiB
Go
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
|
|
}
|