カード・ゲームの制作 VB6
 (b) カードのシャッフル 前へ 目次へ 次へ 

 1. カードのシャッフル

 プログラムでのカードシャッフルは、使用するカードをでたらめな順に取り出して、配列などに順に記録する。必要なカードは配列から順に取り出すことになる。
 大まかな処理の流れは次のように考えられる。カードは1〜53の通し番号と考える。

  1. 使用するカードを配列Aに設定する。
  2. 配列Aから取り出す番号cを乱数で決める。
  3. 配列Aのc番目が未使用であればcを配列B(n)に記憶する(nは1から)。配列Aのc番目は使用済みとする。
  4. 配列Aのc番目が使用済みであれば2.戻り取り出す番号を再度、決める。
  5. 使用する全てのカードについて2.、3.を繰り返す。

 ここでは、カードをシャッフルするサブプロシージャCARDShuffleを作成する。使用するカードのデータをサブプロシージャCARDShuffleの引数とする。


 2. 使用カードのデータ

 サブプロシージャCARDShuffleの引数として渡す使用カードのデータは、配列として渡すことも考えられるが、データサイズが大きくなるので、ここでは文字列データとして渡すことにする。
 次のように53文字で使用する/しないのデータを作成する。1は使用する、0は使用しないとし、先頭の文字がスペードのA、53文字目がJokerに対応する。


図b-1

例) スペードとハートのカードを使うときの使用カードデータは次のようになる。
  11111111111110000000000000111111111111100000000000000
例)偶数のカードとジョーカーを使うときの使用カードデータは次のようになる。
  01010101010100101010101010010101010101001010101010101

 使用カードのデータsから、スペードの5(5番目)の使用する/しないは、Mid(s, 5, 1)で5番目の文字だけを取り出して調べることができる。


 3. 乱数

 乱数については、9Gameを参照すること。ここで使うファンクションプロシージャRansuuを次に示す。

Private Function Ransuu(min, max) As Integer
'整数範囲の乱数
    ransuu = Int((max - min + 1) * Rnd + min)
End Function

 乱数初期化のため、Randomize命令をForm_Loadプロシージャに記述する。


 4. カードシャッフルの処理

 カードをシャッフルするサブプロシージャCARDShuffleを次に示す。

Private Sub CARDShuffle(UsedCard As String)
'カードシャッフル
'引数 UsedCard = 53個の1と0の文字列。 1:使用する、0:使用しない

'
    Dim CardUse(53) As Boolean      'Boolean … 真(True)と偽(False)だけを値として持つ型
    Dim c As Integer, n As Integer, n1 As Integer, nn As Integer

    '※1 カード初期化
    CARDmax = 0        '使用枚数
    For n = 1 To 53
        If Mid(UsedCard, n, 1) = "1" Then    '1文字取り出し
            CARDmax = CARDmax + 1    '使用枚数のカウント
            CardUse(n) = True         '使用する
        Else
            CardUse(n) = False        '使用しない
        End If
    Next n
    '※2 シャッフル
    For n = 1 To CARDmax
        Do
            c = Ransuu(1, CMax)      '取り出すカード番号
            If CardUse(c) Then        '使用するカードのとき
                CardUse(c) = False    '使用しないカード(使用済み)とする
                CARDstock(n) = c        'カード番号を記憶
                Exit Do                    'Doループを抜け出す
            End If
        Loop
    Next n
End Sub

※1 カード初期化で、引数UsedCardを先頭から1文字ずつ調べて、使用するときは枚数をカウントして配列CardUseにTrueを格納する。使用しないときは配列CardUseにFalseを格納する。

※2 シャッフルで、配列CARDStockの1番から順番に乱数で決めたカード番号を記憶する。配列CARDStockの1番から順番に取り出せばシャッフルしたカードを取り出すことになる。


 5. カードシャッフルのテストプログラム

 フォームには図b-2のようにオブジェクトを配置する。


図b-2

Form1のプロパティ
Height 3600
Width 5500

Command1のプロパティ
Caption 表示

Image1のプロパティ
Picture card1.bmp  
Visible False
Picture1(0)のプロパティ
Appearance 0−フラット  
AutoRedraw True
Height 850
Index 0
ScaleMode 3 - ピクセル
Width 630

・プログラムリスト

'カード シャッフル テスト
'※1 グローバル変数
Dim CARDstock(53) As Integer    'カードの山
Dim CARDmax As Integer            'カードの使用枚数

Private Sub Form_Load()
    Dim n As Integer

    Randomize    '乱数の初期化
    With Picture1(0)
        .Left = 120
        .Top = 120
    End With
    For n = 1 To 52
        Load Picture1(n)    'オブジェクトの作成
        With Picture1(n)
            .Left = (n Mod 13) * Picture1(0).Width * 0.6 + 120
            .Top = Int(n / 13) * Picture1(0).Height * 0.6 + 120
            .Visible = True
            .ZOrder    '※2 重なりの変更
        End With
    Next n
End Sub

※1 グローバル変数は、このモジュール全体で共通して参照できる変数である。すなわち、全てのサブ、ファンクションプロシージャで使用できる変数である。これに対して、プロシージャ内だけで使える変数をローカル変数という。

※2 オブジェクトが重なるとき、配置した順で上に配置される。ZOrderは、この上下関係を変更するメソッドである。

Private Sub Command1_Click()
    Dim uc As String
    Dim xx As Integer, yy As Integer

    uc = "1111111111111"    '使用カードのデータ作成
    uc = uc & "1111111111111"
    uc = uc & "1111111111111"
    uc = uc & "1111111111111"
    uc = uc & "1"
    CARDShuffle uc    'カードのシャッフル
    For n = 1 To CARDmax    '※1 カードの取り出し
        xx = 40 * ((CARDstock(n) - 1) Mod 13)
        yy = 55 * Int((CARDstock(n) - 1) / 13)
        Picture1(n - 1).PaintPicture Image1.Picture, 0, 0, , , xx, yy, 40, 55
    Next n
End Sub

Private Sub CARDShuffle(UsedCard As String)
    <<略、(4.カードシャッフルの処理)>>
End Sub

Private Function Ransuu(min, max) As Integer
    <<略、(3.乱数)>>
End Function

※1 カードシャッフル後、配列CARDstockから順にカード番号を取り出して、そのカード番号から画像(Image1)の該当する座標(xx, yy)を計算する。Form_Loadプロシージャで配置した53個のオブジェクト(Picture1(0)〜Picture1(52))に画像を貼り付ける。

 次に実行結果を示すが、乱数を使っているので結果は毎回変わる。ちなみに、Form_Loadプロシージャに書いた乱数を初期化するRandomize命令を取り去ると結果は毎回同じになる。


図b-3 実行例

 適当なファイル名で保存しておく。


 (b) カードのシャッフル 前へ 目次へ 次へ 
Copyright © 2004 Hiroshi Masuda 

 

 

inserted by FC2 system