C#小游戏之扫雷

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

namespace 扫雷
{
    public partial class GameForm : Form
    {
        int num = 0;
        const int M = 18, N = 18, BOMPNUM = 80; //方格的横向纵向数量
        bool isStart = true;                    //是否第一次点击方块
        bool isLost = false;                    //是否输掉了本局游戏
        bool[,] isClicked = new bool[M, N];     //记录方块是否被点击
        bool[,] isLabeled = new bool[M, N];     //记录方块是否被标记
        int[,] isBomp = new int[M, N];          //记录方块包含的信息
        Button[,] gameBomp = new Button[M, N];  //按钮的方式模拟方块

        //窗体构造函数
        public GameForm()                       //窗体构造函数
        {
            InitializeComponent();              //初始化组件
            InitializeGame();                   //初始化游戏
        }

        //初始化本游戏
        private void InitializeGame()           //游戏的初始化
        {
            this.Text = "扫雷";          //游戏窗标题
            this.Width = 40 + M * 30;           //游戏窗宽度
            this.Height = 60 + N * 30;          //游戏窗高度
            this.MaximizeBox = false;                                              //窗体不可最大化
            this.StartPosition=FormStartPosition.CenterScreen;                     //窗口的启动位置
            this.FormBorderStyle = FormBorderStyle.FixedSingle;                    //窗口不可改大小
            //按钮控件的添加
            for(int i=0;i<M;i++)
            {
                for(int j=0;j<N;j++)
                {
                    isBomp[i, j] = 0;                                              //初始无地雷
                    isLabeled[i, j] = false;
                    isClicked[i, j] = false;                                       //初始不点击      
                    gameBomp[i, j] = new Button();
                    gameBomp[i, j].BackColor = Color.LightSkyBlue;                 //浅蓝背景色
                    gameBomp[i, j].FlatStyle = System.Windows.Forms.FlatStyle.Flat;//扁平的外观
                    gameBomp[i, j].Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
                    gameBomp[i, j].Width = 30;                                     //按钮的宽度
                    gameBomp[i, j].Height = 30;                                    //按钮的高度
                    gameBomp[i, j].Top = i * 30 + 10;                              //按钮的位置
                    gameBomp[i, j].Left= j * 30 + 10;
                    gameBomp[i, j].Tag = i*M+j+1;                                  //按钮的标签
                    gameBomp[i, j].Text = " ";                                     //按钮的文本
                    gameBomp[i, j].Click += new EventHandler(OnClickedGameBomp);   //新回调函数
                    gameBomp[i, j].MouseUp += new MouseEventHandler(OnRightClicked); //新回调函数
                    this.Controls.Add(gameBomp[i, j]);                             //加载至窗体
                }
            }
        }

        private void OnRightClicked(object sender, MouseEventArgs e)
        {
            Button thisBomp = sender as Button;
            int i = (int.Parse(thisBomp.Tag.ToString()) % M == 0 ? int.Parse(thisBomp.Tag.ToString()) / M - 1 : int.Parse(thisBomp.Tag.ToString()) / M), j = int.Parse(thisBomp.Tag.ToString()) - i * M - 1;
            if(e.Button==MouseButtons.Right&&!isClicked[i,j])
            {
                isLabeled[i, j] = !isLabeled[i, j];
                if (isLabeled[i, j])
                    thisBomp.BackColor = Color.Red;
                else
                    thisBomp.BackColor = Color.LightSkyBlue;
            }
        }

