问题标签 [mahjong]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
algorithm - 麻将 - 排列瓷砖以确保至少有一条通往胜利的道路,无论布局如何
无论使用哪种布局,有没有什么好的方法来分配瓷砖,以便您可以向用户保证,在游戏开始时,至少存在一条完成拼图并赢得游戏的途径?
显然,根据用户的动作,他们可以切断自己的胜利。我只想能够总是告诉用户,如果他们玩得好,这个谜题是可以赢的。
如果您在游戏开始时随机放置瓷砖,则用户可能会移动一些动作而无法再移动。一个谜题至少可以解决的知识应该让它更有趣。
artificial-intelligence - 解释或研究基于人工智能 (AI) 的麻将游戏方法/策略的资源
虽然麻将(实际游戏,不是麻将纸牌)在基本规则和游戏玩法方面相当简单,但为 AI 设定目标以过渡到针对某些最终游戏目标似乎相当复杂。
有人知道与该主题相关的任何论文、研究或其他材料吗?
c++ - 麻将纸牌求解算法,需要加速
我正在开发一个麻将纸牌解算器,到目前为止,我做得很好。但是,它并没有我希望的那么快,所以我要求你们可能知道的任何其他优化技术。
所有的瓦片都是从布局中知道的,但解决方案不是。目前,我几乎没有规则可以保证安全移除某些相同的瓷砖对(这不会成为可能的解决方案的障碍)。
为清楚起见,当可以随时拾取瓷砖并且瓷砖松动时,当它根本不绑定任何其他瓷砖时,它是免费的。
- 如果有四个免费的免费瓷砖可用,请立即删除它们。
- 如果可以拾取三块瓷砖,并且其中至少有一个是松散的,则移除非松散的。
- 如果可以拾取三张牌,而只有一张免费牌(两张松动),则移除免费和一张随机松动的牌。
- 如果有三个松散的瓷砖可用,请移除其中的两个(无论哪个都无所谓)。
- 由于有四次完全相同的瓷砖,如果剩下两个,请移除它们,因为它们是唯一剩下的。
我的算法递归地在多个线程中搜索解决方案。一旦一个分支完成(到一个没有更多移动的位置)并且它没有导致一个解决方案,它就会将该位置放在一个包含坏的向量中。现在,每次启动新分支时,它都会遍历错误位置以检查该特定位置是否已被检查。
这个过程一直持续到找到解决方案或检查所有可能的位置。
这适用于包含 36 或 72 个图块的布局。但是当有更多时,由于要搜索的位置很多,因此该算法变得非常无用。
所以,我再次问你,如果你们中的任何人有好的想法,如何实施更多的安全瓷砖移除规则或关于算法的任何其他特定加速。
最好的问候, nhaa123
javascript - 请帮我加快这个麻将算法
我正在用 JavaScript 写一些麻将相关的函数。
这是我下面的内容,带有测试用例的代码。
请注意,麻将手由数组表示,其中:
- 元素 0 是手中牌的总数
- 元素 1 到 34 是手中每种类型的牌的数量
- 首先是craks,然后是dots,然后是bams,然后是winds,最后是dragons
查找等待的功能运行非常缓慢。我怎样才能加快速度?
iphone - iPhone - 需要一些纸牌游戏的参考代码
我要建立一个纸牌游戏。游戏会像麻将一样。我想要一些参考代码或链接开始。如果你有的话,请分享它。
algorithm - 如何实现麻将游戏?
麻将是亚洲最受欢迎的游戏之一(不是 Windows 7 中的单人纸牌游戏)。那里有很多麻将游戏,包括雅虎的在线游戏或 DOS 时代的离线游戏!
又一天我在想,我怎么写一个(不包括 GUI)?
数据建模部分很简单。
获胜和得分规则是……模式匹配?
游戏的战略部分,例如决定扔出哪块棋子以及何时进行 Chow 或 Pong 动作是最困难的部分。如何实施?
谢谢!
研究:
- 麻将(日式)演示:http ://www.nobleflash.com/game/4495/Japanese-Mahjong.html
- http://www.ninedragons.com/ - 我以前玩的一款麻将游戏,计分系统:http ://www.ninedragons.com/mahjong/scoring2.html
- 函数语言更适合?以什么方式?F# 是纸牌游戏 AI 的好语言吗?
- 人工智能麻将 - http://www.stanford.edu/class/cs229/proj2009/Loh.pdf
algorithm - 寻找街道和同类的算法
这实际上是一个基于麻将的问题,但是基于 Romme 甚至扑克的背景也很容易理解。
在麻将中,14 张牌(牌就像扑克牌中的牌)被排列成 4 组和一对。一条街道(“123”)总是使用恰好 3 个瓷砖,不多也不少。一组相同类型(“111”)也正好由 3 个牌组成。这导致总和为 3 * 4 + 2 = 14 个图块。
有各种例外,例如 Kan 或十三孤儿,在这里不相关。颜色和值范围 (1-9) 对算法也不重要。
我正在尝试确定是否可以按照上述方式安排手。由于某些原因,它不仅应该能够处理 14 个瓷砖,而且应该能够处理任意数量的瓷砖。(下一步是找出需要交换多少张牌才能完成一手牌。)
例子:
11122233344455
- 很简单,4 套和一对。
12345555678999
- 123, 456, 789, 555, 99
11223378888999
- 123, 123, 789, 888, 99
11223344556789
- 无效手牌
我目前尚未实施的想法是:对于每个图块,尝试制作 a) 一条街道 b) 一组 c) 一对。如果没有一个有效(或者会有 > 1 对),则返回上一个迭代并尝试下一个选项,或者,如果这是最高级别,则失败。否则,从剩余瓦片列表中删除已使用的瓦片并继续下一次迭代。
我相信这种方法有效并且速度也相当快(性能是一个“不错的奖励”),但我对您对此的看法很感兴趣。你能想到替代解决方案吗?这个或类似的东西已经存在了吗?
(不是作业,我在学打麻将。)
c# - 如何快速判断列表是否仅包含重复项?
有多个相关问题,但我正在寻找针对我的案例的解决方案。有一个(通常)14 个整数的数组。如何快速判断每个 int 是否恰好出现两次(即有 7 对)?取值范围从 1 到 35。这里的主要方面是性能。
作为参考,这是我目前的解决方案。它被编写为尽可能接近规范并且没有考虑性能,所以我确信可以大大改进:
使用 Linq 是可选的。我不在乎如何,只要它快:)
编辑:在特殊情况下,int 出现 2n 次且 n > 1。在这种情况下,检查应该失败,即应该有 7 个不同的对。
编辑:结果 我用微小的修改测试了 Ani 和 Jon 的解决方案,并在目标应用程序的多个基准测试运行期间发现,Ani 在我的机器上的吞吐量大约是 Jon 的两倍(Win7-64 上的一些 Core 2 Duo)。生成整数数组所需的时间与相应检查的时间差不多,所以我对结果很满意。谢谢大家!
c# - 如何快速判断列表是否包含列表?
有多个相关问题,但我正在寻找针对我的案例的解决方案。有一个(通常)14 个整数的数组,每个整数的范围在 1 到 34 之间。如何快速判断特定静态列表中的每个 int 是否在该数组中至少出现一次?
作为参考,我目前正在使用这段代码,它被编写为尽可能接近规范,所以它肯定可以大大改进:
所需的列表不是动态的,即它在运行时总是相同的。使用 Linq 是可选的,主要方面是性能。
编辑:
- 输入数组未排序。
- 输入值可能会出现多次。
- 输入数组将包含至少 14 个项目,即比所需数组多 1 个。
- 只有 1 个必需的数组,它是静态的。
- required 中的值是不同的。
- 您可能会认为创建直方图的成本很低。
更新:我也对排序输入数组的解决方案感兴趣。
algorithm - 我如何计算麻将中的shanten数?
这是我之前关于决定一手牌是否准备好的问题的后续。
麻将规则的知识会非常好,但是基于扑克或罗姆棋的背景也足以理解这个问题。
在麻将中,14 张牌(牌就像扑克牌中的牌)被排列成 4 组和一对。顺子(“123”)总是使用 3 张牌,不多也不少。一组相同类型(“111”)也正好由 3 个牌组成。这导致总和为 3 * 4 + 2 = 14 个图块。
有各种例外,例如 Kan 或十三孤儿,在这里不相关。颜色和值范围 (1-9) 对算法也不重要。
一手牌由 13 张牌组成,每次轮到我们时,我们都要选择新的牌,并且必须丢弃任何牌,所以我们留在 13 张牌上——除非我们可以使用新选的牌获胜。
可以安排形成 4 组和一对的手是“准备好的”。只需要交换 1 张牌的手被称为“tenpai”,或“1 from ready”。任何其他手都有一个shanten-number,表示需要交换多少张牌才能进入tenpai。因此,一手牌数为 1 的牌需要 1 张牌才能成为 1 牌(相应地需要 2 张牌)。一手牌数为 5 的牌需要 5 张牌才能成为十牌,以此类推。
我正在尝试计算一手牌的 shanten 数。在谷歌搜索了几个小时并阅读了关于这个主题的多篇文章和论文之后,这似乎是一个未解决的问题(除了蛮力方法)。我能找到的最接近的算法依赖于机会,即它无法 100% 地检测到正确的 shanten 编号。
规则
我将解释一下实际规则(简化),然后我的想法是如何解决这个任务。在麻将中,有 4 种颜色,3 种正常的颜色,就像纸牌游戏中一样(ace、heart、...),称为“man”、“pin”和“sou”。这些颜色各从 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
是 2-shanten 中的一手牌。有 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, 5p, 9p, 9p, E, E, E, S, S
:这手牌是十牌,可以在 9 针或 S 上完成。
为避免更冗长地绘制此文本,您可以在wikipedia上阅读更多示例或使用 google 的各种搜索结果之一。不过,所有这些都更具技术性,所以我希望上面的描述就足够了。
算法
如前所述,我想计算一手牌的 shanten 数。我的想法是根据颜色将瓷砖分成 4 组。接下来,所有的牌都被分类到各自组内的集合中,我们最终在荣誉组中得到三联、对或单个牌,或者另外,在 3 个正常组中得到一串。已完成的集合被忽略。对数进行计数,最终数字递减(最后我们需要 1 对)。单个瓷砖被添加到这个数字。最后,我们将这个数字除以 2(因为每次我们选择一个能让我们更接近天牌的好牌,我们就可以去掉另一个不需要的牌)。
但是,我不能证明这个算法是正确的,而且我也很难为包含许多近距离瓷砖的困难组合并直道。每种想法都值得赞赏。我正在使用 .NET 进行开发,但也欢迎使用伪代码或任何可读语言。