这是我到目前为止所得到的,发现自己陷入困境。= /
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
答案 0 :(得分:8)
这是错误的做法:
Dim rand As New Random
Dim rand1 As Integer = rand.Next(12)
Dim rand2 As Integer = rand.Next(3)
你可以很容易地得到重复的卡片,因为你在不知道它是否已被处理的情况下挑选这张卡片(即使在这次点击中也是如此!)。您还希望每个游戏/应用程序使用一个随机,而不是每张卡。代表卡片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
实际上,你也想要一个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
不是简单地寻找要粘贴的代码,而应该开始尝试学习概念(即使只是学习你想要/需要了解的概念的名称:类,枚举,收藏,对象,方法......)。上面比一个简单的数组更复杂,但如果你研究它,你会看到Card
和Deck
模仿现实世界的版本。甲板在其他地方建立自己,我们只需要使用它。
接下来是持有牌的玩家类和游戏类,以实现游戏规则,交易牌和控制订单(这些留给学生完成)。这导致形式中几乎没有代码,只是一些调用游戏(并且只有游戏),后者又使用Deck和Player,控制转弯,给玩家卡片等。例如:
Private poker As Game
...
New Game(theImgList, 3) ' 3 == the human player
随机播放按钮:
poker.ShuffleDeck()
poker.NewHand()
thisRound = Game.Rounds.HoleCards
交易按钮:
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
在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)
使用类,表单不知道或关心任何事情发生(比如哪种双重方法),只是在请求时发生。德州HoldEm游戏,社区卡由持有IsHouse
财产的玩家(0)和其他IsHuman
玩家持有(基本上他们的卡总是显示):
.o0(是的,“Jon”全力以赴,请全力以赴。)
我肯定希望看到“Neo”出现'6'。绝对是“Neo”的'6'。
答案 1 :(得分:1)
您需要预先生成整个牌组(52张牌),将其存储在列表/堆栈/队列中,并在需要时将其交给玩家。
双循环应该足以按顺序生成卡片,然后按随机数排序:
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 cards As New List(Of String)
For Each s As String In Suits
For Each f As String In Faces
cards.Add(s & f)
Next
Next
Dim r As New Random
Dim cardsShuffled = cards.OrderBy(Function() r.Next)
编辑:以下是填充标签的方法(只有一种方法):
Dim deck As New Stack(Of String)(cardsShuffled)
For Each lbl As Label in {Label1, Label2, Label3, ...} 'you need to write all
Try
lbl.Text = deck.Pop()
Catch ex As InvalidOperationException
MessageBox.Show("No more cards.")
End Try
Next
参考:
一个合适的解决方案是动态创建标签,但首先要确保你可以使用它。重构通常在 之后完成。你有一个可用的产品。