这是我到目前为止发现自己卡住了.=/
Private Sub Dealbtn_Click(sender As Object, e As EventArgs) Handles Dealbtn.Click
Dim Suits() As String = {"S", "D", "C", "H"}
Dim Faces() As String = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"}
Dim rand As New Random
Dim rand1 As Integer = rand.Next(12)
Dim rand2 As Integer = rand.Next(3)
Label2.Text() = Faces(rand1) + Suits(rand2)
End Sub
Run Code Online (Sandbox Code Playgroud)
这是错误的方法:
Dim rand As New Random
Dim rand1 As Integer = rand.Next(12)
Dim rand2 As Integer = rand.Next(3)
Run Code Online (Sandbox Code Playgroud)
您可以很容易地得到重复的卡片,因为您在不知道它是否已经被处理的情况下选择了这张卡片(即使在此点击!).你还希望每个游戏/应用程序使用一个随机,而不是每张卡.代表卡片suit & face 会起作用,但它会将两个重要的信息粘合在一起 - 在大多数游戏中,您稍后将不得不解析它以获取该信息.
甲板由52张牌组成; 每张卡片均由西装和等级制成.让我们构建一个简单的类或两个模仿:
Public Class Card
Public Property Suit As String
Public Property Rank As Integer
' card images from
' http://www.jfitz.com/cards/
Public Property Img As Image
Private Faces() As String = {"Jack", "Queen", "King", "Ace"}
' for text version of the game
Public Function CardText() As String
Dim tmp As String = Rank.ToString
If Rank = 1 Then
tmp = "Ace"
ElseIf Rank >= 11 Then
tmp = Faces(Rank - 11)
End If
Return String.Format("{0} of {1}", tmp, Suit)
End Function
' iDeck class will assign Rank, Suit and img to an "empty" card
Public Sub New(strSuit As String, nRank As Integer, i As Image)
Suit = strSuit
Rank = nRank
Img = i
End Sub
Public Overrides Function ToString() As String
Return CardText()
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
实际上,你也想要一个Value属性,因为在大多数游戏中它与Rank不同.
使用Rank和Suit作为单独的属性,您可以测试一个玩家与另一个玩家的牌以查看谁拥有最好的牌.这在BlackJack等游戏中很容易,因为你所关心的只是Rank和总和.其他游戏中的手牌评估更为复杂,因为你可以使用FullHouse和Flush等组合.现在甲板(两种洗牌方法都用于说明目的):
Public Class Deck
Dim rand As Random
' the deck will be built in the same order a real deck comes in
Private Suits() As String = {"Spades", "Diamonds", "Clubs", "Hearts"}
Private Rank() As Integer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
' useful for blackjack
Private Const Ace As Integer = 1
' freshly opened pack where they are in order. this is reused rather
' than building a new deck each time
Private freshDeck As List(Of Card)
' shuffled deck; Stack prevents any bugs from a botched counter var
Private shoe As Stack(Of Card)
' using an imagelist but My.Resources could work depending on card names
Private imglist As ImageList
' the GAME object passes us the imagelist holding the card pics
Public Sub New(imgs As ImageList) ' ctor
' new random ONCE
rand = New Random
imglist = imgs
NewDeck()
End Sub
' create a new deck (done ONCE) but could be called again
Private Sub NewDeck()
freshDeck = New List(Of Card) ' new object
For Each s As String In Suits
For Each n As Integer In Rank
Dim key As String = CardKey(s, n)
freshDeck.Add(New Card(s, n, imglist.Images(key)))
Next
Next
End Sub
Private keys() As String = {"J", "Q", "K"}
Private Function CardKey(suit As String, rank As Integer) As String
' convert Suit / Key to the key used in the imglist
' (e.g C1.JPG for Clubs, Ace)
' cards come from http://www.jfitz.com/cards/
' use the windows set (or rename them all)
Dim key As String = suit.Substring(0, 1) ' => C, H, D, S
If rank < 11 Then
key &= rank.ToString
Else
key &= keys(rank - 11) ' cvt 11, 12, 13 => J, Q, K
End If
Return key & ".png"
End Function
' Shuffle deck using Fisher-Yates; sub optimal here since we "use up"
' the shoe each hand and are not reshuffling a deck
Public Sub Shuffle()
' new temp deck preserves the new deck starting point
Dim thisDeck As New List(Of Card)(freshDeck.ToArray)
Dim tmp As Card
Dim j As Integer
' hi to low, so the rand pick result is meaningful
' lo to hi introduces a definite bias
For i As Integer = thisDeck.Count - 1 To 0 Step -1
j = rand.Next(0, i + 1) ' NB max param is EXCLUSIVE
tmp = thisDeck(j)
' swap Card j and Card i
thisDeck(j) = thisDeck(i)
thisDeck(i) = tmp
Next
' using a stack for the actual deck in use; copy shuffled deck to the Shoe
shoe = New Stack(Of Card)(thisDeck.ToArray)
End Sub
' shuffle using random and LINQ (neo's answer)
Public Sub ShuffleLinq()
' using the same rand per app run may be random enough
' but would not suffice for most 'serious' games or standards
shoe = New Stack(Of Card)(freshDeck.OrderBy(Function() rand.Next))
End Sub
Public Function DealCard() As Card
' get a card
If shoe.Count = 0 Then
' ToDo: out of cards
' happens with 9+ handed, 7 card games and many hi-lo games...
' usually mucked and burn cards are reshuffled
' some games use shared cards at the end
' (muck/burn list not implemented)
End If
Return shoe.Pop
End Function
End Class
Run Code Online (Sandbox Code Playgroud)
您应该开始尝试学习所呈现的概念,而不是简单地寻找要粘贴的代码(即使它只是学习您想要/需要了解的概念的名称:类,枚举,集合,对象,方法...... ).上面比一个简单的数组更复杂,但如果你研究它,你会看到Card并Deck模仿现实世界的版本.甲板在其他地方建立自己,我们只需要使用它.
接下来是持有牌的玩家类和游戏类,以实现游戏规则,交易牌和控制订单(这些留给学生完成).这导致形式中几乎没有代码,只是一些调用游戏(并且只有游戏),而游戏又使用Deck和Player,控制转弯,给玩家卡等.例如:
Private poker As Game
...
New Game(theImgList, 3) ' 3 == the human player
Run Code Online (Sandbox Code Playgroud)
随机按钮:
poker.ShuffleDeck()
poker.NewHand()
thisRound = Game.Rounds.HoleCards
Run Code Online (Sandbox Code Playgroud)
交易按钮:
Select Case thisRound
Case Game.Rounds.HoleCards
poker.NewHand() ' clears the display etc
poker.DealRound(thisRound) ' deal cards
thisRound = Game.Rounds.Flop ' change round indicator
Case Game.Rounds.Flop ' even this could be internal to Game(poker)
poker.DealRound(thisRound)
thisRound = Game.Rounds.Turn
Run Code Online (Sandbox Code Playgroud)
在Game.DealRound中:
Case Rounds.Flop
myDeck.DealCard() ' burn card
players(0).AddCard(myDeck.DealCard) ' Player(0) is the house or community
players(0).AddCard(myDeck.DealCard)
players(0).AddCard(myDeck.DealCard)
Run Code Online (Sandbox Code Playgroud)
使用类,表单不知道或关心任何事情发生(如哪种双重方法),只是在请求时发生.德州HoldEm游戏,社区卡由玩家(0)持有,玩家(0)拥有IsHouse财产和其他一些玩家IsHuman(基本上他们的卡总是显示):

.o0(是的,"乔恩"全力以赴,请全力以赴.)
我当然希望看到一个'6'出来为"Neo".绝对是"Neo"的'6'.