2011-11-13 14 views
3

52枚のカードの標準デッキを配列で表しています。各カードは整数で表されます。私はカードをシャッフルするために以下の関数を書いた。下のコードは大丈夫ですか?VB.NETでカードのデッキをシャッフルする方法を書いてください

Module Module3 

Sub Main() 

    ' initialize array 
    Dim Cards(52) As Integer 

    ' Unit Test 
    ' Pass array as argument. 
    Console.WriteLine(shuffle(Cards)) 

End Sub 

Function shuffle(ByVal Cards() As Integer) 

    Dim counter = 1 
    Dim rand = New Random() 

    For Each card In Cards 

     ' Grab random number with range of 52 
     Dim n = rand.Next(52) 

     ' Pick a card 
     Dim temp = Cards(counter) 

     ' Swap picked card with random card 
     Cards(counter) = Cards(n) 
     Cards(n) = temp 

     counter += 1 

    Next 

    Return (Cards) 

End Function 

End Module 
+0

ように重複する可能性が知られているがVB.NET?](http://stackoverflow.com/questionsで、リストをランダム化する簡単な方法はあります/ 554587/vb-netの一覧にある簡単な方法でランダム化する) –

+0

@Bruno - リストの使用を検討してください。私が提供したコードを見てください。 – dbasnett

答えて

4

いいえ、コードはあなたの言うことをしません。

Dim Cards(52) As Integer 

これは52は使用しないで、53枚のカードの配列を作成します。

Dim Cards(51) As Integer 

シャッフリング、デッキに以前カードと各カードを交換(またはそれ自体)ではなく、どこでデッキ。 (これはFisher-Yatesシャッフルの原理です)

ループとは別のカウンターを使用する代わりに、カウンターをループに使用します。

Dim rand = New Random() 

For counter = 0 to Cards.Length - 1 

    Dim n = rand.Next(counter + 1) 

    Dim temp = Cards(counter) 
    Cards(counter) = Cards(n) 
    Cards(n) = temp 

Next 
1

この件に関するJeff Atwoodのブログ記事をご覧ください。これは私が配列を使用していないだろう、いくつかのゲームのために使用されようとしている場合は、私があるため容易項目のリストを使用することになり

http://www.codinghorror.com/blog/2007/12/shuffling.html

+0

私はIntels Bull Mountainのアーキテクチャがこのすべてにどのように影響を与えるのだろうか? – dbasnett

1

を追加/削除することができます。

Module Module1 

    Dim deck As New List(Of Integer) 
    Dim prng As New Random 

    Sub Main() 
     newDeck() 
     showDeck() 
     shuffle() 
     showDeck() 
     Dim s As String 
     Do 
      s = Console.ReadLine() 
      Select Case s 
       Case "s" 
        showDeck() 
       Case "c" 
        If deck.Count = 0 Then 
         Console.WriteLine("No cards") 
        Else 
         'take top card 
         Dim foo As Integer = deck(0) 
         deck.RemoveAt(0) 
         Console.WriteLine(foo.ToString) 
        End If 
       Case "n" 
        newDeck() 
        shuffle() 
      End Select 
     Loop Until s.ToLower = "x" 
    End Sub 

    Sub newDeck() 
     deck = Enumerable.Range(1, 52).ToList 'create deck 
    End Sub 

    Sub shuffle() 
     deck = deck.OrderBy(Function(r) prng.Next).ToList 
    End Sub 

    Sub showDeck() 
     Dim ctr As Integer = 0 
     Console.WriteLine() 
     For Each card As Integer In deck 
      Console.Write("{0}", card.ToString.PadLeft(4, " "c)) 
      ctr += 1 
      If ctr Mod 10 = 0 Then Console.WriteLine() 
     Next 
     Console.WriteLine() 
    End Sub 
End Module 

これは、コンピュータが現実の世界を正確に模倣すべきではないと私は考えていました。まず、乱数ジェネレータの種を知ることで問題を示すプログラムがあります。

'create a form with three buttons and a richtextbox 
Dim deckIdx As New List(Of Integer) 
Dim cards As New List(Of card) 
Dim prng As New Random 

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
    newDeck() 
    shuffle() 
    showDeck() 
End Sub 

Private Sub Button3_Click(sender As System.Object, e As System.EventArgs) Handles Button3.Click 
    'show next five cards 
    Dim sb As New System.Text.StringBuilder 
    sb.AppendLine() 
    For x As Integer = 1 To 5 
     Dim foo As card = getTopCard() 
     If Not foo Is Nothing Then sb.AppendFormat("{0}", foo.theCard.ToString.PadLeft(4, " "c)) 
    Next 
    RichTextBox1.AppendText(sb.ToString) 
    RichTextBox1.ScrollToCaret() 
End Sub 

Private Sub Form1_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown 
    Button1.PerformClick() 
End Sub 

Class card 
    Public theCard As Integer 
    Public count As Integer 
End Class 

Sub newDeck() 
    prng = New Random(42) '<<<<<<<<<<<<<<<<<<<<<<<< OOPS!!! 
    deckIdx = Enumerable.Range(0, 51).ToList 'create deck indicies 
    cards = New List(Of card) 
    For Each cIDX As Integer In deckIdx 
     Dim foo As New card 
     foo.theCard = cIDX 
     foo.count = 0 
     cards.Add(foo) 
    Next 
End Sub 

Sub shuffle() 
    deckIdx = deckIdx.OrderBy(Function(r) prng.Next).ToList 
End Sub 

Function getTopCard() As card 
    If deckIdx.Count > 0 Then 
     Dim foo As New card 
     foo.theCard = cards(deckIdx(0)).theCard 
     foo.count = cards(deckIdx(0)).count 
     deckIdx.RemoveAt(0) 
     Return foo 
    Else 
     Return Nothing 
    End If 
End Function 

Sub showDeck() 
    Dim ctr As Integer = 0 
    Dim sb As New System.Text.StringBuilder 
    For Each card As Integer In deckIdx 
     sb.AppendFormat("{0}", cards(card).theCard.ToString.PadLeft(4, " "c)) 
     ctr += 1 
     If ctr Mod 10 = 0 Then sb.AppendLine() 
    Next 
    RichTextBox1.Text = sb.ToString 
End Sub 

プログラムを実行してbutton1/3を繰り返し押すと、同じ結果が繰り返し表示されます。コンピュータが現実の世界を正確に模倣しなければならないという考えに固執するつもりならば、明らかな修正はPRNGを再シードすることではありません。しかし、もし我々が別のアプローチをとったらどうでしょうか?

は何も変わっていないことを確認するために、押しボタン1と3、前と同じようにこのコード

Dim bkgShuffle As Threading.Thread 
Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click 
    Button2.Enabled = False 
    bkgShuffle = New Threading.Thread(AddressOf shuffleBkg) 
    bkgShuffle.IsBackground = True 
    bkgShuffle.Start() 
End Sub 

Sub shuffleBkg() 
    Do 
     Threading.Thread.Sleep(50) 
     shuffle() 
    Loop 
End Sub 

実行にプログラムを追加します。あなたが満足したら、ボタン2を押して、ボタン1と3を押します。

カードを人でプレイすると、デッキが常にシャッフルされているのではないことは明らかですが、それは何か変わるだろうか?私がオンラインでカードをプレイすると、デッキが常にシャッフルされているかどうか知っていますか?

コードは、ボックスの外で考えると、完成品と見なされるべきではありません。

編集: Bull Mountainがこれに影響する可能性があります。

+0

非常に良い。ありがとうございました! – Bruno

+0

あなたのshuffleBkgメソッドで無限ループを終了させるのは何ですか? –

+0

アプリケーションが終了します。私が言ったように、これはある点を示すことでした。 – dbasnett

0

これが正式になりました「ブリッグス」シャッフル

Module module1 

Dim cards(51) As String 
Dim trues(51) As Boolean 
Dim number, Truecheck As Integer 
Dim stores, loopy As String 

Sub main() 

    number = 1 

    cards(0) = "Ace of Spades" 
    cards(10) = "Jack of Spades" 
    cards(11) = "Queen of Spades" 
    cards(12) = "King of Spades" 

    cards(13) = "Ace of Clubs" 
    cards(23) = "Jack of Clubs" 
    cards(24) = "Queen of Clubs" 
    cards(25) = "King of Clubs" 

    cards(26) = "Aec of Diamonds" 
    cards(36) = "Jack of Diamods" 
    cards(37) = "Queen of Diamonds" 
    cards(38) = "King of Diamonds" 

    cards(39) = "Ace of Hearts" 
    cards(49) = "Jack of Heats" 
    cards(50) = "Queen of Hearts" 
    cards(51) = "King of Hearts" 


    For i = 1 To 9 
     number = number + 1 
     cards(i) = number.ToString + " of Spades" 
    Next 

    number = 1 

    For i = 14 To 22 
     number = number + 1 
     cards(i) = number.ToString + " of Clubs" 
    Next 

    number = 1 

    For i = 27 To 35 
     number = number + 1 
     cards(i) = number.ToString + " of Diamonds" 
    Next 

    number = 1 

    For i = 40 To 48 
     number = number + 1 
     cards(i) = number.ToString + " of Hearts" 
    Next 

    For i = 0 To 51 
     Console.WriteLine(cards(i)) 
    Next 


    Console.WriteLine("") 
    Console.WriteLine("") 

    For i = 0 To 51 

linetrue: 

     Randomize() 
     stores = cards(i) 
     Truecheck = Int(Rnd() * 51) 
     If trues(Truecheck) = True Then GoTo linetrue 

     trues(i) = True 
     cards(i) = cards(Truecheck) 
     cards(Truecheck) = stores 
     Console.WriteLine(cards(i)) 

    Next 


End Sub 


End Module 
関連する問題