game_sync/gamerule/thirteen/find.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
}