美文网首页
go 实现斗地主牌型检测

go 实现斗地主牌型检测

作者: 没有昵称会怎样 | 来源:发表于2019-06-20 12:07 被阅读0次

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

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

    相关文章

      网友评论

          本文标题:go 实现斗地主牌型检测

          本文链接:https://www.haomeiwen.com/subject/onyifctx.html