Vb.net 一副牌的所有非重复组合
我想写一个扑克赔率计算器。其背后的想法是,它通过所有可能的组合,可能发挥暴力的方式 我目前的逻辑(为了便于阅读而精简)如下:Vb.net 一副牌的所有非重复组合,vb.net,loops,for-loop,nested-loops,Vb.net,Loops,For Loop,Nested Loops,我想写一个扑克赔率计算器。其背后的想法是,它通过所有可能的组合,可能发挥暴力的方式 我目前的逻辑(为了便于阅读而精简)如下: For i = 0 To unknownCards - 1 For j = 1 To 4 'pick suit For k = 1 To 13 'pick number 'do other
For i = 0 To unknownCards - 1
For j = 1 To 4
'pick suit
For k = 1 To 13
'pick number
'do other work here
Next
Next
Next
然而,这是错误的。它只会按顺序循环卡片。就我而言,卡片的顺序并不重要(例如,我不想单独处理2、3、4和4、3、2),但重要的是我要看到每一种可能的独特组合。我就是不知道该怎么做?任何帮助或建议都会很好
另外,在评论澄清之后,我在VB.net中这样做了:为了强行获得所有手牌的列表,我知道的最简单的方法是在牌上强加一个顺序(例如,按数字排序,然后进行诉讼:标准是2个梅花低,黑桃王牌高),然后选择升序的手牌。这样,即使顺序对你来说并不重要,但对你的手进行排序可以确保你有一个明确的方法来决定独特的手 一种简单易懂但不太理想的方法是嵌套5个循环:第一张牌的整个牌组,然后通过在低于那张牌的所有牌上循环选择第二张牌,依此类推。(实际上,您可以从牌组中的第五张牌开始选择第一张牌,即3张梅花,以此类推,但在完成后,确保每手牌有5张牌可能更容易。)
我选择的语言是Python;如果你想要完整的列表,我会列出52张卡片,或者更好的是只对卡片和使用范围进行编号;然后在注释澄清后,在列表中使用itertools.product 5次,只允许手牌出现在牌的位置。\u 1:为了强行获得所有手牌的列表,我知道的最简单的方法是对牌进行排序(例如,按数字排列,然后进行诉讼:标准是2个梅花低,黑桃王牌高)然后选择按升序排列的手。这样,即使顺序对你来说并不重要,但对你的手进行排序可以确保你有一个明确的方法来决定独特的手 一种简单易懂但不太理想的方法是嵌套5个循环:第一张牌的整个牌组,然后通过在低于那张牌的所有牌上循环选择第二张牌,依此类推。(实际上,您可以从牌组中的第五张牌开始选择第一张牌,即3张梅花,以此类推,但在完成后,确保每手牌有5张牌可能更容易。)
我选择的语言是Python;如果你想要完整的列表,我会列出52张卡片,或者更好的是只对卡片和使用范围进行编号;然后使用列表中的itertools.product 5次,仅允许在卡片上有2598960只手的情况下使用。此代码通过蛮力生成所有可能的手。只生成52张卡片索引的组合比担心循环中的套装和等级更快/更容易/更好。正如@ElizabethSQGoodman所说,这里有5个嵌套循环,每个循环的起点都比我的前一个高 出于性能原因,我选择了一个字节来存放每张卡,一个结构来存放卡片。然后,稍后,您可以根据规则确定每张卡是什么:前13张是梅花,后13张是钻石,等等(请参阅getHumanReadableHand()。在这里,您还可以定义Ace high或low(抱歉,不能同时定义两者)。秩(A,2,3,…,J,Q,K)由指数模13确定。这套衣服是由13除以指数决定的
Module Module1
Sub Main()
Dim hands As New List(Of Hand)()
For c0 As SByte = 0 To 51
For c1 As SByte = c0 + 1 To 51
For c2 As SByte = c1 + 1 To 51
For c3 As SByte = c2 + 1 To 51
For c4 As SByte = c3 + 1 To 51
Dim hand = New Hand
hand.Card0 = c0
hand.Card1 = c1
hand.Card2 = c2
hand.Card3 = c3
hand.Card4 = c4
hands.Add(hand)
Next c4
Next c3
Next c2
Next c1
Next c0
Console.WriteLine("There are {0} possible hands.", hands.Count)
Dim rnd As New Random()
Dim r = rnd.Next(hands.Count - 1)
Console.WriteLine("Random hand: {0}", getHumanReadableHand(hands(r)))
Console.WriteLine("Value: {0}", getHandValue(hands(r)))
Console.ReadLine()
End Sub
Function getHumanReadableHand(hand As Hand) As String
Static suits = {"C", "D", "H", "S"}
Static ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}
Return String.Join(", ", hand.Cards.Select(Function(card) ranks(rank(card)) & suits(suit(card))))
End Function
Private Function rank(card As SByte) As SByte
Return card Mod 13
End Function
Private Function suit(card As SByte) As SByte
Return CSByte(card \ 13)
End Function
Function getHandValue(hand As Hand) As String
Dim cards = hand.Cards
If cards.Select(Function(card) rank(card)).Max() - cards.Select(Function(card) rank(card)).Min() = 4 AndAlso
cards.Select(Function(card) rank(card)).Distinct().Count = 5 AndAlso
cards.Select(Function(card) suit(card)).Distinct().Count = 1 Then
Return "Straight Flush"
ElseIf cards.OrderBy(Function(card) rank(card)).Take(4).Select(Function(card) rank(card)).Distinct().Count = 1 OrElse
cards.OrderBy(Function(card) rank(card)).Skip(1).Take(4).Select(Function(card) rank(card)).Distinct().Count = 1 Then
Return "Four of a Kind"
ElseIf cards.Select(Function(card) rank(card)).Distinct().Count = 2 Then
Return "Full House"
ElseIf cards.Select(Function(card) suit(card)).Distinct().Count = 1 Then
Return "Flush"
ElseIf cards.Select(Function(card) rank(card)).Max() - cards.Select(Function(card) rank(card)).Min() = 4 AndAlso
cards.Select(Function(card) rank(card)).Distinct().Count = 5 Then
Return "Straight"
ElseIf cards.OrderBy(Function(card) rank(card)).Take(3).Select(Function(card) rank(card)).Distinct().Count = 1 OrElse
cards.OrderBy(Function(card) rank(card)).Skip(1).Take(3).Select(Function(card) rank(card)).Distinct().Count = 1 OrElse
cards.OrderBy(Function(card) rank(card)).Skip(2).Take(3).Select(Function(card) rank(card)).Distinct().Count = 1 Then
Return "Three of a Kind"
ElseIf cards.Select(Function(card) rank(card)).Distinct().Count = 3 Then
Return "Two Pairs"
ElseIf cards.Select(Function(card) rank(card)).Distinct().Count = 4 Then
Return "One Pair"
Else
Return "Garbage"
End If
End Function
Structure Hand
Public Property Card0 As SByte
Public Property Card1 As SByte
Public Property Card2 As SByte
Public Property Card3 As SByte
Public Property Card4 As SByte
Public ReadOnly Property Cards As IEnumerable(Of SByte)
Get
Return New List(Of SByte)({Card0, Card1, Card2, Card3, Card4})
End Get
End Property
End Structure
End Module
样本输出:
有2598960只可能的手。
随机手:2C、5C、2D、5S、KS
数值:两对
此代码大约需要60毫秒才能在我的机器上生成所有可能的手。有2598960只可能的手。此代码通过蛮力生成所有可能的手。只生成52张卡片索引的组合比担心循环中的套装和等级更快/更容易/更好。正如@ElizabethSQGoodman所说,这里有5个嵌套循环,每个循环的起点都比我的前一个高 出于性能原因,我选择了一个字节来存放每张卡,一个结构来存放卡片。然后,稍后,您可以根据规则确定每张卡是什么:前13张是梅花,后13张是钻石,等等(请参阅getHumanReadableHand()。在这里,您还可以定义Ace high或low(抱歉,不能同时定义两者)。秩(A,2,3,…,J,Q,K)由指数模13确定。这套衣服是由13除以指数决定的
Module Module1
Sub Main()
Dim hands As New List(Of Hand)()
For c0 As SByte = 0 To 51
For c1 As SByte = c0 + 1 To 51
For c2 As SByte = c1 + 1 To 51
For c3 As SByte = c2 + 1 To 51
For c4 As SByte = c3 + 1 To 51
Dim hand = New Hand
hand.Card0 = c0
hand.Card1 = c1
hand.Card2 = c2
hand.Card3 = c3
hand.Card4 = c4
hands.Add(hand)
Next c4
Next c3
Next c2
Next c1
Next c0
Console.WriteLine("There are {0} possible hands.", hands.Count)
Dim rnd As New Random()
Dim r = rnd.Next(hands.Count - 1)
Console.WriteLine("Random hand: {0}", getHumanReadableHand(hands(r)))
Console.WriteLine("Value: {0}", getHandValue(hands(r)))
Console.ReadLine()
End Sub
Function getHumanReadableHand(hand As Hand) As String
Static suits = {"C", "D", "H", "S"}
Static ranks = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}
Return String.Join(", ", hand.Cards.Select(Function(card) ranks(rank(card)) & suits(suit(card))))
End Function
Private Function rank(card As SByte) As SByte
Return card Mod 13
End Function
Private Function suit(card As SByte) As SByte
Return CSByte(card \ 13)
End Function
Function getHandValue(hand As Hand) As String
Dim cards = hand.Cards
If cards.Select(Function(card) rank(card)).Max() - cards.Select(Function(card) rank(card)).Min() = 4 AndAlso
cards.Select(Function(card) rank(card)).Distinct().Count = 5 AndAlso
cards.Select(Function(card) suit(card)).Distinct().Count = 1 Then
Return "Straight Flush"
ElseIf cards.OrderBy(Function(card) rank(card)).Take(4).Select(Function(card) rank(card)).Distinct().Count = 1 OrElse
cards.OrderBy(Function(card) rank(card)).Skip(1).Take(4).Select(Function(card) rank(card)).Distinct().Count = 1 Then
Return "Four of a Kind"
ElseIf cards.Select(Function(card) rank(card)).Distinct().Count = 2 Then
Return "Full House"
ElseIf cards.Select(Function(card) suit(card)).Distinct().Count = 1 Then
Return "Flush"
ElseIf cards.Select(Function(card) rank(card)).Max() - cards.Select(Function(card) rank(card)).Min() = 4 AndAlso
cards.Select(Function(card) rank(card)).Distinct().Count = 5 Then
Return "Straight"
ElseIf cards.OrderBy(Function(card) rank(card)).Take(3).Select(Function(card) rank(card)).Distinct().Count = 1 OrElse
cards.OrderBy(Function(card) rank(card)).Skip(1).Take(3).Select(Function(card) rank(card)).Distinct().Count = 1 OrElse
cards.OrderBy(Function(card) rank(card)).Skip(2).Take(3).Select(Function(card) rank(card)).Distinct().Count = 1 Then
Return "Three of a Kind"
ElseIf cards.Select(Function(card) rank(card)).Distinct().Count = 3 Then
Return "Two Pairs"
ElseIf cards.Select(Function(card) rank(card)).Distinct().Count = 4 Then
Return "One Pair"
Else
Return "Garbage"
End If
End Function
Structure Hand
Public Property Card0 As SByte
Public Property Card1 As SByte
Public Property Card2 As SByte
Public Property Card3 As SByte
Public Property Card4 As SByte
Public ReadOnly Property Cards As IEnumerable(Of SByte)
Get
Return New List(Of SByte)({Card0, Card1, Card2, Card3, Card4})
End Get
End Property
End Structure
End Module
样本输出:
有2598960只可能的手。
随机手:2C、5C、2D、5S、KS
数值:两对
这段代码大约需要60毫秒才能在我的机器上生成所有可能的手。你的意思是简单地说,“5张卡有多少不同的手”?这是一道数学题:52选择5,即(52!)/(5!*47!)或(52*51*50*49*48)/5!。计算一只手的概率也是一个很容易搜索的数学问题。@ElizabethS.Q.Goodman不,(虽然这是其中的一部分),我正在尝试迭代所有可能的不同的手。不过我要补充一点,如果你试图计算“得到四只手的概率”,这也是一个数学问题,你可以查一下;没有必要把每一手牌都打一遍,你到底想干什么还不清楚。首先是哪种扑克游戏和赔率(壶赔率?手赔率?)?计算5张牌的抽签是非常不同的,你只知道你有什么,你可能会丢弃什么,而游戏中有像HoldEm或7张牌螺柱这样的社区卡。然后,它是基于将使你的手牌和数量的卡尚未到来。看起来第一步是确定你最终可能拥有的手。手牌几率可能很容易,但第一步是确定你最终可能拥有的手牌你的意思是简单地说,“如何?”