Visual Basic 初級講座 |
Visual Basic 中学校 > 初級講座 >
第14回 実技1 ちんちろりん
今回は これまでに登場した知識を活用して、簡単なゲーム「ちんちろりん」を作ります。これまでに解説していない知識も登場しますが今回の目標は実際にアプリケーションを作る手順を体験してもらうことなので、多少知らないことがあっても気にしないで下さい。一応簡単な解説もしてあります。
この回の要約 ・サイコロゲーム「ちんちろりん」をプログラムする。 |
今回はゼロからプログラムを完成させる過程を追っていくので、長い上にごちゃごちゃしてわかりにくくなっていしまっています。
そこで、説明を読む前に注意点を書いておきます。
まず、第1回から通して読んでいただいている場合で、今回の内容を読むのが苦痛な場合は無理して読む必要はありません。この回は飛ばして次の回を読んでください。
次に、完成版をダウンロードできるようにしておきますので、先にダウンロードして動かしたりプログラムをみたりしながら説明を読んだ方が理解しやすいかもしれません。
完成版ちんちろりん
25.59KB lha形式(拡張子lzh)
ここで提供する完成版はVB.NET2003で作成したものです。VB2005でも開いて実行することはできますが、これから説明する手順の結果できあがるものとはフォルダの構造など一部異なる部分が生じます。 |
完成版をダウンロードしてしまうと自分で手順を追って実際にやってみる気がしなくなる危険がありますので、やる気にあふれている方は注意してください。
今回のプログラムは部分部分を切り出して説明しています。最後まで読めばすべての部分が説明されていることになります。やる気にあふれている方は部分部分が登場するたびに実際にそれをVBに打ち込んで見てください。コピー貼り付けでも構いません。とにかく実際にやってみるのと見ているだけなのでは経験として格段の差があります。
実際にやってみて初めて気が付くこともたくさんあるはずです。
今回作成するゲームはサイコロゲームの「ちんちろりん」とほとんど同じルールですが、説明の便宜のためにちょこちょことルールを変えました。
下に画像を載せますが、画像を見てがっかりしないで下さい。あくまでVBのための教材だと思って実際に作ってみて下さい。
■画像1:完成するゲームの画面
このゲームではプレイヤーとコンピュータがサイコロを3つずつふります。サイコロの目の出方によって「役」が決まっていて、高い役を出した方が勝ちです。勝った方は賭け金に役による倍率をかけた金額を獲得できます。
ゲームの流れは、まず賭け金を入力して、プレイヤーが「ちんちろりん」ボタンをクリックします。そうするとプレイヤーの3つのサイコロがふられたことになって、プレイヤーの役が決定します。その後、自動的にコンピュータもサイコロを振り、コンピュータの役が決定します。そして、お互いの役で勝負が決定します。
なお、特例として、役が「ヒフミ」の場合はヒフミを出した方が賭け金の3倍を支払います。
役は次の通りです。弱い役の順番に並んでいます。
役 | 倍率 | 例 | 説明 |
ヒフミ | -3 | 1 2 3 | さいころの目が1、2、3の場合。(数字の順番はどうでも良い) |
目なし | 0 | 5 2 4 | どの役にも当てはまらなかった場合 |
出目 | 1 | 4 5 4 | 2つのサイコロで同じ目が出た場合。出目1〜出目6まであり、残り1つのサイコロの数値で決定する。たとえば、2、2、3と出た場合は出目3 |
アラシ | 2 | 2 2 2 | ピンゾロ・ゴゾロ以外の場合で、3つのサイコロの目がすべて同じだった場合 |
ゴゾロ | 5 | 5 5 5 | すべてのサイコロの目が5の場合 |
ピンゾロ | 5 | 1 1 1 | すべてのサイコロの目が1の場合 |
シゴロ | 3 | 5 4 6 | サイコロの目が4、5、6の場合。(数字の順番はどうでも良い) |
■表1:役一覧
具体的な説明に入る前にプログラムの構造を解説します。
■図1:プログラムの流れ
このプログラムはユーザーが「ちんちろりん」ボタンをクリックすると開始します。このClickイベントではChinchirorinメソッドが呼び出されます。Chinchirorinメソッドを呼び出すと、サイコロの目がランダムに変化して、3つのサイコロの目を元に「役」を知ることができます。
これをプレイヤーとコンピュータが1回ずつ行った後、Judgeメソッドを呼び出して勝敗を判定します。
以上のことからわかるようにChinchirorinメソッドがこのプログラムの中で重要な位置を占めていますが、他にもいくつかのメソッドを作ることになります。登場するすべての自作メソッドを表にまとめておきます。
メソッド名 | 機能 |
Chinchirorin | サイコロの目をランダムに変化させて、出た「役」を返す。 |
GetYaku | 3つのサイコロ目から「役」を判断して返す。 |
GetYakuName | 「役」の名前を取得する。 |
GetYakuPoint | 「役」の倍数(得点)を取得する。 |
Judge | 勝敗を判定して、賭け金の移動を行う。 |
■表2:作成するメソッドの一覧
それでは早速プログラムにかかります。
まず、新規プロジェクトを作成してください。名前はChinchirorinにしましょう。VB2005 Express Editionを使用している場合はプロジェクトを作成したらすぐに保存してください。保存しないと自動的に割り当てられる一時的なフォルダが使用されてしまうため具合が悪いのです。
次にこのアプリケーションで使用するサイコロの画像を以下からダウンロードしてください。 なお、既に完成版をダウンロードしている場合は別途に画像をダウンロードする必要はありません。
サイコロの画像 7.67KB lha形式(拡張子lzh)
ダウンロードしたら、これを解凍して、中にある6個の画像ファイルを「image」という名前のフォルダを作ってコピーします。コピーする場所はVBのバージョンのよって少し異なります。
VB2005の場合は、プロジェ靴のフォルダの中にあるbinフォルダ下のDebugフォルダとReleaseフォルダの両方にimageフォルダを作成してください。両方のimageフォルダは全く同じ内容になります。
■画像2:フォルダの構成(VB2005の場合)
VB.NET2002、VB.NET2003の場合はプロジェクトのフォルダの中にあるbinフォルダにimageフォルダを配置します。
■画像3:フォルダ構成(VB.NET2002, VB.NET2003の場合)
次に画面から作ります。下の画像のようにコントロールを配置してください。
■画像4:コントロールの配置と名称
各コントロールには以下の表のようにプロパティを設定してください。
表にないコントロールに関しては画像を見ながら適当に配置してください。たとえば、「役」とか「あなた」とか「コンピュータ」とか書いたラベルを似たような位置に似たような色で貼り付ければOKです。
コントロール | 機能 | プロパティ | 値 |
Panael1 (Panel) |
見た目のためだけにあります。機能はありません。 | BackColor | 0, 192, 0 (緑) |
BorderStyle | Fixed3D | ||
lblPlayerMoney (Label) |
プレイヤーの持ち金を表示します。 | TextAlign | MiddleRight |
lblPlayerYaku (Label) |
プレイヤーの出した役を表示します。 | ||
lblComputerMoney (Label) |
コンピューターの持ち金を表示します。 | TextAlign | MiddleRight |
lblComputerYaku (Label) |
コンピューターの役を表示します。 | ||
picSai1 (PictureBox) |
1つ目のサイコロを表示します。 | ||
picSai2 (PictureBox) |
2つ目のサイコロを表示します。 | ||
picSai3 (PictureBox) |
3つ目のサイコロを表示します。 | ||
lblYakuName (Label) |
3つのサイコロの示す役を表示します。 | TextAlign | MiddleCenter |
lblMessage (Label) |
ゲームの進行メッセージを表示します。 | TextAlign | MiddleCenter |
txtBet (TextBox) |
賭け金を入力します。 | TextAlign | Right |
btnPlay (Button) |
ちんちろりんを開始します。 | ||
Timer1 (Timer) |
コンピュータの番を制御します。 | Interval | 1000 |
■表3:コントロール
表を見ると面倒くさくなる方もいると思いますが、言われた通りに配置するだけでも結構勉強になります。
配置の際の注意点をいくつか挙げておきます。
まず、Panel1を最初に配置して、picSai1, picSai2, picSai3, lblYakuNameはその上に配置するようにすると作業が楽です。これは必須ではありません。また、ラベル、テキストボックスのフォントはすべてMS ゴシックで、サイズは16です。
Timerを配置すると、フォームの上ではなく、少し下の部分の拡張領域に表示されます。はじめてTimerを使う方はびっくりするかもしれませんがこれで正常です。表3にもありますが、Intervalプロパティを1000にするのを忘れないで下さい。
では、サイコロを振るところからプログラムします。「サイコロを振る」と言っても今回作るプログラムにはアニメーションはありません。単純に3つのサイコロの目が表示されるだけです。表示される目はもちろんランダムです。
はじめに画像があるフォルダのパスを取得しておきます。これは次のようになります。
Dim BasePath As String '画像のあるフォルダのフルパス(末尾に \ はつけないこと) |
Private
Sub Form1_Load(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles MyBase.Load
BasePath = Application.StartupPath & "\image" End Sub |
■リスト1:初期設定
これで変数BasePathを見ればいつでも画像があるフォルダのパスがわかります。FormのLoadイベントはこのように初期処理をするためによく使われます。今回は画像フォルダの取得の他にプレイヤーのコンピュータの始めの持ち金10000を表示するように指示しています。
3つのサイコロにランダムな目を表示するChinchirorinメソッドとその呼び出し部分は次のようになります。実際に打ち込んで動かしてみてください。
Private
Sub btnPlay_Click(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles btnPlay.Click '▼サイコロをふる Chinchirorin() 'サイコロをふる End Sub |
Private
Sub Chinchirorin()
Dim Rnd
As New Random picSai1.Image =
Image.FromFile(File1) End Sub |
■リスト2:サイコロをふる
ぱっと見ていただければわかるように処理は単純です。1〜6のランダムな数を取得するためにRandomクラスのNextメソッドを利用しています。画像ファイルの名前はそのままSaikoro1.bmp 〜 Saikoro6.bmpとなっているので、出た数を元にファイルを取得してImageクラスのFromFileメソッドでピクチャーボックスに表示します。
これらの部分はクラスのメソッドを知識さえあれば全然難しくありません。メソッドの知識がない方も今覚えていただければよいだけです。VBの構文としてはしごく簡単なものです。
なんか、サイコロの画像が表示できるようになると、もうほとんどプログラムが完成したような気分になってしまいますね。
では、3つのサイコロも目から役の名前を求めて表示するようにしましょう。今回作成するちんちろりんには目なし(役なし)も含めて12個の役があります。
プログラムではこれらの役を数字で管理することにします。たとえば、1は「目なし」、8は「アラシ」、11は「シゴロ」といった感じです。
しかし、プログラムの中で突然1とか8とか11とかが出てくると、どの役のことだか見た目で分かりにくくなります。プログラムがわかりにくくなっても完成するゲームには変わりはないのですが、後々プログラムを改造したり、他の人にプログラムをあげたりする場合もあるわけですからプログラムがわかりやすいに越したことはありません。
こういう場合、定数を使ってわかりにくさを解決します。定数を使うとたとえば次のように役を定義することができます。
'以下の部分は「例」です。今回は実際には使用しません。
Private
Const Menashi As
Integer = 1
Private Const Arashi As Integer = 8 Private Const Sigoro As Integer = 11 |
■リスト3:「例」として、定数で役を定義する方法
これで、プログラムの中に直接1とか8とか11とか書く代わりに、Menashi、Arashi、Sigoroなどと記述できるようになり、プログラムが分かりやすくなります。
ところで、今回は定数よりも一歩進んでさらにわかりやすい「列挙体」(れっきょたい)というものを採用します。
「列挙体」は初級講座では初登場です。列挙体は関係のある値をまとめる役割があります。定数はそれぞれが互いに関係なく存在していますが、列挙体はそれぞれを意味のあるまとまりとして扱うことができます。今回の例で行くと「役」というまとまりを扱えるようになるわけです。このことでプログラムがどういう風に楽になるかは実際に打ち込んで試してみてください。列挙体を作るのが楽しくなってきますから。
役を表す列挙体の宣言は次のようになります。列挙体の名前はChinchirorinYakuとしておきました。どこでもいいのですがとりあえずフォームのプログラムの先頭の方に書いてください。VB.NET2003以前なら「Windows フォームデザイナで生成されたコード」とある部分のすぐ下あたりに書くのが普通です。
Private
Enum ChinchirorinYaku Hifumi = -1 Menashi = 1 Deme1 = 2 Deme2 = 3 Deme3 = 4 Deme4 = 5 Deme5 = 6 Deme6 = 7 Arashi = 8 Arashi5 = 9 Arashi1 = 10 Sigoro = 11 End Enum |
■リスト4:列挙体で役を定義する
列挙体はVBには随所に見られます。たとえば、TextAlignプロパティはHorizontalAlignmentという列挙体を指定することになっています。この列挙体ではCenter、Left、Rightが定義されています。
次に、役の名前を取得する関数GetYakuNameを記述します。これは簡単です。次のようになります。
Private
Function GetYakuName(ByVal
Yaku As ChinchirorinYaku)
As String Select Case Yaku Case ChinchirorinYaku.Deme1 Return "出目1" Case ChinchirorinYaku.Deme2 Return "出目2" Case ChinchirorinYaku.Deme3 Return "出目3" Case ChinchirorinYaku.Deme4 Return "出目4" Case ChinchirorinYaku.Deme5 Return "出目5" Case ChinchirorinYaku.Deme6 Return "出目6" Case ChinchirorinYaku.Arashi1 Return "ピンゾロ" Case ChinchirorinYaku.Arashi5 Return "ゴゾロ" Case ChinchirorinYaku.Arashi Return "アラシ" Case ChinchirorinYaku.Sigoro Return "シゴロ" Case ChinchirorinYaku.Hifumi Return "ヒフミ" Case ChinchirorinYaku.Menashi Return "目なし" End Select End Function |
■リスト5:役の名前を返す
この関数の引数がさきほど定義した列挙体ChinchirorinYaku型になっている点に注意してください。このように列挙体は型のように使えるのです。また、Select CaseのCase句でも列挙体を利用しています。
役の定義ができたところで、いよいよサイコロをふって出た役を表示するようにしましょう。
ちんちろりんのルールを知らない方は具体的にどのような「役」があるのか、表1を参照しながら説明を読んでください。
まず、3つの数字から役を返す関数GetYakuを作ります。この関数は3つの数字を引数にとり、「役」を返します。戻り値は何型になるか想像できますか? 「役」を表す型ですから、当然ChinchirorinYaku型、つまりあの列挙体です。
■画像5:GetYaku関数の模式図
関数を作るときのこつは上記のような模式図を頭の中に思い浮かべ、関数の中と外を明確に区別することです。
関数の外側にあっては関数は完全にブラックボックスです。中がどうなっているかは不明だけどとにかく3つの数字を渡すと「役」を返してくれるというものです。
関数の内側にあっては外の世界は一切見えないものと考えます。渡されてきた3つの数字をもとにどのように「役」を返すのかだけに専念します。
GetYaku関数をお見せする前に少しプログラムのことを考えて見ましょう。どうやって役を判断すればよいでしょうか?
一番簡単なのが「ピンゾロ」と「ゴゾロ」です。たとえば、「ピンゾロ」は3つの数字がすべて1のときの役ですから次のように書くことができます。
Private
Function
GetYaku(ByVal
Number1 As Integer,
ByVal Number2
As
Integer,
ByVal Number3
As
Integer)
As ChinchirorinYaku '以下の部分は「例」です。今回は実際には使用しません。 If Number1 =
1 And Number2 =
1 And Number3 =
1 Then |
■リスト6:「例」として、役「ピンゾロ」を判定する方法
さぁ、他の役も自力で判断してGetYaku関数を完成させると言うのはどうですか?もし、自力で挑戦するのなら下の完成版を見るのは少し後にし下さい。
完成版のGetYaku関数は次のようになります。
Private
Function
GetYaku(ByVal
Number1 As Integer,
ByVal Number2
As
Integer,
ByVal Number3
As
Integer)
As ChinchirorinYaku Dim Deme As Integer '▼アラシ(ゾロ目)の判断 If Number1 = Number2 AndAlso Number1 = Number3 Then If Number1 = 1 Then'ピンゾロ(1のゾロ目)、ゴゾロ(5のゾロ目) Return ChinchirorinYaku.Arashi1 ElseIf Number1 = 5 Then Return ChinchirorinYaku.Arashi5 Else 'その他のゾロ目 Return ChinchirorinYaku.Arashi End If End If '▼出目の判断
'注:「出目」とは同じ数字が2つある場合に残りの数字のことを言う。 If Number1 =
Number2 Then Case 1 Return ChinchirorinYaku.Deme1 Case 2 Return ChinchirorinYaku.Deme2 Case 3 Return ChinchirorinYaku.Deme3 Case 4 Return ChinchirorinYaku.Deme4 Case 5 Return ChinchirorinYaku.Deme5 Case 6 Return ChinchirorinYaku.Deme6 End Select '▼ヒフミとシゴロの判断 'この時点では、3つの数字はばらばらであることがわかっていることに留意 If Number1 +
Number2 + Number3 = 6 Then If Number1 +
Number2 + Number3 = 15 Then '▼やくなし Return ChinchirorinYaku.Menashi End Function |
■リスト7:役の判定
ここまでできれば、実際に役を表示させるのは簡単です。最初に書いたボタンのClickイベントとChinchirorinメソッドを改造して次のようになります。Chinchirorinメソッドでは追加したり変更されたりしたところに色をつけておきました。
Dim PlayerYaku As ChinchirorinYaku 'プレイヤーの出した役 |
Private Sub
btnPlay_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
btnPlay.Click '▼賭け金のチェック If Not IsNumeric(txtBet.Text) OrElse CInt(txtBet.Text) = 0 ThenMsgBox("賭け金を入力してください。", MsgBoxStyle.Information) Exit Sub End If '▼表示の初期化 lblPlayerYaku.Text = "" '▼サイコロをふる PlayerYaku = Chinchirorin()
'サイコロをふる End Sub |
Private
Function
Chinchirorin()
As
ChinchirorinYaku Dim
Rnd As
New Random picSai1.Image = Image.FromFile(File1)
Yaku = GetYaku(Saikoro1, Saikoro2, Saikoro3) Return Yaku End Function |
■リスト8:サイコロをふって出た役の名前を表示する
実はこれでプログラムの大半は完成です。後は「コンピュータの番」を作って、プレイヤーの役とコンピュータの役のどちらが強いか判定して、賭け金を移動するだけですね。
ここまでの部分を試しに動かして、ついでにちんちろりんの役を覚えると言うのもいいでしょう。
プレイヤーがサイコロを振ったら、次はコンピュータが振ります。コンピューターの番は自動的に行われます。自動的にゲームが進行するようにタイマーを使います。
タイマーはプレイヤーがサイコロをふったすぐ後に作動させます。btnPalyのClickイベントに次の色が付いている部分のコードを追加してください。
Private
Sub btnPlay_Click(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles btnPlay.Click '▼賭け金のチェック If
Not IsNumeric(txtBet.Text)
OrElse CInt(txtBet.Text)
= 0 Then '▼表示の初期化 lblPlayerYaku.Text = "" '▼サイコロをふる PlayerYaku = Chinchirorin()
'サイコロをふる '▼コンピュータの番へ
btnPlay.Enabled =
False |
■リスト9:タイマーをセットしてコンピュータの番へ移行する
タイマーはあらかじめプロパティウィンドウで表3のようにIntervalプロパティを1000に設定しあるものとします。Intervalが1000ということは1秒ごとにTickイベントが発生すると言うことですから、上記のコードの最後のTimer1.Enabled = Trueから1秒後にTickイベントが発生します。
このTickイベントは、次の通りです。
Dim ComputerYaku As ChinchirorinYaku 'コンピュータの出した役 |
Private
Sub Timer1_Tick(ByVal
sender As System.Object,
ByVal e As System.EventArgs)
Handles Timer1.Tick Timer1.Enabled = False '▼サイコロをふる ComputerYaku = Chinchirorin() '▼勝敗判定 '勝敗判定に伴う表示や金額の足し引きなどはすべてJudgeメソッド内で行う。 Call Judge() btnPlay.Enabled = True End Sub |
Private
Sub Judge() End Sub |
■リスト10:コンピュータの番
プレイヤーとコンピュータの勝敗判定と賭け金の移動を行うJudgeメソッドはこの後で説明します。ここでは空のJudgeメソッドだけ載せておきました。
Tickイベントのコードは見れば分かると思います。最初の行でTimer1.Enabled = Falseとしていますが、これはTickイベントが何回も発生するのを防ぐためです。放っておくとTickイベントは繰り返し繰り返し何度でも自動的に発生するのです。
最後に残ったプレイヤーとコンピュータの勝ち負けを判断するJudgeメソッドを説明します。
ちんちろりんでは役ごとに倍率が決まっています。役と倍率は表1の通りです。たとえば、出目6で買っても賭け金の1倍、つまり賭け金分の金額がもらえるだけですが、ピンゾロで勝つと賭け金の5倍の金額を得ることができます。逆にヒフミは賭け金の3倍の金額を払うことになります。
プログラムではまずこの役ごとの倍率を取得する関数を作っておきます。
次のようになります。
Private
Function GetYakuPoint(ByVal
Yaku As ChinchirorinYaku)
As Integer
Select
Case Yaku |
■リスト11:役の倍数を取得する
これは単なる1つのSelect Case文です。
これで準備が整ったのでいよいよJudgeメソッドを記述します。次の通りです。
Private
Sub Judge()
Dim PlayerMoney
As Integer =
CInt(lblPlayerMoney.Text)
'プレイヤーの現在の金額 If PlayerYaku > ComputerYaku Then '●プレイヤーが勝った場合 '▼倍率の取得
If ComputerYaku < 0
Then
PlayerMoney += Bet * Point
'プレイヤーの獲得金額 ElseIf PlayerYaku < ComputerYaku Then '●コンピュータが勝った場合'※コードの説明は、すぐ上の「プレイヤーが勝った場合」の説明を参照のこと If PlayerYaku < 0 ThenPoint = GetYakuPoint(PlayerYaku) Else Point = GetYakuPoint(ComputerYaku) End If
PlayerMoney -= Bet * Point Else '●ワカレ(引き分け)の場合
lblMessage.Text = "ワカレ(引き分け)です。" End If lblPlayerMoney.Text = PlayerMoney End Sub |
■リスト12:勝敗判定と賭け金の移動
コードは長いですが、プログラムは単純です。ヒフミのときだけ他の役と違って、役を出した方がお金を払うので処理が分かれていますがその他は素直に読めば分かると思います。
以上で完成しました。今回は書いてある順番にプログラムをコピー貼り付けしていくと完成するので少し張り合いがなかったかもしれませんが、この作業を物足りないと感じていると言うことはVBにかなり馴れてきたと言うことです。
正直言って、この「ちんちろりん」ゲームは面白いゲームではありません。ここから先はみなさんのアイディアを盛り込んでゲームを楽しいものに作り変えるように挑戦してみてください。ほとんど同じ構造でポーカーゲームも作れそうですね。
それから、このプログラムはいつまでたってもゲームオーバーになりません。持ち金がマイナスになっても続きます。また、持ち金が処理しきれない金額になるとエラーが発生します。これらの点も腕試しに修正しておいてください。ここまで付き合っていただいたみなさんには簡単なことでしょう。
それでは、長い説明にお付き合いいただいてありがとうございました!質問や感想などは掲示板にお願いします。