手順 3: 各ラベルへのランダムなアイコンの割り当て
ゲームで毎回、同じアイコンが同じセルに表示されていたのでは、やりがいがありません。これを避けるには、AssignIconsToSquares() メソッドを使用して、フォームのラベル コントロールにアイコンをランダムに割り当てます。
各ラベルにランダムなアイコンを割り当てるには
次のコードを追加する前に、メソッドのしくみについて検討します。新しいキーワード foreach (Visual C# の場合) および For Each (Visual Basic の場合) があります (1 つの行は意図的にコメント アウトされています。これについてはこの手順の最後に説明します)。
''' <summary> ''' Assign each icon from the list of icons to a random square ''' </summary> ''' <remarks></remarks> Private Sub AssignIconsToSquares() ' The TableLayoutPanel has 16 labels, ' and the icon list has 16 icons, ' so an icon is pulled at random from the list ' and added to each label For Each control In TableLayoutPanel1.Controls Dim iconLabel = TryCast(control, Label) If iconLabel IsNot Nothing Then Dim randomNumber = random.Next(icons.Count) iconLabel.Text = icons(randomNumber) ' iconLabel.ForeColor = iconLabel.BackColor icons.RemoveAt(randomNumber) End If Next End Sub
/// <summary> /// Assign each icon from the list of icons to a random square /// </summary> private void AssignIconsToSquares() { // The TableLayoutPanel has 16 labels, // and the icon list has 16 icons, // so an icon is pulled at random from the list // and added to each label foreach (Control control in tableLayoutPanel1.Controls) { Label iconLabel = control as Label; if (iconLabel != null) { int randomNumber = random.Next(icons.Count); iconLabel.Text = icons[randomNumber]; // iconLabel.ForeColor = iconLabel.BackColor; icons.RemoveAt(randomNumber); } } }
前の手順で示されているように、AssignIconsToSquares() メソッドを追加します。このメソッドを、「手順 2: Random オブジェクトおよびアイコンのリストの追加」で追加したコードのすぐ下に配置できます。
前に説明したように、AssignIconsToSquares() メソッドに新しいものが含まれています。つまり、foreach ループ (Visual C# の場合) および For Each (Visual Basic の場合) です。For Each ループは、同じ処理を繰り返し実行する必要がある場合にいつでも使用できます。ここでは、次のコードで説明されているように、TableLayoutPanel のラベルごとに同じステートメントを実行する必要があります。最初の行では、control という名前の変数を作成し、その変数に一度に 1 つずつコントロールを格納して、そのコントロールに対してループ内のステートメントを実行します。
For Each control In TableLayoutPanel1.Controls ' The statements you want to execute ' for each label go here ' The statements use iconLabel to access ' each label's properties and methods Next
foreach (Control control in tableLayoutPanel1.Controls) { // The statements you want to execute // for each label go here // The statements use iconLabel to access // each label's properties and methods }
[!メモ]
"iconLabel" および "control" という名前が使用されているのは、わかりやすくするためです。これらの名前を任意の名前に置き換えても、コードはまったく同じように動作します (ただしループ内の各ステートメントで名前を変更する必要はあります)。
AssignIconsToSquares() メソッドは、TableLayoutPanel の各ラベル コントロールを反復処理し、それぞれに対し同じステートメントを実行します。これらのステートメントは、「手順 2: Random オブジェクトおよびアイコンのリストの追加」で追加したリストからランダムなアイコンを取得します (リストに各アイコンを 2 つずつ含め、ランダムなラベル コントロールにアイコンのペアが割り当てられるようにしたのはこのためです)。
foreach または For Each ループ内で実行されるコードを詳しく見てみましょう。次に示しているのは前に示したコードの一部です。
Dim iconLabel = TryCast(control, Label) If iconLabel IsNot Nothing Then Dim randomNumber = random.Next(icons.Count) iconLabel.Text = icons(randomNumber) ' iconLabel.ForeColor = iconLabel.BackColor icons.RemoveAt(randomNumber) End If
Label iconLabel = control as Label; if (iconLabel != null) { int randomNumber = random.Next(icons.Count); iconLabel.Text = icons[randomNumber]; // iconLabel.ForeColor = iconLabel.BackColor; icons.RemoveAt(randomNumber); }
最初の行では、control 変数を iconLabel という名前のラベルに変換しています。その次の行は、変換が成功したかどうかを確認する if ステートメントです。変換が成功した場合は、if ステートメント内のステートメントが実行されます (前のチュートリアルでも説明したように、if ステートメントは、指定した任意の条件を評価するために使用されます)。if ステートメントの最初の行では、randomNumber という名前の変数を作成し、icons リスト内の項目のいずれかに対応する乱数をこの変数に格納します。そのために、前に作成した Random オブジェクトの Next メソッドを使用します。Next メソッドは乱数を返します。またこの行では、icons リストの Count プロパティを使用して、乱数を選択する範囲を決定しています。次の行では、icons リストのいずれかの項目をラベルの Text プロパティに割り当てています。コメントアウトしている行は、このトピックの後半で説明します。最後に、if ステートメントの最終の行で、フォームに追加したアイコンをリストから削除しています。
コード内にわからない部分があれば、コード要素の上にマウス ポインターを合わせると、関連するヒントが表示されます。Visual Studio デバッガーを使用して、プログラムの実行中にコードの各行をステップ実行することもできます。詳細については、「How Do I: Step with The Debugger in Visual Studio? (操作方法: Visual Studio のデバッガーでステップ実行する)」または「Visual Studio Debugger の開始、中断、ナビゲート、および停止」を参照してください。
ゲーム ボードをアイコンで埋めるには、プログラムが起動したらすぐに AssignIconsToSquares() メソッドを呼び出す必要があります。Visual C# を使用している場合は、Form1 コンストラクターの InitializeComponent() メソッドの呼び出しのすぐ下にステートメントを追加し、フォームが新しいメソッドを呼び出してフォーム自体の設定後に表示されるようにします。新しいオブジェクト (クラスや構造体など) を作成するときは、コンストラクターを呼び出します。詳細については、「Constructors (C# Programming Guide) (コンストラクター (C# プログラミング ガイド))」または「コンストラクターとデストラクターの使用方法」 (Visual Basic の場合) を参照してください。
public Form1() { InitializeComponent(); AssignIconsToSquares(); }
Visual Basic の場合は、AssignIconsToSquares() メソッドの呼び出しを Form1_Load メソッドに追加します。コードは次のようになります。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load AssignIconsToSquares() End Sub
プログラムを保存し、実行します。各ラベルに割り当てられたランダムなアイコンを備えたフォームが表示されます。
いったんプログラムを終了して、再び実行します。次の図に示すように、各ラベルに別のアイコンが割り当てられています。
ランダムなアイコンが表示された絵合わせゲーム
アイコンは、まだ非表示に設定されていないため、表示されています。アイコンをプレーヤーに非表示にするには、各ラベルの Forecolor プロパティをその BackColor プロパティと同じ色に設定できます。
ヒント ラベルのようなコントロールを非表示にする別の方法は、Visible プロパティを False に設定することです。
アイコンを非表示にするには、プログラムを停止し、For Each ループ内のコードのコメント行からコメント記号を削除します。
iconLabel.ForeColor = iconLabel.BackColor
iconLabel.ForeColor = iconLabel.BackColor;
メニュー バーで、[すべて保存] をクリックし、プログラムを保存したうえで実行します。アイコンが非表示になったように見えます。青い背景のみが表示されます。ただし、アイコンはランダムに割り当てられて、そこに存在しています。アイコンは、背景と同じ色であるため、プレーヤーには見えなくなっています。これで、ゲームはやりがいのあるものになりました。プレーヤーはすべてのアイコンをすぐに見ることができなくなったためです。
続行または確認するには
チュートリアルの次の手順に進むには、「手順 4: 各ラベルへの Click イベント ハンドラーの追加」を参照してください。
チュートリアルの前の手順に戻るには、「手順 2: Random オブジェクトおよびアイコンのリストの追加」を参照してください。