]]] 15パズル・ゲーム [[[ | プログラミング実習(VB) |
Microsoft Visual Basic 2010 Express Edition |
8パズル・ゲームを15パズルに作り変える。
基本的には、8パズルのプログラムにボタンを7個追加すればよいのだが、もう少し効率のよい方法がある。デザイン画面でボタンを配置するのではなく、プログラムでボタンを配置するのである。プログラムなので、繰り返しでいくつでも配置することができる。もちろん、これらのオブジェクトも配列で管理する。
このように、プログラムでオブジェクトを配置する方法を「コントロールの動的配置」という。
フォーム
Text = 8パズル・ゲーム
Font.Size = 11
ボタン 1個
(Name) = btnKaishi
Text = 開始
ラベル 1個
(Name) = lblKaisuu
今回、オブジェクトの配置はプログラム起動後、一度だけでよいから、動的配置のプログラムはForm1_Loadメソッドに作成する。
(1) メンバ変数の宣言(変更)
ボタンが16個に増えるので配列の個数を変更する。
Public Class Form1
'複数のボタンを配列で管理する。
Dim btnTile(916) As Button '1〜916のボタン用の配列
Dim Kaisuu As Integer '移動回数カウント用
Dim InitX(916), InitY(916) As Integer 'ボタンの初期座標(答え合わせ用)
(2) Form1_Loadメソッドの変更
今回の最大のポイントである。8パズルのプログラムを変更する場合は、Form1_Loadメソッドのプログラムだけ削除して、新たに作成する。
「コントロールの動的配置」のプログラム手順は次のとおりである。
@ オブジェクトを作成する。
A オブジェクトをコントロールコレクションに追加する。
B オブジェクトのプロパティを設定する。
C オブジェクトのイベントハンドラを設定する。
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles MyBase.Load
Dim n As Integer
'16個のボタンをここで作成する。
For n = 1 To 16
btnTile(n) = New Button '@Buttonオブジェクト作成
Me.Controls.Add(btnTile(n)) 'A作成したオブジェクトを追加
With btnTile(n) 'Bプロパティの設定
.Width = 240 / 4
.Height = 240 / 4
.Left = 12 + .Width * Int((n - 1) Mod 4)
.Top = 12 + .Height * Int((n - 1) / 4)
.Visible = True
.Text = n.ToString
.ForeColor = Color.Blue
.Font = New Font("MS ゴシック", 12, FontStyle.Bold)
End With
'ボタン初期座標の格納
InitX(n) = btnTile(n).Left
InitY(n) = btnTile(n).Top
'Cイベントハンドラの登録
AddHandler btnTile(n).Click, AddressOf btnTile_Click
Next
btnTile(16).Visible = False '最後のボタンだけ非表示
End Sub
(3) With 〜 End With
たくさんのプロパティを設定するときは、このプログラムのようにWith 〜 End Withを使って設定すると便利である。次のプログラムは、左側も右側も同じである。
With btnTile(n) 'Bプロパティの設定
.Width = 240 / 4
.Height = 240 / 4
.Left = 12 + .Width * Int((n - 1) Mod 4)
.Top = 12 + .Height * Int((n - 1) / 4)
.Visible = True
.Text = n.ToString
.ForeColor = Color.Blue
.Font = New Font("MS ゴシック", 12, FontStyle.Bold)
End With
btnTile(n).Width = 240 / 4
btnTile(n).Height = 240 / 4
btnTile(n).Left = 12 + .Width * Int((n - 1) Mod 4)
btnTile(n).Top = 12 + .Height * Int((n - 1) / 4)
btnTile(n).Visible = True
btnTile(n).Text = n.ToString
btnTile(n).ForeColor = Color.Blue
btnTile(n).Font = New Font("MS ゴシック", 12, FontStyle.Bold)
8パズルのプログラムを変更する場合は、残りの4つのメソッド、btnTile_Click、IsMoveTile、btnKaishi_Click、IsGameClearのボタンの個数が9個から16個に変わったので、それに対応して変更していくだけである。
Private Sub btnTile_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim n As Integer
For n = 1 To 15
If sender.Equals(btnTile(n)) = True Then
'MessageBox.Show(n.ToString & "番のボタン")
If IsMoveTile(n) = True Then '移動の可否を調べる
Kaisuu = Kaisuu + 1 '移動回数カウント
lblKaisuu.Text = "移動回数:" & Kaisuu.ToString &
"回"
End If
End If
Next
'クリアの判定
If IsGameClear() = True Then
MessageBox.Show(Kaisuu.ToString & "回で完成しました。", "15パズル")
End If
End Sub
Private Function IsMoveTile(ByVal TileNum As Integer) As Boolean
'TileNum番のタイルが移動可能かどうかを調べ、可能であれば
'移動する。そして、Trueを返却する。
'移動できなければ、Falseを返却する。
'移動の可否は、TileNum番の上下左右のどこかに16番のタイルが
'あるかどうかで決める。あれば、移動可能ということになる。
Dim work As Integer 'データ入れ替え用
'TileNum番の上
If btnTile(TileNum).Top - btnTile(1).Height = btnTile(16).Top _
And btnTile(TileNum).Left = btnTile(16).Left Then
work = btnTile(TileNum).Top 'タイル16番と入れ替え
btnTile(TileNum).Top = btnTile(16).Top
btnTile(16).Top = work
'TileNum番の下
ElseIf btnTile(TileNum).Top + btnTile(1).Height = btnTile(16).Top _
And btnTile(TileNum).Left = btnTile(16).Left Then
work = btnTile(TileNum).Top 'タイル16番と入れ替え
btnTile(TileNum).Top = btnTile(16).Top
btnTile(16).Top = work
'TileNum番の左
ElseIf btnTile(TileNum).Top = btnTile(16).Top _
And btnTile(TileNum).Left - btnTile(1).Width = btnTile(16).Left Then
work = btnTile(TileNum).Left 'タイル16番と入れ替え
btnTile(TileNum).Left = btnTile(16).Left
btnTile(16).Left = work
'TileNum番の右
ElseIf btnTile(TileNum).Top = btnTile(16).Top _
And btnTile(TileNum).Left + btnTile(1).Width = btnTile(16).Left Then
work = btnTile(TileNum).Left 'タイル16番と入れ替え
btnTile(TileNum).Left = btnTile(16).Left
btnTile(16).Left = work
Else '移動不可
Return False
End If
Return True '移動可能、移動済み
End Function
Private Sub btnKaishi_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnKaishi.Click
Dim Ransuu As New System.Random '乱数オブジェクトの作成
Dim mae As Integer = 0 '前に移動したタイル番号
Dim rd As Integer '乱数データ(整数1-8)
Dim n As Integer
For n = 0 To 30 '移動回数 30回 ←50回程度に増やすと良い。
Do '永久ループ
rd = Ransuu.Next(1, 16) '乱数(移動するタイル番号)の生成
If mae <> rd Then '前の番号と違う
If IsMoveTile(rd) = True Then '移動できた
mae = rd '移動したタイル番号を記憶しておく
Exit Do '永久ループ脱出
End If
End If
Loop
Next
Kaisuu = 0 '移動回数の初期化
lblKaisuu.Text = "移動回数:" & Kaisuu.ToString & "回"
End Sub
Private Function IsGameClear() As Boolean
Dim n As Integer
For n = 1 To 16
If btnTile(n).Left <> InitX(n) Or btnTile(n).Top <> InitY(n)
Then
'未完成
Return False
End If
Next
'完成(クリア)
Return True
End Function
Microsoft Visual Basic 2010 Express Edition | |
]]] 15パズル・ゲーム [[[ | Copyright©2014 Hiroshi Masuda |