カード・ゲームの制作 VB6 | |
(4) 役の判定 |
役の判定は、ゲームの勝敗を決めるときに必要になるが、ほかに、プレーヤー以外がもう一枚引くかどうかを判断するのにも使用する。
ここでは、役判定の処理をプログラムする。
1. 役判定
持ち札は(手札)は、次のとおりである。
配列 | オブジェクト | |
親 | Tefuda(0) 〜 Tefuda(2) | picCard(0) 〜 picCard(2) |
場1 | Tefuda(3) 〜 Tefuda(5) | picCard(3) 〜 picCard(5) |
場2 | Tefuda(6) 〜 Tefuda(8) | picCard(6) 〜 picCard(8) |
場3 | Tefuda(9) 〜 Tefuda(11) | picCard(9) 〜 picCard(11) |
場4 | Tefuda(12) 〜 Tefuda(14) | picCard(12) 〜 picCard(14) |
配列の最初の数字(0,3,6,9,12)のどれかを引数として渡すと、役の値を返却するファンクション(関数)プロシージャHyoukaを作成する。
例えば、引数として3を渡すと、場1(Tefuda(3) 〜 Tefuda(5))のカードについて役の値が返却される。
◆ 役の返却値の検討
役 | 儲け | 関数の返却値 | リーチ |
クッピン(親のみの役)…Aと9 | 最強 | 999 | /// |
シッピン(子のみの役)…Aと4 | 3倍返し | 998 | /// |
嵐…3枚とも同じ数字(A,3,5,10) | 10倍返し | 888 | 800+合計 |
嵐…3枚とも同じ数字(2,4,6,7,8,9) | 5倍返し | 777 | 700+合計 |
順子(シュンツ)…同じマークの連番 | 5倍返し | 555 | 500+合計 |
合計の1の位 | 2倍返し | 9,8,7,6,5,4,3,2,1,0 | /// |
リーチの”合計”は1の位の合計のこと。
2. 役判定の処理
「新しいプロジェクト」を開いて、役判定の処理をテストするプログラムを作成する。
作成後に正しく役の判定が行われるかをテストする必要があるので別のプロジェクトとして作成する。(テスト終了後に役判定の処理(プロシージャ)を本来のプロジェクトにコピー&ペーストで追加することにする。)
判定すべきカードは配列Tefuda(グローバル変数)に格納していたので、ここでも同じようにする。配列Tefudaに格納されているカードの番号は0(スペードのA)から順に割り当てられている。
*カード番号の一覧マーク/数字 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | J | Q | K |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
スペード | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | - | - | - |
クラブ | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | - | - | - |
ハート | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | - | - | - |
ダイヤ | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | - | - | - |
Height | 4500 |
---|---|
Width | 6000 |
フォームに次のオブジェクトを配置する。
テキストボックス ・・・ Text1, Text2
コマンドボタン ・・・ Command1, Command2
ラベル ・・・ Label1
各オブジェクトの大きさなどは適当に設定する。
MultiLine | True |
---|---|
ScrollBars | 2 - 垂直 |
[2枚テスト]ボタンをクリックすると、カード2枚すべての組合せについて判定をし、[3枚テスト]をクリックすると、Text2に入力された番号を1枚目として2,3枚目のすべての組合せについて判定をする。結果はText1に表示される。
・プログラムリスト(役判定の処理)
Dim Tefuda(3) As Integer 'グローバル変数
Private Function Hyouka(cnum As Integer) As Integer
'役の評価
'引数 cnum … 持ち札の番号(配列の添字:0=親、3,6,9,12=場)
'グローバル Tefuda() … カード番号(0〜52、0=スペードA)
' 倍率 返却値1 返却値2
' クッピン(親のみの役)…Aと9 最強 999 ///
' シッピン(子のみの役)…Aと4 3倍返し 998 ///
' 嵐…3枚とも同じ数字(A,3,5,10) 10倍返し 888 800
' 嵐…3枚とも同じ数字(2,4,6,7,8,9) 5倍返し 777 700
' 順子(シュンツ)…同じマークの連番 5倍返し 555 500
' 合計の1の位 2倍返し 9,8,7,6,5,4,3,2,1,0 ///
Dim tf(3) As Integer '持ち札
Dim cm(3) As Integer, cn(3) As Integer 'カードのマークcmと数字cn
Dim goukei As Integer
Dim n As Integer, n2 As Integer, wk As Integer
tf(1) = Tefuda(cnum) '※1 カード番号コピー 1枚目
tf(2) = Tefuda(cnum + 1) 'カード番号コピー 2枚目
tf(3) = Tefuda(cnum + 2) 'カード番号コピー 3枚目
For n = 1 To 2 '※2 カード番号のソート(昇順)
For n2 = n + 1 To 3
If tf(n) > tf(n2) And tf(n)
<> -1 And tf(n2) <> -1 Then
wk = tf(n)
tf(n) = tf(n2)
tf(n2) = wk
End If
Next n2
Next n
For n = 1 To 3 '※3 マークと数字に分解
If tf(n) = -1 Then
cm(n) = -1
'マーク
cn(n) = -1 '数字
Else
CardMark tf(n), cm(n), cn(n)
'マークと数字
End If
Next n
'※4 役判定
If cnum = 0 Then 'クッピン(親のみの役)…Aと9 最強 999
If cn(1) = 1 And cn(2) = 9 And cn(3) = -1 Then
Hyouka = 999
Exit Function
End If
Else 'シッピン(子のみの役)…Aと4 3倍返し 998
If cn(1) = 1 And cn(2) = 4 And cn(3) = -1 Then
Hyouka = 998
Exit Function
End If
End If
If cn(1) = cn(2) And cn(2) = cn(3) Then '嵐
If cn(1) = 1 Or cn(1) = 3 Or cn(1) = 5 Or cn(1)
= 10 Then
Hyouka = 888 'A,3,5,10-10倍返し 888
Exit Function
Else '2,4,6,7,8,9-5倍返し 777
Hyouka = 777
Exit Function
End If
ElseIf cn(1) = cn(2) And cn(3) = -1 Then '嵐リーチ
If cn(1) = 1 Or cn(1) = 3 Or cn(1) = 5 Or cn(1)
= 10 Then
Hyouka = 800 'A,3,5,10-10倍返し 800
Else '2,4,6,7,8,9-5倍返し 700
Hyouka = 700
End If
ElseIf cm(1) = cm(2) And cm(2) = cm(3) Then '順子(シュンツ)
If cn(1) = cn(2) - 1 And cn(1) = cn(3) - 2
Then
Hyouka = 555 '5倍返し 555
Exit Function
End If
ElseIf cm(1) = cm(2) And cm(3) = -1 Then '順子(シュンツ)リーチ
If cn(1) = cn(2) - 1 Then
Hyouka = 500 '5倍返し 500
End If
End If
If cn(3) = -1 Then
goukei = (cn(1) + cn(2)) Mod 10 '合計の1の位-2倍返し 9,8,7,6,5,4,3,2,1,0 ///
Else
goukei = (cn(1) + cn(2) + cn(3)) Mod 10 '合計の1の位-2倍返し 9,8,7,6,5,4,3,2,1,0 ///
End If
Hyouka = Hyouka + goukei
End Function
※1 カード番号はソートして順番が変わってしまうのでグローバルのTefudaに影響がないように配列tfにコピーしている。
※2 最もシンプルなソートのアルゴリズムである。
※3 カード番号を13で割り算し、その商がカードのマーク、その余りに1を加算したものがカードの数字となる。
※4 役の判定処理。カード番号のソート後に行う。
・クッピンとシッピン・・・カード2枚(cn(3)が-1)である。 cn(1)=1 かつ cn(2)=9シッピンは 4)である。
・嵐・・・カード3枚(cn(1),cn(2),cn(3))とも同じ数字である。 リーチはcn(3)が-1である。
・順子・・・カード3枚(cm(1),cm(2),cm(3))とも同じマークであり、かつ、連番である。 リーチはcm(3)が-1である。
・その他・・・カードの数字をすべて加算した1の位が得点となる。
カードがないときは配列cn,cmともに-1であるからどちらで判定しても良い。
・プログラムリスト(2枚テストの処理)
Private Sub Command1_Click()
Dim cnum(40) As Integer 'カード番号(使用分)格納
Dim n As Integer, cn As Integer
Dim n1 As Integer, n2 As Integer, n3 As Integer, rr As Integer
cn = 1 '※1 使用するカード番号の設定
For n = 1 To 10
cnum(cn) = n - 1
cn = cn + 1
Next n
For n = 14 To 23
cnum(cn) = n - 1
cn = cn + 1
Next n
For n = 27 To 36
cnum(cn) = n - 1
cn = cn + 1
Next n
For n = 40 To 49
cnum(cn) = n - 1
cn = cn + 1
Next n
Text1.Text = ""
For n1 = 1 To 40 - 1 '※2 役判定テスト
For n2 = n1 + 1 To 40
DoEvents
Tefuda(1) = cnum(n1) '1枚目
Tefuda(2) = cnum(n2) '2枚目
Tefuda(3) = -1 '3枚目 なし
rr = Hyouka(1) '役判定処理
kekka rr
Next n2
Next n1
Text1.Text = Text1.Text & "END"
End Sub
※1 使用するカード40枚のカード番号を配列cnumに順番に記憶させる。
※2 配列(グローバル)Tefudaにカード番号をセットして役判定処理Hyoukaを呼び出す。
テストするカードは1枚目のカード番号と1枚目のカード番号以降すべてのカード番号との組合せについて調べる。
Hyoukaプロシージャの引数に1を指定しているので、Tefuda(1)〜Tefuda(3)について判定する。実際には親のカードを調べるときの引数である。
・プログラムリスト(3枚テストの処理)
Private Sub Command2_Click()
Dim cnum(40) As Integer 'カード番号(使用分)
Dim n As Integer, cn As Integer
Dim n1 As Integer, n2 As Integer, n3 As Integer, rr As Integer
cn = 1 '※1 使用するカード番号の設定
For n = 1 To 10
cnum(cn) = n - 1
cn = cn + 1
Next n
For n = 14 To 23
cnum(cn) = n - 1
cn = cn + 1
Next n
For n = 27 To 36
cnum(cn) = n - 1
cn = cn + 1
Next n
For n = 40 To 49
cnum(cn) = n - 1
cn = cn + 1
Next n
Text1.Text = ""
n1 = Val(Text2.Text) '※2 役判定テスト
For n2 = n1 + 1 To 40 - 1
For n3 = n2 + 1 To 40
DoEvents
Tefuda(1) = cnum(n1) '1枚目
Tefuda(2) = cnum(n2) '2枚目
Tefuda(3) = cnum(n3) '3枚目
rr = Hyouka(1) '役判定処理
kekka rr
Next n3
Next n2
Text1.Text = Text1.Text & "END"
End Sub
※1、※2とも2枚テストの処理と同じである。
・プログラムリスト(結果表示)
Private Sub kekka(rr As Integer)
Dim x1 As Integer, msg As String
msg = ""
For n = 1 To 3 '※1 マークと数字に分解
x1 = Int(Tefuda(cnum + n) / 13)
'マーク
If x1 = 0 Then 'スペード
msg = msg & "S"
ElseIf x1 = 1 Then 'クラブ
msg = msg & "C"
ElseIf x1 = 2 Then 'ハート
msg = msg & "H"
ElseIf x1 = 3 Then 'ダイヤ
msg = msg & "D"
Else
msg = msg & " "
End If
msg = msg & Str((Tefuda(cnum + n) Mod 13)
+ 1) '数字
msg = msg & " "
Next n
' 倍率 返却値1 返却値2
' クッピン(親のみの役)…Aと9 最強 999 ///
' シッピン(子のみの役)…Aと4 3倍返し 998 ///
' 嵐…3枚とも同じ数字(A,3,5,10) 10倍返し 888 800
' 嵐…3枚とも同じ数字(2,4,6,7,8,9) 5倍返し 777 700
' 順子(シュンツ)…同じマークの連番 5倍返し 555 500
' 合計の1の位 2倍返し 9,8,7,6,5,4,3,2,1,0 ///
'※2 役判定
If rr = 999 Then
msg = msg & "クッピン"
ElseIf rr = 998 Then
msg = msg & "シッピン"
ElseIf rr = 888 Then
msg = msg & "嵐10倍"
ElseIf rr = 777 Then
msg = msg & "嵐5倍"
ElseIf rr = 555 Then
msg = msg & "順子"
ElseIf rr >= 800 Then
msg = msg & "嵐10倍リーチ"
ElseIf rr >= 700 Then
msg = msg & "嵐5倍リーチ"
ElseIf rr >= 500 Then
msg = msg & "順子リーチ"
Else
msg = msg & "なし" & Str(rr)
'役なしのメッセージを省略するときコメントにする
'msg = ""
'役なしのメッセージを省略するときコメントを削除
End If
If msg <> "" Then
Text1.Text = Text1.Text & msg & vbCrLf
'結果をText1に表示
End If
Text1.SelStart = Len(Text1.Text)
End Sub
※1 マークを記号(S,C,H,D)に変換している。
※2 役判定(Hyoukaプロシージャ)の結果をメッセージに変換している。
・プログラムリスト(初期設定)
Private Sub Form_Load()
Text1.Text = ""
Text2.Text = "1"
End Sub
実行して、おかしな判定がないか自分の目で確かめる。
40枚から2枚を取り出す組合せなので、780通りある。3枚テストは最大741通りである。
テスト用のプログラムは適当な名前で保存しておく。
この後、カードゲームで必要になるのはHyoukaプロシージャだけである。
3. プロシージャの移動
Hyoukaプロシージャ(Private Function Hyouka(cnum As Integer) As Integer 〜 End
Function)までをゲームプログラムにコピーする。
注意 宣言の「Dim Tefuda(3) As Integer 'グローバル変数」の行は不要である。
手順
(4) 役の判定 | |
Copyright © 2004 Hiroshi Masuda |