利用 C# 写的扫雷小游戏(winform框架)
主要运用的知识点:
- C#属性赋值
- C#中数组的声明与使用
- C#泛型集合的使用
- C#继承关系
- ,C#Random随机数对象
有好多不足之处需要完善,欢迎大佬点评
// 该项目的全局变量
// 地雷数量
int MinesS = 10;
// 行
int row=10;
// 列
int col = 8;
// 格子的间隔
int jiange = 2;
// 边界
int bodr = 10;
// 格子的大小
int sizes = 30;
// 地图数组
Minesbutton[,] mintarrery;
// 随机数
Random ran = new Random();
// 存储所有格子的泛型集合
List<Minesbutton> mineslist = new List<Minesbutton>();
public class Minesbutton : Button
{
// 横坐标
public int abscissa { get; set; }
// 纵坐标
public int ordinate { get; set; }
// 内容信息
public string content { get; set; }
// 是否判定过
public bool isbool { get; set; }
}
// 地图布局
private void Buju()
{
mintarrery = new Minesbutton[col,row];
// 循环行
for (int i = 0; i < row; i++)
{
// 循环列
for (int j = 0; j < col; j++)
{
// 初始化一个新的方格
Minesbutton minesbtn = new Minesbutton();
// 指定该方格的宽度和高度
minesbtn.Width = minesbtn.Height = sizes;
// 字体的颜色
minesbtn.ForeColor = Color.Black;
// 设置方格的位置
minesbtn.Location = new Point(bodr + ((sizes + jiange) * j), +bodr + ((sizes + jiange) * i));
// 格子的横坐标
minesbtn.abscissa = j;
// 格子的的纵坐标
minesbtn.ordinate = i;
// 默认格子显示的内容信息为空
minesbtn.content = string.Empty;
minesbtn.BackgroundImage = Image.FromFile(@"../../imgs/wall.png");
minesbtn.BackgroundImageLayout = ImageLayout.Stretch;
// 把初始化后的格子对象放入数组内
mintarrery[j, i] = minesbtn;
Controls.Add(minesbtn);
// 绑定单击事件
minesbtn.Click += Minesbtn_Click;
mineslist.Add(minesbtn);
}
}
}
// 地雷的生成
private void Newmines()
{
// 地雷个数
int mines = MinesS;
while (mines > 0)
{
int ranrow = ran.Next(row);
int rancol = ran.Next(col);
if (mintarrery[rancol, ranrow].content == string.Empty)
{
// 设置显示内容为雷
mintarrery[rancol, ranrow].content = "雷";
//mintarrery[rancol, ranrow].BackgroundImage = Image.FromFile(@"../../imgs/Mines.png");
mines -= 1;
}
}
}
// 格子单击事件
int x=0;
private void Minesbtn_Click(object sender, EventArgs e)
{
x = 0;
Minesbutton minesbtn = sender as Minesbutton;
// 通过sender传递被点的格子的横坐标和纵坐标
Saolei(minesbtn.abscissa, minesbtn.ordinate);
//MessageBox.Show("横坐标" + minesbtn.abscissa.ToString() + "纵坐标" + minesbtn.ordinate.ToString());
for (int i = 0; i < mineslist.Count; i++)
{
if (mineslist[i].isbool == true)
{
x++;
if (x == col * row - MinesS)
{
MessageBox.Show("成功");
x = 0;
ShuaxinMap();
}
}
}
}
// 判断是不是雷
private bool ISmines(int hengzuobiao,int zongzuobiao)
{
// 先声明变量默认表示不是雷
bool jieguo = false;
// 指定范围在整个地图内
if (hengzuobiao>=0&&hengzuobiao<col&&zongzuobiao>=0&&zongzuobiao<row)
{
// 是否被判断过
if (mintarrery[hengzuobiao,zongzuobiao].isbool==false)
{
// 判断内容是不是雷
if (mintarrery[hengzuobiao,zongzuobiao].content=="雷")
{
jieguo = true;
}
}
}
return jieguo;
}
// 扫雷
private void Saolei(int hengzuobiao,int zongzuobiao)
{
List<Minesbutton> minesbuttons = new List<Minesbutton>();
minesbuttons.Add(mintarrery[hengzuobiao,zongzuobiao]);
// 循环集合成员
while (minesbuttons.Count>0)
{
int heng = minesbuttons[0].abscissa;
int zong = minesbuttons[0].ordinate;
// 周围雷数
int mines = 0;
if (ISmines(heng,zong)==true)
{
minesbuttons.Clear();
mintarrery[heng, zong].BackgroundImage = Image.FromFile(@"../../imgs/Mines.png");
MessageBox.Show("游戏结束!");
ShuaxinMap();
}
// 不是雷的情况
else
{
// 判断周围的雷八个方向
if (ISmines(heng - 1,zong)==true)
{
mines += 1;
}
if (ISmines(heng, zong-1) == true)
{
mines += 1;
}
if (ISmines(heng-1 , zong +1) == true)
{
mines += 1;
}
if (ISmines(heng-1,zong-1)==true)
{
mines += 1;
}
if (ISmines(heng + 1, zong) == true)
{
mines += 1;
}
if (ISmines(heng, zong +1) == true)
{
mines += 1;
}
if (ISmines(heng + 1, zong-1) == true)
{
mines += 1;
}
if (ISmines(heng + 1, zong + 1) == true)
{
mines += 1;
}
minesbuttons[0].isbool = true;
minesbuttons[0].BackColor = Color.Wheat;
minesbuttons[0].BackgroundImage = null;
// 周围没雷
if (mines==0)
{
minesbuttons.AddRange(zhouweimines(heng,zong));
}
else
{
mintarrery[heng, zong].Text = mines.ToString();
}
minesbuttons.RemoveAt(0);
}
}
}
// 周围格子
private List<Minesbutton> zhouweimines(int heng,int zong)
{
// 存储周围格子
List<Minesbutton> mineslist = new List<Minesbutton>(8);
// 点击的不是最左边
if (heng > 0)
{
// 点击的不是最上边的格子
if (zong > 0)
{
// 左上方有格子,没被判断过
if (mintarrery[heng - 1, zong - 1].isbool == false)
{
mineslist.Add(mintarrery[heng - 1, zong - 1]);
}
}
// 点击的不是最下面
if (zong + 1 < row)
{
// 左下方有格子,没被判断过
if (mintarrery[heng - 1, zong + 1].isbool == false)
{
mineslist.Add(mintarrery[heng - 1, zong + 1]);
}
}
// 点击的不是最左边,左边还有,没被判断过
if (mintarrery[heng - 1,zong].isbool==false)
{
mineslist.Add(mintarrery[heng-1,zong]);
}
}
// 点击的格子的行数加1小于列数,为最右边的左边的格子
if (heng+1<col)
{
// 点击的为不是最上面的格子
if (zong>0)
{
// 右上角有格子,没被判断过
if (mintarrery[heng+1,zong-1].isbool==false)
{
mineslist.Add(mintarrery[heng +1, zong - 1]);
}
// 点击的为最下面的上一个
if (zong+1<row)
{
// 右下角有格子,没被判断过
if (mintarrery[heng + 1, zong + 1].isbool == false)
{
mineslist.Add(mintarrery[heng + 1, zong + 1]);
}
}
// 点击的为右边的格子,没被判断过
if (mintarrery[heng+1,zong].isbool==false)
{
mineslist.Add(mintarrery[heng + 1, zong]);
}
}
}
// 点击的不是最上面的格子,上面还有格子
if (zong>0)
{
// 上方有格子,没被判断过
if (mintarrery[heng,zong-1].isbool==false)
{
mineslist.Add(mintarrery[heng , zong-1]);
}
}
// 点击的不是最下面的格子,下面还有格子
if (zong+1<row)
{
// 下方有格子,没被判断过
if (mintarrery[heng,zong+1].isbool==false)
{
mineslist.Add(mintarrery[heng, zong + 1]);
}
}
return mineslist;
}
private void ShuaxinMap()
{
foreach (Minesbutton item in mineslist)
{
item.Dispose();
}
Buju();
Newmines();
}
private void Form1_Load(object sender, EventArgs e)
{
Buju();
Newmines();
}