首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么计算麻将的单数?

我怎么计算麻将的单数?
EN

Stack Overflow用户
提问于 2010-11-21 16:55:24
回答 5查看 4.5K关注 0票数 9

这是我的先前关于决定一只手是否准备好的问题的后续。

对麻将规则的了解将是极好的,但基于扑克或罗马的背景也足以理解这个问题。

在麻将,14块瓷砖(瓷砖就像扑克牌)被安排成4组和一对。一个直线("123")总是使用准确的3个瓷砖,而不是更多,也不是更少。同一类型的一套("111")也正是由3个瓷砖组成的。这将导致3*4+2= 14瓦。 有各种例外,如菅直人或十三个孤儿,在这里不相关。颜色和值范围(1-9)对算法也不重要。

一只手由13块瓷砖组成,每次轮到我们挑选新的瓷砖时,我们必须丢弃任何瓷砖,所以我们只能使用13块瓷砖--除非我们能用新采摘的瓷砖赢得胜利。

一只可以排列成4组和一对的手是“准备好”的。一只只需要一个瓷砖就可以交换的手被称为"tenpai",或者说是“准备好的1块”。其他任何一只手都有一个shanten数,表示需要交换多少块才能在tenpai。因此,一只手有一个小数目的1需要一个瓷砖是张牌(和2个瓷砖准备好,相应地)。一只手有一个5的单数,需要5块瓷砖才能达到藤牌等。

我在计算一只手的单数。在搜索了几个小时并阅读了多篇关于这个主题的文章和论文之后,这似乎是一个尚未解决的问题(除了蛮力方法)。我所能找到的最接近的算法依赖于偶然,即它无法100%地检测出正确的shanten数。

规则

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

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

把我们原来的手稍微换成2p, 2p, 3p, 3p, 3p, 4p, 5m, 5m, 5m, W, W, W, E,我们在1-shanten得到了一只手,也就是说,它需要额外的瓷砖才能成为藤牌。在这种情况下,把一个2p换成一个3p把我们带回到tenpai,所以通过抽一个3p和一个E,我们赢了。

1p, 1p, 5p, 5p, 9p, 9p, E, E, E, S, S, W, W是一个两手空空的人.有一个完整的三重奏和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, 5p, 9p, 9p, E, E, E, S, S。这只手在张牌中可以完成一个9针或一个S。

为了避免绘制更长的文本,您可以在维基百科上阅读更多的示例,或者使用google的各种搜索结果之一。不过,所有这些都有点技术性,所以我希望上面的描述足够。

算法

如前所述,我想计算一只手的单数。我的想法是将瓷砖按颜色分成4组。接下来,所有的瓷砖在它们各自的组中被分类,我们结束于荣誉组中的三胞胎,对或单一的瓷砖,或者,另外,在三个正常的组中有条纹。已完成的集合将被忽略。对被计数,最后的数目会减少(我们最后需要1对)。将单个瓷砖添加到此数字中。最后,我们将这个数字除以2(因为每次我们选择一个好的瓷砖使我们更接近tenpai,我们就可以去掉另一个不想要的瓷砖)。

但是,我不能证明这个算法是正确的,而且我也很难将困难的组合并在一起,因为在近距离内包含了很多块。每一种想法都会受到赞赏。我正在用.NET进行开发,但伪代码或任何可读的语言也是受欢迎的。

EN

回答 5

Stack Overflow用户

发布于 2010-11-21 17:09:18

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

票数 2
EN

Stack Overflow用户

发布于 2013-09-20 10:46:48

正确的算法示例:syanten.cpp

递归裁剪形式从手的顺序:集合,对,不完整的形式,-并计算它。所有的变体。结果是所有变体的最小Shanten值: Shanten = Min(Shanten,8-*2-)

C#样本(从c++中提取)可以找到这里 (俄文)。

票数 1
EN

Stack Overflow用户

发布于 2016-02-10 23:45:02

我做了一些思考,想出了一个与mafu略有不同的公式。首先,想想一只手(一只非常糟糕的手):

1S4s6s1Mm 8m 9m 9m7p8p西北偏东

通过使用mafu的算法,我们所能做的就是去掉一对(9m,9m)。然后我们剩下11个单打。现在,如果我们应用mafu公式,我们得到(11-1)*2/3,它不是整数,因此不能是shanten数。这就是我想到这个的地方:

N= (S + 1) /3)-1

N代表shanten数,S代表得分和。得分是什么?这是许多瓷砖,你需要使一个不完整的集完整。例如,如果您手中有(4,5),您需要3或6使它成为一个完整的3套,也就是说,只有一个瓷砖。因此,这个不完整的一对得到了1分,因此,( 1 ,1)只需要1就可以变成3集。任何一张瓷砖显然都需要2张牌才能变成3张,然后得到2张。当然,任何完整的一组都可以得到0。请注意,我们忽略了单身成为一对的可能性。现在,如果我们试图在上面找到所有不完整的集合,我们就会得到:

(4s,6s) (8m, 9m ) (7p,8p) 1S1mM东东9m

然后,我们计算它的分数之和= 1*3+2*7 = 17。现在,如果把这个数字应用到上面的公式中,我们得到(17+1)/3 -1=5,这意味着这只手是5-shanten。这比亚历克西的要复杂一些,而且我没有证据,但到目前为止,它似乎对我有用。请注意,这样的手可以用另一种方式进行解析。例如:

(4s,6s) (9m,9m) (7p,8p) 1S1mMM8m东北偏西

然而,它仍然得到了分数总和17和5-山藤根据公式。我也不能证明这一点,这比亚历克西的公式要复杂一点,但也介绍了可以应用的分数(?)其他的东西。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4239028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档