Visual Basic 计算卡片列表的直接组合
Visual Basic evaluate a list of cards for a straight combination
我正在创建一个扑克评估器,但我无法弄清楚如何检查 "straight" 组合(我还需要知道组合是什么牌)。
我有一张卡片列表,所以我需要弄清楚的是:
列表中是否包含 A?
如果是:
- 创建一个 A 高的新列表。
- 创建一个新的 A 低的列表。
- 运行 检查两个列表,return 以顺子组合中卡片数量较多的那个为准。
如果否:
- 运行 检查列表和 return 顺子组合中的牌。
如何检查顺子组合:
运行遍历列表,检查当前卡的rank+1是否等于上一张卡的rank
使用这种方法我们将运行变成一个问题....
考虑以下因素:
- 国王
- 女王
- 杰克
- 三个
- 两个
结果将是:
- King = Nothing = False
- 女王=国王=真
- 杰克 = 皇后 = 真
- 三=杰克=假
- 二 = 三 = 正确
那个结果不行,那样的话结果应该是:King,Queen,Jack。
我不确定如何以巧妙的方式或以可行的方式将其放入代码中。我试过做 LINQ,也试过使用 for 循环。
这是我制作的卡片class:
Public Enum CardRank
Two = 2
Three = 3
Four = 4
Five = 5
Six = 6
Seven = 7
Eight = 8
Nine = 9
Ten = 10
Jack = 11
Queen = 12
King = 13
Ace = 14
End Enum
Public Enum CardSuit
Club = 1
Diamond = 2
Heart = 3
Spade = 4
End Enum
Public Class Card
Public Rank As CardRank
Public Suit As CardSuit
#Region "Constructor"
Sub New()
End Sub
Sub New(ByVal Rank As CardRank, ByVal Suit As CardSuit)
Me.Rank = Rank
Me.Suit = Suit
End Sub
#End Region
Public Overrides Function ToString() As String
Return [Enum].GetName(GetType(CardRank), Rank) + " of " + [Enum].GetName(GetType(CardSuit), Suit)
End Function
End Class
复制此内容以快速开始:
Dim Deck As New List(Of Card)
Dim Cards As List(Of Card) = New Card() {New Card(CardRank.King, CardSuit.Spade), New Card(CardRank.Queen, CardSuit.Heart), New Card(CardRank.Jack, CardSuit.Club), New Card(CardRank.Three, CardSuit.Spade), New Card(CardRank.Two, CardSuit.Diamond)}.ToList()
'Add deck
For Each Suit As CardSuit In [Enum].GetValues(GetType(CardSuit))
For Each Rank As CardRank In [Enum].GetValues(GetType(CardRank))
Deck.Add(New Card(Rank, Suit))
Next
Next
For Each Card As Card In Cards
Deck.Remove(Card)
Next
也许我做错了?
编辑:顺子是连续排列的五张牌。请注意,在德州扑克中,A 可以高也可以低。
编辑:这是我列出我的卡的方式。 (当然可以更改以适应其他方法)
Dim tempList = Cards.GroupBy(Function(card) card.Rank).Reverse().OrderByDescending(Function(group) group.Count()).SelectMany(Function(group) group).ToList()
你可以做的是找到最小和最大牌,然后用总和来检查它是否是顺子。伪代码:
def isStraight(cards)
isStraight = true;
// Check for cases except ace has value 1.
min = cards.min()
for (index = min + 1; index < min + 5; index++)
isStraight &= cards.exist(index);
if not isStraight:
// Check for case ace has value 1
isStraight = cards.exist(14) and
cards.exist(2) and
cards.exist(3) and
cards.exist(4) and
cards.exist(5)
return isStraight
嗯。不是微不足道的,但这是我将如何解决它。
首先更新你的颜值如下:
Public Enum CardRank
Ace = 0
Two = 1
Three = 2
Four = 3
Five = 4
Six = 5
Seven = 6
Eight = 7
Nine = 8
Ten = 9
Jack = 10
Queen = 11
King = 12
End Enum
因此您的值 运行 从 A 的 0 到 K 的 12。在许多情况下,如果您习惯了基于 0 的索引,您会发现生活会变得更轻松 (https://en.wikipedia.org/wiki/Zero-based_numbering)
现在,如果您的牌按升序排列,则很容易判断您是否有顺子。 (我已经 VB 很多年没写了,所以这将是伪代码)
Integer card = rank of first card
//Check each of the following cards
For i = 2 to 5
Integer nextCard = rank of next card
If (nextCard != (card + 1) mod 13) return false
card = nextCard
End For
因为我们 mod 是 13,K 之后的牌是 (12 + 1) mod 13 = 13 mod 13 = 0,也就是预期的 A .
我不太懂扑克,所以我不确定顺子是否可以绕过 A(意思是 Q、K、A、2、3 是顺子?)。如果不是,那么检查 A 高和 A 低这两种情况仍然很容易。 Ace 低是微不足道的,就是这个代码。对于 A 高,它必须从 10 开始。排序后,A 将是第一张牌(这并不理想)因此任何从 [A,10,...] 开始的序列都可以快速重新排列为 [10,。 .., Ace] 然后 运行 通过相同的算法。
男
我要感谢所有愿意花时间提供帮助的人,这是我困扰了好几天的问题!
最后我自己想通了。我这样做的方法涵盖了所有可能性,而不仅仅是一些,而且它还 returns 创建组合的卡片列表。
基函数:
Private Function ReturnStraight(ByVal tempList As List(Of Card)) As List(Of Card)
Dim cardslist As New List(Of List(Of Card)) 'Lists of lists of cards in sequential rank
Dim temporaryList As New List(Of Card) 'Temporary list to add seqeuntial ranked cards to, to later add to the above list
Dim previousCard As Card = tempList(0) 'Gotta start somewhere
For i = 0 To tempList.Count - 1
Dim Card As Card = tempList(i)
If Card.Rank + 1 = previousCard.Rank Then 'If the queen + 1 equals king
If temporaryList.Find(Function(c) c.Rank = previousCard.Rank) Is Nothing Then : temporaryList.Add(previousCard) : End If 'If it doesn't already contain the previous card, add it (we want the king, which we wouldn't get without this)
temporaryList.Add(Card) 'Add the card (the queen)
If i = tempList.Count - 1 Then 'We need this if because of certain scenarios, e.g. King, Queen, Jack, Three, Two - King, Queen, Jack would be added, but three and two would not because we would not enter the else below when Two + 1 = 3...
If temporaryList.Count > 0 Then : cardslist.Add(temporaryList) : End If 'If the list is not empty, add it to the list of list of cards
temporaryList = New List(Of Card) 'Assign it a new empty list of cards to elimate referencing
End If
Else 'If the sequential list breaks (goes from jack to 3), add the temporary list of cards to the list of list of cards
If temporaryList.Count > 0 Then : cardslist.Add(temporaryList) : End If 'If the list is not empty, add it to the list of list of cards
temporaryList = New List(Of Card) 'Assign it a new empty list of cards to elimate referencing
End If
previousCard = Card 'Assign the current card to the previousCard holder
Next
cardslist = cardslist.OrderByDescending(Function(list) list.Count()).ToList() 'We want to list them in descending order by the count of cards
If Not cardslist.Count = 0 Then 'We have to check to see if the cardlist is empty or not, because if it is and we return it, we get an error....
Return cardslist(0) 'Return the highest count card list
End If
Return tempList 'Function failed because there are not enough cards, so return the original list
End Function
我是如何使用它的:
Dim tempList = Cards.GroupBy(Function(card) card.Rank).OrderByDescending(Function(group) group.Count()).SelectMany(Function(group) group).ToList()
If tempList.Find(Function(Card) Card.Rank = CardRank.Ace) IsNot Nothing Then 'We have an ace
Dim noAce = (From Card As Card In tempList Where Card.Rank <> CardRank.Ace Select Card).ToList()
Dim lst = ReturnStraight(noAce)
If lst(lst.Count - 1).Rank = CardRank.Two Or lst(0).Rank = CardRank.King Then
lst.Add((From Card As Card In tempList Where Card.Rank = CardRank.Ace Select Card).ToList(0))
End If
Else
Dim lst = ReturnStraight(tempList)
For Each Card As Card In lst
MsgBox(Card.ToString())
Next
End If
我正在创建一个扑克评估器,但我无法弄清楚如何检查 "straight" 组合(我还需要知道组合是什么牌)。
我有一张卡片列表,所以我需要弄清楚的是:
列表中是否包含 A?
如果是:
- 创建一个 A 高的新列表。
- 创建一个新的 A 低的列表。
- 运行 检查两个列表,return 以顺子组合中卡片数量较多的那个为准。
如果否:
- 运行 检查列表和 return 顺子组合中的牌。
如何检查顺子组合:
运行遍历列表,检查当前卡的rank+1是否等于上一张卡的rank
使用这种方法我们将运行变成一个问题....
考虑以下因素:
- 国王
- 女王
- 杰克
- 三个
- 两个
结果将是:
- King = Nothing = False
- 女王=国王=真
- 杰克 = 皇后 = 真
- 三=杰克=假
- 二 = 三 = 正确
那个结果不行,那样的话结果应该是:King,Queen,Jack。
我不确定如何以巧妙的方式或以可行的方式将其放入代码中。我试过做 LINQ,也试过使用 for 循环。
这是我制作的卡片class:
Public Enum CardRank
Two = 2
Three = 3
Four = 4
Five = 5
Six = 6
Seven = 7
Eight = 8
Nine = 9
Ten = 10
Jack = 11
Queen = 12
King = 13
Ace = 14
End Enum
Public Enum CardSuit
Club = 1
Diamond = 2
Heart = 3
Spade = 4
End Enum
Public Class Card
Public Rank As CardRank
Public Suit As CardSuit
#Region "Constructor"
Sub New()
End Sub
Sub New(ByVal Rank As CardRank, ByVal Suit As CardSuit)
Me.Rank = Rank
Me.Suit = Suit
End Sub
#End Region
Public Overrides Function ToString() As String
Return [Enum].GetName(GetType(CardRank), Rank) + " of " + [Enum].GetName(GetType(CardSuit), Suit)
End Function
End Class
复制此内容以快速开始:
Dim Deck As New List(Of Card)
Dim Cards As List(Of Card) = New Card() {New Card(CardRank.King, CardSuit.Spade), New Card(CardRank.Queen, CardSuit.Heart), New Card(CardRank.Jack, CardSuit.Club), New Card(CardRank.Three, CardSuit.Spade), New Card(CardRank.Two, CardSuit.Diamond)}.ToList()
'Add deck
For Each Suit As CardSuit In [Enum].GetValues(GetType(CardSuit))
For Each Rank As CardRank In [Enum].GetValues(GetType(CardRank))
Deck.Add(New Card(Rank, Suit))
Next
Next
For Each Card As Card In Cards
Deck.Remove(Card)
Next
也许我做错了?
编辑:顺子是连续排列的五张牌。请注意,在德州扑克中,A 可以高也可以低。 编辑:这是我列出我的卡的方式。 (当然可以更改以适应其他方法)
Dim tempList = Cards.GroupBy(Function(card) card.Rank).Reverse().OrderByDescending(Function(group) group.Count()).SelectMany(Function(group) group).ToList()
你可以做的是找到最小和最大牌,然后用总和来检查它是否是顺子。伪代码:
def isStraight(cards)
isStraight = true;
// Check for cases except ace has value 1.
min = cards.min()
for (index = min + 1; index < min + 5; index++)
isStraight &= cards.exist(index);
if not isStraight:
// Check for case ace has value 1
isStraight = cards.exist(14) and
cards.exist(2) and
cards.exist(3) and
cards.exist(4) and
cards.exist(5)
return isStraight
嗯。不是微不足道的,但这是我将如何解决它。
首先更新你的颜值如下:
Public Enum CardRank
Ace = 0
Two = 1
Three = 2
Four = 3
Five = 4
Six = 5
Seven = 6
Eight = 7
Nine = 8
Ten = 9
Jack = 10
Queen = 11
King = 12
End Enum
因此您的值 运行 从 A 的 0 到 K 的 12。在许多情况下,如果您习惯了基于 0 的索引,您会发现生活会变得更轻松 (https://en.wikipedia.org/wiki/Zero-based_numbering)
现在,如果您的牌按升序排列,则很容易判断您是否有顺子。 (我已经 VB 很多年没写了,所以这将是伪代码)
Integer card = rank of first card
//Check each of the following cards
For i = 2 to 5
Integer nextCard = rank of next card
If (nextCard != (card + 1) mod 13) return false
card = nextCard
End For
因为我们 mod 是 13,K 之后的牌是 (12 + 1) mod 13 = 13 mod 13 = 0,也就是预期的 A .
我不太懂扑克,所以我不确定顺子是否可以绕过 A(意思是 Q、K、A、2、3 是顺子?)。如果不是,那么检查 A 高和 A 低这两种情况仍然很容易。 Ace 低是微不足道的,就是这个代码。对于 A 高,它必须从 10 开始。排序后,A 将是第一张牌(这并不理想)因此任何从 [A,10,...] 开始的序列都可以快速重新排列为 [10,。 .., Ace] 然后 运行 通过相同的算法。
男
我要感谢所有愿意花时间提供帮助的人,这是我困扰了好几天的问题!
最后我自己想通了。我这样做的方法涵盖了所有可能性,而不仅仅是一些,而且它还 returns 创建组合的卡片列表。
基函数:
Private Function ReturnStraight(ByVal tempList As List(Of Card)) As List(Of Card)
Dim cardslist As New List(Of List(Of Card)) 'Lists of lists of cards in sequential rank
Dim temporaryList As New List(Of Card) 'Temporary list to add seqeuntial ranked cards to, to later add to the above list
Dim previousCard As Card = tempList(0) 'Gotta start somewhere
For i = 0 To tempList.Count - 1
Dim Card As Card = tempList(i)
If Card.Rank + 1 = previousCard.Rank Then 'If the queen + 1 equals king
If temporaryList.Find(Function(c) c.Rank = previousCard.Rank) Is Nothing Then : temporaryList.Add(previousCard) : End If 'If it doesn't already contain the previous card, add it (we want the king, which we wouldn't get without this)
temporaryList.Add(Card) 'Add the card (the queen)
If i = tempList.Count - 1 Then 'We need this if because of certain scenarios, e.g. King, Queen, Jack, Three, Two - King, Queen, Jack would be added, but three and two would not because we would not enter the else below when Two + 1 = 3...
If temporaryList.Count > 0 Then : cardslist.Add(temporaryList) : End If 'If the list is not empty, add it to the list of list of cards
temporaryList = New List(Of Card) 'Assign it a new empty list of cards to elimate referencing
End If
Else 'If the sequential list breaks (goes from jack to 3), add the temporary list of cards to the list of list of cards
If temporaryList.Count > 0 Then : cardslist.Add(temporaryList) : End If 'If the list is not empty, add it to the list of list of cards
temporaryList = New List(Of Card) 'Assign it a new empty list of cards to elimate referencing
End If
previousCard = Card 'Assign the current card to the previousCard holder
Next
cardslist = cardslist.OrderByDescending(Function(list) list.Count()).ToList() 'We want to list them in descending order by the count of cards
If Not cardslist.Count = 0 Then 'We have to check to see if the cardlist is empty or not, because if it is and we return it, we get an error....
Return cardslist(0) 'Return the highest count card list
End If
Return tempList 'Function failed because there are not enough cards, so return the original list
End Function
我是如何使用它的:
Dim tempList = Cards.GroupBy(Function(card) card.Rank).OrderByDescending(Function(group) group.Count()).SelectMany(Function(group) group).ToList()
If tempList.Find(Function(Card) Card.Rank = CardRank.Ace) IsNot Nothing Then 'We have an ace
Dim noAce = (From Card As Card In tempList Where Card.Rank <> CardRank.Ace Select Card).ToList()
Dim lst = ReturnStraight(noAce)
If lst(lst.Count - 1).Rank = CardRank.Two Or lst(0).Rank = CardRank.King Then
lst.Add((From Card As Card In tempList Where Card.Rank = CardRank.Ace Select Card).ToList(0))
End If
Else
Dim lst = ReturnStraight(tempList)
For Each Card As Card In lst
MsgBox(Card.ToString())
Next
End If