话不多说,代码先给出来 文件名 mahjong.go
很多的实现方法,写的注释我觉得已经很详细了,多看下注释。

package mainimport ("sort""fmt"
)//牌类型
type CardType intconst (CardType_Unknown CardType = iotaCardType_WCardType_TCardType_S
)//实现string
func (st CardType) String() string {str := ""switch st {case CardType_W:str += "W"case CardType_T:str += "T"case CardType_S:str += "S"}return str
}//牌定义
type Card struct {Type  CardTypeValue int
}//实现string
func (c *Card) String() string {return fmt.Sprint("Card: ", c.Value, " ", c.Type)
}//自定义排序
type SortCards []*Cardfunc (sc SortCards) Len() int {return len(sc)
}func (sc SortCards) Less(i, j int) bool {if sc[i].Type != sc[j].Type {return sc[i].Type < sc[j].Type} else {return sc[i].Value < sc[j].Value}panic("unknown...")
}func (sc SortCards) Swap(i, j int) {sc[i], sc[j] = sc[j], sc[i]
}//实现
func (sc SortCards) Sort() {sort.Sort(sc)
}//最简单的胡牌算法
/*
1.首先我们要明白,什么样的牌可以胡牌?
2.  4*3+2,7*2 可以胡牌;当然,这是手上有14张牌的时候,所以用公式来说就是 N*3 + 1*2 (0<=n<=4)
3. 再者,麻将有不同的花色,而且每一个花色是没有关联的,所以可以分开单独计算,随便还可以加个携程,还能提高效率(单核机当我没说),多好啊。
总结:说简单点就是 先分开花色,在每一个花色中计算能否符合条件,只要一个不符合,直接false。
*/
func AnalyzeCardsSimple(cards []*Card) bool {//有个七对,特殊判断一下就可以了if len(cards) ==14 {// todo 计算是否有七个对子}//用一个slice来装不同花色的牌diffColorCards := GetDiffColorCards(cards)fmt.Println(diffColorCards)for _,tempCards := range diffColorCards {//1-9 每张牌的数量cardsNum := make([]int,10)for _, card := range tempCards {cardsNum[card]++}isHu := SplitCards(cardsNum,false)fmt.Println(isHu)if !isHu {return false}}return true
}/**
这是目前最简单的单机拆牌,只能判断是否能胡,不能用于计算牌型方面的东西。
原理:从第一张牌开始计算,假如一个牌有4张,在整个牌里面他只能做刻字和一个顺子;除开 333344445555 这种特殊情况,但是拆分出来也是判断可以胡的。所以减去三张牌,在调用SplitCards,这个时候它的第一张牌就只有一张,自然而然的就走找顺子的道路上了。但是减去三张发现后面也没有办法胡,看代码继续走下面,再减去2张试试呢。比如 22223344 这种牌一张牌它就只能去找后面的顺子,没有就不能胡。这里还有一个问题,就是有重复计算的部分比如 33334567 的牌,减去三个 3 剩下 34567,减去345剩67 不能胡;在回来减去两个 3 剩下 334567 ,在减去345剩下367不能胡;在回来到下面减一个345 剩33367,减去333 剩下67 ,这里和第一次其实是一样的算法,只是顺序不同。*/
//对子只能存在一对。
func SplitCards(cardsNum []int,hasPair bool) bool {cnt := 0for _, num := range cardsNum {if num > 0 {break}cnt++}//判断没有牌为可以胡牌if len(cardsNum) == cnt {return true}for i := 0; i < len(cardsNum); i++ {switch cardsNum[i] {case 4:fallthroughcase 3://这种存在这几种情况,可以加后面成顺子,取两张为对子,或取一个刻字//减掉后再传入SplitCardscardsNum[i]-=3if SplitCards(cardsNum,hasPair) {return true}cardsNum[i]+=3//这种不行就向下传递。。。fallthroughcase 2:if !hasPair {hasPair = truecardsNum[i]-=2if SplitCards(cardsNum,hasPair) {return true}cardsNum[i]+=2}fallthroughcase 1:if i+2 < len(cardsNum) && cardsNum[i+1] > 0 &&  cardsNum[i+2] >0 {cardsNum[i]--cardsNum[i+1]--cardsNum[i+2]--if SplitCards(cardsNum,hasPair) {return true}cardsNum[i]++cardsNum[i+1]++cardsNum[i+2]++}}}return false
}//获取不同颜色的牌
func GetDiffColorCards(cards []*Card) map[CardType][]int {colorCards := make(map[CardType][]int)for _, card := range cards {if _,ok := colorCards[card.Type]; !ok {colorCards[card.Type] = append([]int{},card.Value)}else {colorCards[card.Type] = append(colorCards[card.Type],card.Value)}}return colorCards
}

测试代码:mahjong_test.go

package mainimport ("testing""fmt"
)func TestSortCards(t *testing.T) {cards := []*Card{&Card{CardType_W,1},&Card{CardType_W,1},&Card{CardType_W,1},&Card{CardType_W,2},&Card{CardType_W,2},&Card{CardType_W,2},&Card{CardType_T,3},&Card{CardType_T,3},&Card{CardType_T,4},&Card{CardType_T,4},&Card{CardType_S,3},&Card{CardType_S,3},&Card{CardType_S,5},&Card{CardType_S,5},}SortCards(cards).Sort()fmt.Println(cards)//tempCards := make([]*Card, len(cards))//copy(tempCards,cards)//fmt.Println(tempCards)//temp := append([]*Card{}, &Card{CardType_S, 7})//fmt.Println(temp)//diffColorCards := GetDiffColorCards(cards)//fmt.Println(diffColorCards)//for _,tempCards := range diffColorCards {//    fmt.Println(tempCards)//}simple := AnalyzeCardsSimple(cards)fmt.Println(simple)
}

