写了一个简单的牌型检测算法,还请方家多指点
本方法没有使用 1-5 为花色 1-13 表示牌点的方法 而是使用 1-54 分别代表方块1 -大王来表示每张牌
package main
import (
"fmt"
"time"
"math/rand"
"runtime"
"log"
)
//所有扑克牌id
//1,2,3,4,5,6,7,8,9,10,11,12,13
//14,15,16,17,18,19,20,21,22,23,24,25,26
//27,28,29,30,31,32,33,34,35,36,37,38,39
//40,.41,42,43,44,45,46,47,48,49,50,51,52
//53,54
const (
_ =iota
CARD_TYPE_SINGLE //单牌
CARD_TYPE_TWO //对牌
CARD_TYPE_THREE // 三张
CARD_TYPE_THREE_ONE // 三带1
CARD_TYPE_THREE_TWO // 三带2
CARD_TYPE_SING_SHUN // 单顺
CARD_TYPE_TWO_SHUN //双顺
CARD_TYPE_THREE_SHUN //三顺
CARD_TYPE_AIR_SINGLE // 飞机带单
CARD_TYPE_AIR_TWO // 飞机带双
CARD_TYPE_FOUR_TOW // 四带二
CARD_TYPE_BOOM // 炸弹
CARD_TYPE_ROCKET //火箭
)
//统计多有各牌点的张数
func getPointNum(arr []int)map[int][]int {
cardMap := make(map[int]int)
for _, v :=range arr {
_, id := getColorAndID(v)
num, ok := cardMap[id]
if !ok {
cardMap[id] =1
}
cardMap[id] = num +1
}
detailMap := make(map[int][]int)
for id, num :=range cardMap {
detailMap[num] = append(detailMap[num], id)
}
return detailMap
}
//计算牌型
//牌点为(1-54)
//传入的牌是有序的
func getCardType(arr []int) int {
detailMap:=getPointNum(arr)
len1:= len(detailMap[1])
len2 := len(detailMap[2])
len3 := len(detailMap[3])
len4 := len(detailMap[4])
switch len(detailMap) {
case 1:
if len1 ==1 {//单牌
return CARD_TYPE_SINGLE
}else if len1 ==2 && arr[0]==53 &&arr[1]==54 {
return CARD_TYPE_ROCKET //火箭
}else if len2 ==1 {
return CARD_TYPE_TWO //对子
}else if len3 ==1 {
return CARD_TYPE_THREE //三张
}else if len1 >=5 {
fmt.Println("detail",detailMap[1],isSort(detailMap[1]))
if !isSort(detailMap[1]) {
return -1
}
return CARD_TYPE_SING_SHUN //单顺
}else if len2 >=3 {
if !isSort(detailMap[2]) {
return -1
}
return CARD_TYPE_TWO_SHUN //双顺
}else if len3 >=2 {//三顺
if isSort(detailMap[3]) {
return CARD_TYPE_THREE_SHUN
}else {// 4,5,6 ,8 飞机带单
if len3 ==4 {
m:=splitSlice(detailMap[3])
if len(m)==2 &&( (len(m[0])==1 && isSort(m[1])) || (len(m[1])==1 && isSort(m[0])) ) {
return CARD_TYPE_AIR_SINGLE
}
return -1
}
}
}else if len4==1 {
return CARD_TYPE_BOOM
}else {
return -1
}
case 2:
if len1==1 && len3 ==1{
return CARD_TYPE_THREE_ONE //三带单
}else if len2 ==1 && len3 ==1{
return CARD_TYPE_THREE_TWO //三带对
}else if len4==1 && (len1 ==2 || len2==2){
return CARD_TYPE_FOUR_TOW
}else if len3 == len1 && len3 !=0 {
if !isSort(detailMap[3]) {
return -1
}
return CARD_TYPE_AIR_SINGLE //飞机带单
}else if (len3==len2 || len3 == len4*2) && len3 !=0 {
if !isSort(detailMap[3]) {
return -1
}
return CARD_TYPE_AIR_TWO //飞机带对
}else if len3==5 && len1==1 {// 4,5,6,7,9 +1单
m:=splitSlice(detailMap[3])
if len(m)==2 &&( (len(m[0])==1 && isSort(m[1])) || (len(m[1])==1 && isSort(m[0])) ) {
return CARD_TYPE_AIR_SINGLE
}
return -1
}else if len3 == len4*4 && len3 !=0{//4,5,6,7 +炸弹
if isSort(detailMap[3]) {
return CARD_TYPE_AIR_SINGLE
}
return -1
}
return -1
case 3:
if (len4*2 + len2 )== len3 && len3 !=0 {
if !isSort(detailMap[3]) {
return -1
}
return CARD_TYPE_AIR_TWO
}else if len3 ==5 &&len4 ==1 && len1==1{//4,5,6,7,8 +炸弹 +1
return CARD_TYPE_AIR_SINGLE
}
return -1
case 4:
return -1
}
return -1
}
//检查数组是否连续
func isSort(arr []int)bool {
randomQuickSort(arr,0,len(arr))
for i:=0;i
if arr[i+1] -arr[i] >1 {
return false
}
}
return true
}
获取一张牌的花色和牌点
func getColorAndID(point int) (color int,id int) {
color1 := point /13
if point %13 ==0 {
color = color1
}else {
color = color1+1
}
point2 := point %13
if point >=53{
id = point
}else if point2 ==0 {
id =13
}else if point2 ==1 {
id =14
}else if point2 ==2{
id =15
}else {
id = point2
}
return
}
快速排序
func randomQuickSort(list []int, start, end int) {
if end-start >1 {
// get the pivot
mid := randomPartition(list, start, end)
randomQuickSort(list, start, mid)
randomQuickSort(list, mid+1, end)
}
}
func randomPartition(list []int, begin, end int) int {
i := randInt(begin, end)
list[i], list[begin] = list[begin], list[i]
return partition(list, begin, end)
}
func partition(list []int, begin, end int) (i int) {
cValue := list[begin]
i = begin
for j := i +1; j < end; j++ {
if list[j] < cValue {
i++
list[j], list[i] = list[i], list[j]
}
}
list[i], list[begin] = list[begin], list[i]
return i
}
func randInt(min, max int) int {
rand.Seed(time.Now().UnixNano())
return min + rand.Intn(max-min)
}
//将有序切片切割为有序与无序切片
//4,5,6,8
func splitSlice(arr []int)map[int][]int {
l := len(arr)
m := make(map[int][]int)
l3 :=0
for i :=0; i < l-1; i++ {
l2 := len(m)
if arr[i+1]-arr[i] >1 {
fmt.Println(i+1)
m[l2] = arr[l3:i+1]
l3 = i+1
}
}
m[len(m)] = arr[l3:]
return m
}
//所有扑克牌id
//1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11,12,13
//14,15,16,17,18,19,20,21,22,23,24,25,26
//27,28,29,30,31,32,33,34,35,36,37,38,39
//40,.41,42,43,44,45,46,47,48,49,50,51,52
//53,54