手順 3: 各ラベルへのランダムなアイコンの割り当て

ゲームで毎回、同じアイコンが同じセルに表示されていたのでは、やりがいがありません。 これを避けるには、AssignIconsToSquares() メソッドを使用して、フォームのラベル コントロールにアイコンをランダムに割り当てます。

各ラベルにランダムなアイコンを割り当てるには

  1. 次のコードを追加する前に、メソッドのしくみについて検討します。 新しいキーワード foreach (Visual C# の場合) および For Each (Visual Basic の場合) があります (1 つの行は意図的にコメント アウトされています。これについてはこの手順の最後に説明します)。

    /// <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);
            }
        }
    } 
    
    ''' <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
    
  2. 前の手順で示されているように、AssignIconsToSquares() メソッドを追加します。 このメソッドを、「手順 2: Random オブジェクトおよびアイコンのリストの追加」で追加したコードのすぐ下に配置できます。

    前に説明したように、AssignIconsToSquares() メソッドに新しいものが含まれています。つまり、foreach ループ (Visual C# の場合) および For Each (Visual Basic の場合) です。 For Each ループは、同じ処理を繰り返し実行する必要がある場合にいつでも使用できます。 ここでは、次のコードで説明されているように、TableLayoutPanel のラベルごとに同じステートメントを実行する必要があります。 最初の行では、control という名前の変数を作成し、その変数に一度に 1 つずつコントロールを格納して、そのコントロールに対してループ内のステートメントを実行します。

    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
    }
    
    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
    
    注意

    "iconLabel" および "control" という名前が使用されているのは、わかりやすくするためです。 これらの名前を任意の名前に置き換えても、コードはまったく同じように動作します (ただしループ内の各ステートメントで名前を変更する必要はあります)。

    AssignIconsToSquares() メソッドは、TableLayoutPanel の各ラベル コントロールを反復処理し、それぞれに対し同じステートメントを実行します。 これらのステートメントは、「手順 2: Random オブジェクトおよびアイコンのリストの追加」からランダムなアイコンを取得します。 (リストに各アイコンを 2 つずつ含め、ランダムなラベル コントロールにアイコンのペアが割り当てられるようにしたのはこのためです)。

    foreach または For Each ループ内で実行されるコードを詳しく見てみましょう。 次に示しているのは前に示したコードの一部です。

    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);
    }
    
    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
    

    最初の行では、control 変数を iconLabel という名前のラベルに変換しています。 その次の行は、変換が成功したかどうかを確認する if ステートメントです。 変換が成功した場合は、if ステートメント内のステートメントが実行されます (前のチュートリアルでも説明したように、if ステートメントは、指定した任意の条件を評価するために使用されます)。if ステートメントの最初の行では、randomNumber という名前の変数を作成し、icons リスト内の項目のいずれかに対応する乱数をこの変数に格納します。 そのために、前に作成した Next オブジェクトの Random メソッドを使用します。 Next メソッドは乱数を返します。 またこの行では、Count リストの icons プロパティを使用して、乱数を選択する範囲を決定しています。 次の行では、icons リストのいずれかの項目をラベルの Text プロパティに割り当てています。 コメントアウトしている行は、このトピックの後半で説明します。 最後に、if ステートメントの最終の行で、フォームに追加したアイコンをリストから削除しています。

    コード内にわからない部分があれば、コード要素の上にマウス ポインターを合わせると、関連するヒントが表示されます。 Visual Studio デバッガーを使用して、プログラムの実行中にコードの各行をステップ実行することもできます。 詳細については、「How Do I: Step with The Debugger in Visual Studio?」 (操作方法: Visual Studio のデバッガーでステップ実行する) または「デバッガーでのコード間の移動」を参照してください。

  3. ゲーム ボードをアイコンで埋めるには、プログラムが起動したらすぐに AssignIconsToSquares() メソッドを呼び出す必要があります。 Visual C# を使用している場合は、Form1constructorInitializeComponent() メソッドの呼び出しのすぐ下にステートメントを追加し、フォームが新しいメソッドを呼び出してフォーム自体の設定後に表示されるようにします。 新しいオブジェクト (クラスや構造体など) を作成するときは、コンストラクターを呼び出します。 詳細については、「コンストラクター (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  
    
  4. プログラムを保存し、実行します。 各ラベルに割り当てられたランダムなアイコンを備えたフォームが表示されます。

  5. いったんプログラムを終了して、再び実行します。 次の図に示すように、各ラベルに別のアイコンが割り当てられています。

    ランダムなアイコンが表示された絵合わせゲーム
    ランダムなアイコンが表示された絵合わせゲーム

    アイコンは、まだ非表示に設定されていないため、表示されています。 アイコンをプレーヤーに非表示にするには、各ラベルの Forecolor プロパティをその BackColor プロパティと同じ色に設定できます。

    ヒント

    ラベルのようなコントロールを非表示にする別の方法は、Visible プロパティを False に設定することです。

  6. アイコンを非表示にするには、プログラムを停止し、For Each ループ内のコードのコメント行からコメント記号を削除します。

    iconLabel.ForeColor = iconLabel.BackColor;
    
    iconLabel.ForeColor = iconLabel.BackColor
    
  7. メニュー バーで、[すべて保存] をクリックし、プログラムを保存したうえで実行します。 アイコンが非表示になったように見えます。青い背景のみが表示されます。 ただし、アイコンはランダムに割り当てられて、そこに存在しています。 アイコンは、背景と同じ色であるため、プレーヤーには見えなくなっています。 これで、ゲームはやりがいのあるものになりました。プレーヤーはすべてのアイコンをすぐに見ることができなくなったためです。

続行または確認するには