Algorithm 我怎样计算麻将中的十位数?

Algorithm 我怎样计算麻将中的十位数?,algorithm,mahjong,Algorithm,Mahjong,这是我的计划的后续行动 麻将规则的知识将是极好的,但扑克或romme的背景也足以理解这个问题 麻将中有14块瓷砖(瓷砖像 扑克牌)分为4组 还有一双。直的(“123”)总是 仅使用3个瓷砖,不多也不多 较少的同类型的一套(“111”) 也正好由3块瓷砖组成。这 导致3*4+2=14的总和 瓷砖 有很多例外,比如菅直人 或者十三个不是孤儿 与此相关。颜色和值范围 (1-9)也不重要 算法 一手牌由13个牌组成,每次轮到我们时,我们都要挑选一个新牌,并且必须丢弃任何牌,所以我们只能选择13个牌——除

这是我的计划的后续行动

麻将规则的知识将是极好的,但扑克或romme的背景也足以理解这个问题

麻将中有14块瓷砖(瓷砖像 扑克牌)分为4组 还有一双。直的(“123”)总是 仅使用3个瓷砖,不多也不多 较少的同类型的一套(“111”) 也正好由3块瓷砖组成。这 导致3*4+2=14的总和 瓷砖

有很多例外,比如菅直人 或者十三个不是孤儿 与此相关。颜色和值范围 (1-9)也不重要 算法

一手牌由13个牌组成,每次轮到我们时,我们都要挑选一个新牌,并且必须丢弃任何牌,所以我们只能选择13个牌——除非我们可以使用新挑选的牌获胜

一只手可以排列成4组,一对“准备就绪”。只需要交换1块瓷砖的手牌被称为“tenpai”,或“1 from ready”。任何另一只手上都有一个shanten数字,表示在tenpai中需要交换多少瓷砖。因此,一只手的单十个数字为1时,需要1个牌才能成为十牌(相应地,需要2个牌才能准备好)。一只手的十个数字为5的牌需要5个牌才能成为十牌,以此类推

我在计算一只手的十位数。在谷歌上搜索了几个小时,阅读了多篇关于这个主题的文章和论文后,这似乎是一个尚未解决的问题(暴力方法除外)。我能找到的最接近的算法依赖于偶然性,也就是说,它无法100%地检测到正确的shanten数

规则 我将解释一些实际的规则(简化),然后我的想法如何处理这项任务。在麻将中,有4种颜色,3种普通的颜色,如纸牌游戏(王牌、心牌等),分别称为“人”、“别针”和“苏”。这些颜色分别为1到9种,可用于形成直线以及同类组。第四种颜色被称为“荣誉”,只能用于同类团体,但不能用于直人。这七项荣誉将被称为“E、S、W、N、R、G、B”

让我们看一个天派手的例子:
2p,3p,3p,3p,4p,5m,5m,5m,W,W,E
。接下来,我们选择一个
E
。这是一个完整的麻将牌(准备好了),由2-4针(记住,针可以用于直杆)、3针三杆、5人三杆、W三杆和E对组成

将我们原来的手稍微更改为
2p、2p、3p、3p、4p、5m、5m、5m、5m、W、W、E
,我们在1-shanten中得到了一只手,也就是说,它需要一块额外的瓷砖才能成为tenpai。在这种情况下,用2p换3p会让我们回到tenpai,所以通过画3p和E我们赢了

1p,1p,5p,5p,9p,9p,E,E,S,S,W,W
是一个二把手。有1个完整的三联体和5对。最后我们需要一对,所以一旦我们从1p、5p、9p、S或W中选择一对,我们需要丢弃另一对。示例:我们选择一个1针并丢弃一个W。手现在处于1-shanten状态,看起来如下:
1p,1p,1p,5p,5p,9p,9p,E,E,E,S,S,W
。接下来,我们等待5p、9p或S。假设我们选择5p并丢弃剩余的W,我们得到:
1p、1p、1p、5p、5p、9p、9p、E、E、E、S、S
。这只手在tenpai中,可以在9针或S针上完成

为了避免把这段文字画得更长,你可以在谷歌或使用谷歌的各种搜索结果阅读更多的例子。不过,所有这些都有点技术性,所以我希望上面的描述就足够了

算法 如上所述,我想计算一只手的十位数。我的想法是根据颜色将瓷砖分成4组。接下来,所有的瓷砖在各自的组中被分类成一组,我们在荣誉组中以三胞胎、成对或单个瓷砖结束,或者,另外,在3个正常组中以Streight结束。已完成的集将被忽略。对进行计数,最后的数字递减(我们最后需要1对)。将单个磁贴添加到此编号。最后,我们将这个数字除以2(因为每次我们选择一个好的瓷砖使我们更接近tenpai,我们就可以去掉另一个不需要的瓷砖)


然而,我不能证明这个算法是正确的,而且我也很难为包含许多近距离瓷砖的困难组合并直线。每一种想法都值得赞赏。我是在.NET中开发的,但是也欢迎使用伪代码或任何可读语言。

我最好的猜测是一种受A*启发的方法。你需要找到一些永远不会高估shanten数的启发式方法,并使用它来搜索蛮力树,只在可能足够快地进入就绪状态的区域内进行搜索。

确定你的手是否已经在tenpai中听起来像是一个问题。贪婪算法是行不通的——正如Dialecticus指出的,你需要考虑整个问题空间。

< P>我对这个问题有了更多的思考。要查看最终结果,请跳到最后一节

第一个想法:暴力手段 首先,我写了一个蛮力方法。它能够在一分钟内识别出3-shanten,但它不是很可靠(有时太长了,而且即使是3-shanten也无法列举整个空间)

蛮力法的改进 我想到的一件事是给暴力手段增加一些智慧。天真的方法是添加任何剩余的瓷砖,看看它是否产生了麻将,如果没有尝试下一个递归,直到找到它。假设剩下大约30块不同的瓷砖,最大深度为6(我不确定是否可能有7+的shanten手[编辑:根据后面开发的公式,最大可能的shanten数为(13-1)*2/3=8]),我们得到(13*30)^6种可能性,这是一个很大的(10^15范围)

然而,没有必要把每一个左撇子都放进去
Remove completed 3-sets
If removed, return (i.e. do not simulate NOT taking the 3-set later)

Remove 2-set by looping through discarding any other tile (this creates a number of branches in the simulation)
If removed, return (same as earlier)

Use the number of left-over single tiles to calculate the shanten number
Remove completed 3-sets
Remove 2-set by looping through discarding any other tile
Use the number of left-over single tiles to calculate the shanten number