Visual Basic 评估直接组合的卡片列表

本文关键字:列表 组合 Basic 评估 Visual | 更新日期: 2023-09-27 18:30:52

我正在创建一个扑克评估器,但我在弄清楚如何检查"直接"组合时遇到了麻烦(我还需要知道是什么牌组成了组合)。

我有一个卡片列表,所以我需要弄清楚以下内容:

列表是否包含王牌?

如果是:

  • 创建一个 ace 较高的新列表。
  • 创建一个 ace 较低的新列表。
  • 对两个列表运行检查,并返回具有较高直接组合的卡片数的卡数。

如果否:

  • 运行检查列表并返回直接组合的卡。

如何检查直线组合:

浏览列表,检查当前卡牌的等级 + 1 是否等于前一张卡牌的等级。

使用这种方法,我们将遇到一个问题。

请考虑以下因素:

  1. 女王
  2. 千斤顶

结果将是:

  1. 国王 = 什么都没有 = 假
  2. 女王=国王=真
  3. 杰克 = 女王 = 真
  4. 三 = 插孔 = 假
  5. 二 = 三 = 真

那个结果不好,那种情况下的结果应该是:国王,王后,杰克。

我不确定如何以聪明的方式将其放入代码中,或者只是以一种可行的方式。我尝试过做LINQ,也尝试过使用for循环。

这是我制作的卡片类:

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

也许我这样做的方式不对?

编辑:直是五张顺序等级的牌。请注意,在德州扑克中,Aces 可以是高或低。编辑:这是我列出我的卡ATM的方式(当然可以更改以适应其他方法)

Dim tempList = Cards.GroupBy(Function(card) card.Rank).Reverse().OrderByDescending(Function(group) group.Count()).SelectMany(Function(group) group).ToList()

Visual Basic 评估直接组合的卡片列表

您可以做的是找到最小和最大卡,并使用总和来检查它是否是直的。伪代码:

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

因此,您的值从 Ace 的 0 到 King 的 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

由于我们按 13 mod,国王之后的牌将是 (12 + 1) mod 13 = 13 mod 13 = 0,这是 Ace,正如预期的那样。

我真的不懂扑克,所以我不确定直道是否可以通过王牌(意思是 Q、K、A、2、3 是直的?如果没有,那么检查 ace 高和 ace 低这两种情况仍然很容易。王牌低是微不足道的,就是这个代码。对于 ace 高,它必须从 10 开始。排序后,Ace 将是第一张牌(这并不理想),因此任何以 [Ace, 10, ...] 开头的序列都可以快速重新排列为 [10, ..., Ace],然后通过相同的算法运行。

我要感谢所有提供时间和帮助的人,这是我几天来一直在努力解决的问题!

最后我自己想通了。我的方法涵盖了所有可能性,而不仅仅是一些,它还返回创建组合的卡片列表。

基本函数:

    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