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 = " "; //按钮的文本
}
}
}
}
}
运行效果如下:
左键点击,右键标记。