]]] 15パズル・ゲーム [[[ プログラミング実習(VB)  
Microsoft Visual Basic 2010 Express Edition

15パズル・ゲーム

 8パズル・ゲームを15パズルに作り変える。
 基本的には、8パズルのプログラムにボタンを7個追加すればよいのだが、もう少し効率のよい方法がある。デザイン画面でボタンを配置するのではなく、プログラムでボタンを配置するのである。プログラムなので、繰り返しでいくつでも配置することができる。もちろん、これらのオブジェクトも配列で管理する。
 このように、プログラムでオブジェクトを配置する方法を「コントロールの動的配置」という。

 

1 デザイン

15パズル・ゲームのデザイン
フォーム
 Text = 8パズル・ゲーム
 Font.Size = 11
 
ボタン 1個
 (Name) = btnKaishi
 Text = 開始
 
ラベル 1個
 (Name) = lblKaisuu

 

2 コントロールの動的配置

 今回、オブジェクトの配置はプログラム起動後、一度だけでよいから、動的配置のプログラムは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)

 

3 そのほかの変更

 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 

 

 

 

 

 

inserted by FC2 system