go 实现斗地主牌型检测

写了一个简单的牌型检测算法,还请方家多指点

本方法没有使用 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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。