我如何随机向牌手洗牌和交易?

这是我到目前为止,发现自己卡住了。= /

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 

您需要预先生成全部牌(52张牌),将其存储在列表/堆栈/队列中,并在需要时将其交给玩家。

双循环应该足够好,可以顺序生成卡片,然后按随机数字sorting:

 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 

参考:

  • Stack(Of T).Pop @ MSDN 。

一个合适的解决scheme是dynamic创build标签,但首先确保您可以得到这个工作。 重构通常是你有一个工作产品完成的。

这是错误的做法:

 Dim rand As New Random Dim rand1 As Integer = rand.Next(12) Dim rand2 As Integer = rand.Next(3) 

你可以很容易地得到重复的卡,因为你正在select这张卡,而不知道它是否已经被处理(即使在这个点击!)。 你也想要一个随机用于每个游戏/应用程序,而不是每个卡。 将一张卡片作为suit & face 将会起作用,但它将两个重要的信息粘合在一起 – 在大多数游戏中,您稍后必须parsing它才能获取该信息。

甲板由52张牌组成; 每张卡片由西装和等级组成。 让我们build立一个简单的类或两个模仿:

 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作为单独属性,您可以testing一个玩家与另一个玩家的卡片,以查看谁拥有最好的卡片。 这在一些像“大酒杯”这样的游戏中很容易,因为你所关心的只是排名和总和。 在其他游戏中,手牌评估更为复杂,因为您可以使用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 ' (eg 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 

而不是简单地寻找代码粘贴,你应该开始尝试学习概念 (即使它只是学习你想要/需要了解更多的概念名称:类,枚举,集合,对象,方法… )。 上面的内容比简单的数组要复杂得多,但是如果你学习它,你会看到CardDeck模仿真实世界的版本。 甲板build立在其他地方,我们只需要使用它。

接下来是一个玩家类,持有这些牌和一个游戏类来执行游戏规则,交易卡和控制顺序(这些留给学生完成)。 这会导致几乎没有代码的forms,只是一些调用游戏(而只有游戏),反过来使用甲板和玩家,控制轮​​stream,给玩家等卡,例如:

 Private poker As Game ... New Game(theImgList, 3) ' 3 == the human player 

随机播放button:

  poker.ShuffleDeck() poker.NewHand() thisRound = Game.Rounds.HoleCards 

交易button:

  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) 

使用类,表单不知道或关心如何发生任何事情(如哪个suff方法),只是在请求时发生。 德克萨斯扑克游戏,其中社区牌由玩家(0)拥有一个IsHouse财产和一些其他玩家是人(基本上是他们的牌总是显示):

在这里输入图像描述

.o0(是的,“乔恩”全力以赴,请全力以赴。)
而且我一定要看到“Neo”出现了“6”。 绝对是“新”的“6”。