        private void OnClickedGameBomp(object sender, EventArgs e)                 //方块点击事件
        {
            Button thisBomp = sender as Button;
            int i = (int.Parse(thisBomp.Tag.ToString()) % M == 0 ? int.Parse(thisBomp.Tag.ToString()) / M -1: int.Parse(thisBomp.Tag.ToString()) / M), j = int.Parse(thisBomp.Tag.ToString()) - i * M - 1;
            if (isStart)                        //是否首次点击
            {
                setBomp(i, j);
                isStart = false;
            }
            if (isLabeled[i, j])
                return;
            if (isClicked[i,j]||isLost)         //是否已点击过
                return;

            if (isBomp[i, j]==-1)               //是否踩中地雷
            {
                isLost = true;
                discoverAllBomp();
                MessageBox.Show("啊哦,踩雷身亡了!","游戏失败",MessageBoxButtons.OK,MessageBoxIcon.Error);
                reStartGame();
            }
            else
            {
                gameBomp[i, j].BackColor = Color.LightGreen;
                isClicked[i, j] = true;
                if (isBomp[i, j] > 0)           //周围有雷,显示雷的数量
                    thisBomp.Text = isBomp[i, j].ToString();
                else                            //周围无雷,进行扩充处理
                {
                    if (i - 1 > -1 && j - 1 > -1 && isBomp[i - 1, j - 1] >-1)
                        OnClickedGameBomp(gameBomp[i - 1, j - 1], null);
                    if (i - 1 > -1 && isBomp[i - 1, j] > -1)
                        OnClickedGameBomp(gameBomp[i - 1, j], null);
                    if (i - 1 > -1 && j + 1 < M && isBomp[i - 1, j + 1] > -1)
                        OnClickedGameBomp(gameBomp[i - 1, j + 1], null);
                    if (j - 1 > -1 && isBomp[i, j - 1] > -1)
                        OnClickedGameBomp(gameBomp[i, j - 1], null);
                    if (j + 1 < M && isBomp[i, j + 1] > -1)
                        OnClickedGameBomp(gameBomp[i, j + 1], null);
                    if (j - 1 > -1 && i + 1 < M && isBomp[i + 1, j - 1] > -1)
                        OnClickedGameBomp(gameBomp[i + 1, j - 1], null);
                    if (i + 1 < N && isBomp[i + 1, j] > -1)
                        OnClickedGameBomp(gameBomp[i + 1, j], null);
                    if (i + 1 < N && j + 1 < M && isBomp[i + 1, j + 1] > -1)
                        OnClickedGameBomp(gameBomp[i + 1, j + 1], null);
                }
            }
            num++;
            if (num == M * N - BOMPNUM)
            {
                discoverAllBomp();
                MessageBox.Show("恭喜你成功通关!", "游戏胜利", MessageBoxButtons.OK, MessageBoxIcon.Information);
                reStartGame();
            }
        }

        //显示所有地雷
        private void discoverAllBomp()
        {
            for (int i = 0; i < M; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    if (isBomp[i, j] == -1)
                        gameBomp[i, j].Text = "●";
                }
            }
        }

        //随机安放地雷
        private void setBomp(int clickedI,int clickedJ)
        {
            int i,j, k;
            //随机安放布雷
            Random rand = new Random();
            for(i=0;i<BOMPNUM;i++)
            {
                j = rand.Next(M);
                k = rand.Next(N);
                if(isBomp[j,k]==-1||((j==clickedI)&&(k==clickedJ)))
                {
                    i--;
                    continue;
                }
                else
                    isBomp[j, k] = -1;
            }
            //每个方块周围雷数量的统计
            for(i=0;i<M;i++)
            {
                for(j=0;j<N;j++)
                {
                    k = 0;
                    if (isBomp[i, j] == -1)continue;
                    if (i - 1 > -1 && j - 1 > -1 && isBomp[i - 1, j - 1] == -1)k++;
                    if (i - 1 > -1&&isBomp[i - 1, j] == -1)k++;
                    if (i - 1 > -1 && j + 1 < M && isBomp[i - 1, j + 1] == -1)k++;
                    if (j - 1 > -1 && isBomp[i, j - 1] == -1)k++;
                    if (j + 1 < M && isBomp[i, j + 1] == -1)k++;
                    if (j - 1 > -1 && i+1 < N && isBomp[i+1, j - 1] == -1)k++;
                    if (i+1 <N && isBomp[i+1, j] == -1)k++;
                    if (i + 1 < N &&j+1<M&& isBomp[i + 1, j+1] == -1)k++;
                    isBomp[i, j] = k;
                }
            }
        }

        //重新开始游戏
        private void reStartGame()
        {
            num = 0;
            isLost = false;
            isStart = true;
            for (int i = 0; i < M; i++)
            {
                for (int j = 0; j < N; j++)
                {
                    isBomp[i, j] = 0;                                              //初始无地雷
                    isClicked[i, j] = false;                                       //初始不点击      
                    gameBomp[i, j].BackColor = Color.LightSkyBlue;                 //浅蓝背景色
                    gameBomp[i, j].Text = " ";                                     //按钮的文本
                }
            }
        }
    }
}

运行效果如下:

左键点击,右键标记。




评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值