骰子问题(葫芦和顺子识别)
我正在做一个骰子游戏。我有 5 个骰子,其中有所有值,我需要确定它们是否组成葫芦(一个 3 个,另一个 2 个)、小顺子(1-4、2-6 或 3-6)或大顺子(1-5、2-6)。
也许解决这个问题的最佳方法似乎是使用正则表达式。
有谁知道我将如何在正则表达式中表示这些规则?
或者,如果您能提供更好的解决方案,我将不胜感激。
示例:
- 葫芦 = 44422 或 11166 或 12212 等。
- 小顺子 = 12342 或 54532 等。
- 大顺子 = 12345 或 52643 等。
编辑
更改措辞以强调这是我缺乏经验的观点。
我知道如何使用代码来实现这一点,但这似乎是一个冗长的解决方案,我想知道是否有更简单的方法。
I'm making a dice game. There are 5 dice in which I have all the values for and I need to determine if they make up a full house (3 of one and 2 of another), small straight (1-4, 2-6 or 3-6) or a large straight (1-5, 2-6).
Perhaps the best way to approach this seems to be to use regular expressions.
Does anyone know how I would go about representing these rules in regex?
Or if you can provide a better solution, I'd appreciate that.
Examples:
- Full house = 44422 or 11166 or 12212 etc.
- Small Straight = 12342 or 54532 etc.
- Large Straight = 12345 or 52643 etc.
Edit
Changed wording to highlight that this is my inexperienced opinion.
I know how to achieve this using code, but it seems like such a long winded solution, I'm wondering if there's a more simplistic approach.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我会对所有数字进行递减排序,然后对每个值进行一些线性标准匹配,无论它是 int[] 还是字符串。
I would order all the numbers decreasing and then do some linear criteria matching on each value as you go along it whether it be in an int[] or a string.
不了解 C#,但在脚本语言中我会采用正则表达式路线。对于每一边,计算它在组合中出现的次数并将结果连接在一起。例如,对于组合
12342
,计数器字符串将为121100
。然后将计数器字符串与这些模式进行匹配:Don't know about c#, but in a scripting language I'd take the regexp route. For each side, calculate how many times it occurs in the combination and join the results together. For example, for the combination
12342
the counter string will be121100
. Then match the counter string against these patterns:您始终可以执行
LINQ
聚合查询并计算相同卡片的数量。这将类似于(无法测试它):这样您就可以轻松地知道您是否正在处理可能的顺子(或根本没有),一对,三元组等。
我不是
LINQ
专家和我目前无法测试这段代码,所以我不确定它是否会按原样编译,但它可能会帮助您或让您了解如何解决手头的问题。例如:
if count query = 5 :我们正在处理空手牌、同花或顺子 =>运行特定的同花/顺子逻辑。
if count query = 4:我们正在处理单个对。
if count query = 3 :我们正在处理双对或三元组 => if max count =3 then Triple
if count query = 2 :我们正在处理葫芦/扑克。如果最大计数 = 4,则扑克
You could always do a
LINQ
aggregate query and count the number of same cards. It would be something similar to (can't test it):This way you would easily know if you are dealing with a possible straight (or nothing at all), a pair, a triple, etc.
I am no
LINQ
expert and I can not test this bit of code at the moment, so I am not sure if it will compile as it is, but it might help you or give you an idea on how to approach the problem at hand.For example:
if count query = 5 : We are dealing with an empty hand, a flush or a straight => Run particular flush/straight logic.
if count query = 4 : We are dealing with a single pair.
if count query = 3 : We are dealing with a double pair or a triple => if max count =3 then triple
if count query = 2 : We are dealing with a full house / poker. If max count = 4 then poker
我不会评论您如何查找结果,而是评论您如何存储结果以供以后查找。
由于只有 46656 种可能的组合,并且一个字节可以存储最终的手牌强度,因此这个问题比扑克手牌问题容易得多。
您可以有一个查找表,其中包含作为索引的手牌并与该手牌的结果相关联(某些手牌可以有多个结果)。每个字节可以将所有手型存储为二进制表示形式(希望,如果不使用短整型)。
您获得的每个数字(例如 66655 - 满堂彩)都是以六为基数 (1-6) 的数字,将其转换为以 10 为基数的数字以获得查找表中的索引。
它将需要大约 46656 字节(+ CPU 对齐),并且可以放入 CPU L2 缓存。速度将是巨大的,因为您需要做的唯一操作是转换数基,以及提取手部力量的二进制或运算。
你会错过的是一手牌的真正力量。例如。 66655 比 66644 更好。你可以很容易地弄清楚这一点 - 你将需要一个更大的类型来存储结果:)
I won't comment on how you seek the results, but rather on how you store the result for later lookup.
Since you have only 46656 possible combinations and one byte can store the resulting hand strength, this problem is much easier than a poker hand problem.
You can have a lookup table, consisting of hands as indexes and associated with results (some hands can have multiple results) of that hand. Each byte can store all hand types as a binary representation (hopefully, if not use a short).
Each number you get (eg. 66655 - full house) is a number in base six (1-6), convert it into a base 10 number to get the index in the lookup table.
It will require about 46656 bytes (+ CPU alignment), and can fit into CPU L2 cache. Speed would be enourmous, since the only operation you would need to do is convert number base, and the binary OR operation to extract a hand strenght.
What you will miss is the real strength of a hand. Eg. 66655 is better than 66644. You can easily figure that out - you will need a bigger type to store result into :)
我决定自己尝试一下,最终没有使用正则表达式——我想也许由于搜索所需的简单性,正则表达式会增加比它们节省的更多的复杂性。不过,我对另一个答案使用了类似的逻辑:计算每个数字的数量,并以此为基础进行所有评分:
令我惊讶的是,我发现在 5 骰子掷骰子中,小顺子和大顺子的概率是相等的。是这样吗!?
编辑:已修复;我发现,当我将包含一对的小顺子包括在内时,小顺子的概率会显着上升。
当我想到这一点时,一对和一个小顺子可能应该使用该对作为最高骰子,并将顺子中的最高数字作为下一个最高数字(为了正确比较两个都是一对和小顺子的骰子) )。如果是这样,我将用以下代码替换处理 PairSmallStraight 的代码块:
I decided to try myself, and I ended up not using regular expressions -- I thought maybe with the simplicity of the searches required, regular expressions would add more complexity than they save. I used similar logic to another answer though: count the quantity of each number and base all the scoring on that:
I discovered, to my surprise, that the probability of a small straight and a large straight are equal in 5-die rolls. Is that true!?
EDIT: Fixed; I see that when I include small straights that include a pair, the probability of a small straight goes up significantly.
When I think about it, a pair and a small straight should probably use the pair as the highest die and the highest number in the straight as the next highest (in order to [properly compare two rolls that are both a pair with a small straight). If so, I'd replace the block of code for handling PairSmallStraight with this:
您可以尝试将您的值放入列表中。这将使您能够快速对值进行排序。如果你添加这些值,就会给你带来帮助。 111AA = 29 和 222KK = 30。只是一个想法。
You could try to put your values in to a list. This would allow you to quickly sort your values. And if you add the values that would give you the hand. 111AA = 29 and 222KK = 30. Just an idea.
这是我的代码:
Here is my Code: