マインスイーパみたいなゲームを作成する

マインスイーパのようなゲームを作成してみました。
プログラムを起動すると、「Mine」というフォームが開きます。

  • startボタンをクリックします。



  • 10×10のマスが表示されます。



  • マス目をクリックすると、周囲に存在する地雷の数が表示されます。



  • 地雷をクリックしてしまうと、2秒後に「残念!!」のメッセージが表示されます。


↓2秒後


  • 地雷以外のすべてのマスをクリックすると、2秒後に「ヤッタ(^0^/」と表示されます。


↓2秒後



※プログラムを終了する場合は、左クリックします。startボタンをクリックすると再びゲームを開始します。




以下プログラムです。

using System;
using System.Threading;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace mine
{
    public partial class MineForm : Form
    {
        const string Text_name = "Mine";              // フォームの名前
        const int Width_length = 400;                 // フォームの幅
        const int Height_length = 400;                // フォームの高さ
        const int mass_num = 10;                      // 行・列のマス数
        const int mass_wid = 20;                      // 1マスの幅
        int mass_start;                               // 行・列の始まりの位置
        int mass_end;                                 // 行・列の終わりの位置
        bool button_flg = false;                      // ボタンフラグ
        int max_zirai_num = 10;                       // 最大地雷個数
        string[,] mass = new string[10, 10];          // マスの配列

        private void set_mass_start() { mass_start = mass_wid * 4; }

        private void set_mass_end() { mass_end = mass_start + mass_wid * mass_num; }

        public MineForm()
        {
            InitializeComponent();
        }

        private void Mine_Load(object sender, EventArgs e)
        {
            // 画面関連変数設定
            Text = Text_name;
            Width = Width_length;
            Height = Height_length;
            Left = Screen.PrimaryScreen.Bounds.Width-Width;
            Top = Screen.PrimaryScreen.Bounds.Top;

            // マス関連変数設定
            set_mass_start();
            set_mass_end();

            // ラベルの表示
            label1.Left = 200;
            label1.Top = 20;
            label1.Text = "startをクリック!!";

        }

        private void button_Click(object sender, EventArgs e)
        {
            // ラベルの表示
            label1.Left = 200;
            label1.Top = 20;
            label1.Text = "どうぞ";

            // マスの表示
            Graphics g = CreateGraphics();
            for (int n = mass_start; n <= mass_end; n += mass_wid)
            {
                g.DrawLine(Pens.Black, mass_start, n, mass_end, n);     // 行方向の線
                g.DrawLine(Pens.Black, n, mass_start, n, mass_end);     // 列方向の線
            }

            // マスの初期化
            for (int x = 0; x <= mass_num - 1; x++)
            {
                for (int y = 0; y <= mass_num - 1; y++)
                {
                    mass[x, y] = "unknown";
                }
            }

            // 地雷配置
            Random rm = new Random();
            for(int n = 0; n <= max_zirai_num-1; n++)
            {
                mass[rm.Next(mass_num), rm.Next(mass_num)] = "zirai";
            }

            button_flg = true;  // ボタンフラグON

            g.Dispose();
        }

        private void MineForm_MouseDown(object sender, MouseEventArgs e)
        {
            // 右クリックした場合
            if (e.Button == MouseButtons.Right)
            {
                // 終了
                Close();
            }
            // startボタンを押した状態で左クリックした場合
            else if(button_flg == true & e.Button == MouseButtons.Left)            
            {
                // クリックした場所がマスの場合
                if (((int)e.X > mass_start & (int)e.X < mass_end)
                    & ((int)e.Y > mass_start & (int)e.Y < mass_end))
                {
                    // マスの特定
                    int x = ((int)(e.X / mass_wid) + 1) - (mass_start / mass_wid);  // 行
                    int y = ((int)(e.Y / mass_wid) + 1) - (mass_start / mass_wid);  // 列

                    // マスの位置
                    int point_x = (x-1) * mass_wid + mass_start;
                    int point_y = (y-1) * mass_wid + mass_start;
                    Rectangle rect = new Rectangle(point_x, point_y, mass_wid, mass_wid);

                    // 地雷を踏んだら
                    if (mass[x-1, y-1] == "zirai")
                    {
                        button_flg = false;  // ボタンフラグOFF

                        // マスを黒色を変える
                        Graphics g = CreateGraphics();
                        g.FillRectangle(Brushes.Black, rect);
                        g.DrawRectangle(Pens.Black, rect);

                        // 2秒スリープ
                        Thread.Sleep(2000);

                        // ラベルの表示
                        label1.Text = "残念!!";

                        g.Dispose();

                        // 画面クリア
                        Invalidate();

                    }
                    // 地雷を踏んでないなら
                    else
                    {
                        // 周囲の地雷の数カウント
                        int cnt = 0;
                        for (int i = (x - 1) - 1; i <= x; i++)
                        {
                            for (int j = (y - 1) - 1; j <= y; j++)
                            {
                                if (i >= 0 & i <= mass_num - 1 & j >= 0 & j <= mass_num - 1)
                                {
                                    if (mass[i, j] == "zirai")
                                    {
                                        cnt++;
                                    }
                                }
                            }
                        }

                        // マスを緑色に変える
                        Graphics g = CreateGraphics();
                        g.FillRectangle(Brushes.LightGreen, rect);
                        g.DrawRectangle(Pens.Black, rect);

                        // 周囲の地雷の数を表示
                        Font myfont = new Font("SansSerif", 11, FontStyle.Bold);
                        g.DrawString("" + cnt, myfont, Brushes.Black, rect);

                        // マスをsafeに指定する
                        mass[x - 1, y - 1] = "safe";

                        // unknownのマスがなかったら
                        bool u_flg = false;
                        for (int i = 0; i <= mass_num - 1; i++)
                        {
                            for (int j = 0; j <= mass_num - 1; j++)
                            {
                                if (mass[i, j] == "unknown")
                                {
                                    u_flg = true;
                                }
                            }
                        }
                        if (!u_flg)
                        {
                            button_flg = false;  // ボタンフラグOFF

                            // 2秒スリープ
                            Thread.Sleep(2000);

                            // ラベルの表示
                            label1.Text = "ヤッタ(^0^/";

                            // 画面クリア
                            Invalidate();
                        }
                        g.Dispose();
                    }
                }
            }
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }
    }
}