新建一个C#的窗体应用程序。代码和项目如下。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MineSweeperSharp
{
public partial class FormMatrix : Form
{
class Brick : Button
{
public bool isMine;
public int x;
public int y;
public Brick(int in_x, int in_y, bool in_isMine = false)
{
x = in_x;
y = in_y;
isMine = in_isMine;
}
public bool isUncovered()
{
if (Text == flagStr || Text == "")//如果砖头的文本不是旗子或空白
{
return true;
}
else
{
return false;
}
}
public void draw(String str, String frontName, int frontSize, Color fore, Color back)
{
Text = str;
Font = new Font(frontName, frontSize);
ForeColor = fore;
BackColor = back;
}
public void drawNormal() //正常砖块
{
draw("", "Segoe UI", 14, Color.Black, Color.LightGray);
}
public void drawBase() //陷下去砖块
{
draw("", "Segoe UI", 14, Color.Black, Color.Snow);
}
public const String minestr="$";
public void drawMine() //雷
{
draw(minestr, "Wingdings", 18, Color.Black, Color.LightGray);
}
public const String explosive = "*";
public void drawExplosive() //爆炸
{
draw("*", "Wingdings", 18, Color.Black, Color.Red);
}
public const String flagStr = "~";
public void drawFlag() //旗子
{
draw(flagStr, "Wingdings", 18, Color.Black, Color.Orange);
}
public void drawNumber(int num) //数字
{
Color currNumColor = Color.Black;
switch (num)
{
case 0: currNumColor = Color.Snow; break;
case 1: currNumColor = Color.Blue; break;
case 2: currNumColor = Color.Green; break;
case 3: currNumColor = Color.Red; break;
case 4: currNumColor = Color.DarkBlue; break;
case 5: currNumColor = Color.Brown; break;
case 6: currNumColor = Color.LightBlue; break;
case 7: currNumColor = Color.Black; break;
case 8: currNumColor = Color.Gray; break;
}
draw(num.ToString(), "Segoe UI ", 14, currNumColor, Color.Snow);
return;
}
}
public FormMatrix()
{
InitializeComponent();
startNewGame();
}
void startNewGame()
{
Controls.Clear(); //清除所有控件
int upMargin = 64; //上边距 2的6次方
int leftMargin = 64; //左边距
int dx = 32; //按钮的高度
int dy = 32; //按钮的宽度
bricks=new Brick[10,10];
Random rd = new Random(); //随机数的生成器
for (int i = 0; i < 10; i++) //等Form初始化之后,添加100个按钮 10*10
{
for (int j = 0; j < 10; j++)
{
Brick newBrick = new Brick(i, j); //创建按钮
if (rd.Next()%6 == 0) //用随机值决定本砖块是否是雷
{
newBrick.isMine = true;
//newBrick.drawMine();
}
newBrick.Location = new Point(leftMargin + dx * i, upMargin + dy * j); //设定按钮的位置
newBrick.Size = new Size(dx, dy); //设定按钮的大小
newBrick.BackColor = Color.LightGray;
newBrick.MouseClick += new MouseEventHandler(newBrick_MouseClick); //给每个按钮加按键响应
newBrick.MouseUp += new MouseEventHandler(newBrick_MouseUp);
this.Controls.Add(newBrick); //将新按钮添加到窗体
bricks[i,j]=newBrick; //添加到数组
}
}
Button resetButton = new Button(); //创建重置游戏按钮
resetButton.Size = new Size(64,48);
resetButton.Location = new Point(Size.Width/2-64/2,8);
resetButton.BackColor = Color.LightGray;
resetButton.Text = "Reset";
resetButton.MouseClick += resetButton_MouseClick;
Controls.Add(resetButton);
}
bool isWin()
{
int mineCount = 0; //统计雷数
int uncovereBrickCount = 0;
foreach(Brick brick in bricks) //遍历所有的砖块
{
if(brick.isMine) //如果是雷
{
mineCount++;
}
if(brick.isUncovered())//如果是没掀开过的砖块
{
uncovereBrickCount++;
}
}
if (uncovereBrickCount == mineCount) //两者相同
{
return true; //赢了
}
else
{
return false;
}
}
Brick[,] bricks;
void resetButton_MouseClick(object sender, MouseEventArgs e)
{
startNewGame();
return;
}
void newBrick_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) //右击颜色变成红色
{
Brick currBrick = (Brick)sender;
currBrick.drawFlag();
}
}
void digBrick(Brick brick)
{
int currX = brick.x; //先获取当前坐标
int currY = brick.y;
int mineCountRounded = 0;//周围雷数计数器
for (int i = -1; i <= 1; i++) //判断八项
{
for (int j = -1; j <= 1; j++)
{
int testX = currX + i; //获取当前索引
int testY = currY + j;
if (testX >= 0 && testX < 10 && testY >= 0 && testY < 10) //判断索引的合法性
{
if (bricks[testX, testY].isMine == true)//判定是否是雷
{
mineCountRounded++;
}
}
}
}
brick.drawNumber(mineCountRounded);//将数字写在按钮上
if (mineCountRounded == 0) //判断是不是空地 周围没有雷
{
for (int i = -1; i <= 1; i++)
{
for (int j = -1; j <= 1; j++)
{
int testX = currX + i; //获取当前索引
int testY = currY + j;
if (testX >= 0 && testX < 10 && testY >= 0 && testY < 10) //判断索引的合法性
{
if (bricks[testX, testY].isMine == false && bricks[testX,testY].Text=="")//判定是否是雷
{
digBrick(bricks[testX,testY]); //递归调用
}
}
}
}
}
}
void newBrick_MouseClick(object sender, MouseEventArgs e)
{
Brick currBrick = (Brick)sender; //点击后颜色变成淡蓝色
if (e.Button == MouseButtons.Left) //如果是左键
{
if (currBrick.Text == Brick.flagStr)
{
return;
}
if (currBrick.isMine) //是雷
{
currBrick.drawExplosive();
MessageBox.Show("You are blown up!");
startNewGame();
}
else //不是雷
{
digBrick(currBrick);//挖开当前雷
if (isWin())
{
MessageBox.Show("You Win!");
startNewGame();
}
}
}
}
}
}