当然,这代码是第一个版本,其中还有更多可以优化。
那得看有需要优化需求的朋友是不是多了。
请留言我会实时收到消息。

golang实现最简单的麻将胡牌算法(不包括牌型,有需求后续可以更新牌型计算)相关推荐

  1. python实现洗牌算法_为什么渔民耶茨最有用的洗牌算法?

    Would you say modern version of fisher yates is the most unbiased shuffling algorithm? How would you ...

  2. 麻将胡牌算法带癞子 python实现

    姐姐:你去帮我和闺蜜打麻将? 学霸哥哥:可是我不会打麻将呀! 姐姐:你不是学霸吗?我教你一个麻将公式,我闺蜜可是单身哟! 学霸哥哥:什么公式? 姐姐:麻将胡牌公式: AAA*M+ABC*N+BB,WM ...

  3. python编程胡牌将是什么意思_python麻将和牌算法

    #coding='utf-8'#author='小罗QQ1271801445'#麻将胡牌算法#判定规则:n*(abc)+m*(ddd)+ee#特殊牌型:7*(ee),7对. ##规则:##胡牌的基础牌 ...

  4. python联机麻将_python麻将和牌算法

    #coding='utf-8' #麻将胡牌算法 #判定规则:n*(abc)+m*(ddd)+ee #特殊牌型:7*(ee),7对. ##规则: ##胡牌的基础牌型: ##(1)11.123.123.1 ...

  5. python麻将和牌算法

    之前用vba写过,当时的思路不清楚,也没有python这样强大的工具,写了好长时间. 现在想想,真的是太太太落后了.磨刀不误砍柴工,学习还是大有裨益的. 麻将和牌规则: 胡牌的基础牌型:(1)11.1 ...

  6. python实现洗牌算法_如何高效而完美地洗牌?用Python做很简单

    Python不用学,看看你就懂:拿来就能用,用用你就会 无需安装编程软件,把代码拷贝到在线编辑器即可运行 考虑一下扑克牌,如何用电脑编程做到高效而完美地洗牌呢? 要求是代码少.效率高,洗牌的结果要同时 ...

  7. 这或许是讲解 Knuth 洗牌算法最好的文章

    点击蓝色"五分钟学算法"关注我哟 加个"星标",一起学算法 作者 | liuyubobobo 来源公众号 | 是不是很酷 首先来思考一个问题: 设计一个公平的洗 ...

  8. Unity | 三种洗牌算法

    拓展资料:C#Shuffle算法(洗牌算法.抽样算法) - 简书 代码: using System.Collections.Generic; using UnityEngine;/** * Write ...

  9. 带赖子的麻将胡牌算法Java_带赖子的超高效麻将、跑胡子胡牌算法

    文档 github地址 https://github.com/yuanfengyun/qipai/tree/master/doc lua版 https://github.com/yuanfengyun ...

  10. 带赖子的超高效麻将、跑胡子胡牌算法

    腾讯课堂视频讲解:https://ke.qq.com/course/305608?tuin=104cb0e2 文档 github地址 https://github.com/yuanfengyun/qi ...

最新文章

  1. 二进制安装 kubernetes 1.12(三) - 部署 Master 节点组件
  2. 超实用:IIS 7.5修改WEB.CONFIG即可实现*.HTML伪静态
  3. 关于Gitlab若干权限问题
  4. linux挂载新硬盘,开机自动挂载
  5. Flex 幻灯片播放
  6. 【ArcGIS微课1000例】0023:ArcGIS将地理照片(无人机照片)转为点(航迹)案例教程
  7. Vue脚手架搭建项目
  8. For循环执行顺序流程
  9. 增广拉格朗日 matlab,大连理工优化方法增广拉格朗日方法MATLAB程序
  10. SpringApplication#run⽅法第5步,打印banner(四)
  11. electron build报错,nsis下载不下来的情况
  12. 最新kali之arping
  13. java组件技术考试题_Java核心技术2020年春答案试题题目及答案,期末考试题库,章节测验答案...
  14. 科学计算机符号大全,计算机符号代码大全
  15. 第八节课-深度学习软件
  16. linux镜像使用什么pe安装系统,Linux系统ISO镜像文件可不可以用pe启动盘来安装
  17. hdu 杭电1429 胜利大逃亡(续)
  18. Kendo ui 使用总结----Kendo UI 模板
  19. 用element-ui el-select 实现拼音码搜搜功能ts版
  20. excel2016打开空白解决方法

热门文章

  1. “多模态视频人物识别”课程分享学习总结
  2. OutMan——C语言中文件的操作
  3. 花3150本钱拉一车菠萝,在马路边摆摊卖水果,卖7天收入4170
  4. javaScript学习手册:JS对象
  5. [每日一氵] Python 训练过程中,如何优雅的保存loss
  6. java-net-php-python-64jspm自主学习试题库系统录像演示2019查重计算机毕业设计程序
  7. Android按键之Menu详解
  8. mysql 函数 人民币大写_sql 数字转人民币大写函数(两种方法)
  9. 利用爬虫获得疫情信息,并存入表格
  10. 已知树节点获取树的节点路径(js树节点路径)