扫雷-c#
程序员文章站
2022-04-07 23:01:25
...
一、实验目的:
1、掌握c#窗体和控件的常用属性和功能
2、完成扫雷游戏的基本功能
二、实验要求:
1、游戏基本功能必须实现。鼠标左键点非雷点,否则游戏结束;鼠标右键一次标记雷点,邮件两次标记上问号,右键三次取消标记。
2、可以对游戏选择难度,分为初级、中级和高级,按笑脸按钮重新开始游戏
3、符合游戏逻辑。每个点周围的雷的个数必须正确
4、点开雷点,显示游戏结束,并且显示各个点的情况
5、点开所有非雷点或者标记完所有雷点时,能够显示游戏胜利
6、不接受键盘操作,只接受鼠标操作
三、实验内容:
1、构建菜单栏,添加开始栏、帮助栏,开始栏用于游戏难度的选择,帮助栏用于游戏规则的介绍
2、创建雷区,使用buttonarray模拟雷区,start按钮用于重新开始游戏
3、鼠标左键时,分三种情况:
(1)鼠标点击雷点时,直接显示游戏结束
(2)鼠标点击空白点时,周围没雷,则显示周围点的情况,周围有雷,只显示此点的雷数
(3)鼠标左键点了一个大于0的数字,显示周围雷点的情况,若周围雷点标错,直接显示游戏结束
4、鼠标右键时,第一次标记为雷点,第二次标记为疑问,第三次取消标记。
5、显示周围点的情况时,因为周围点的雷点数也可能为0,还需要显示此点周围的情况,需用递归,完成此项功能。
6、点击笑脸按钮时,如果不是第一次开始,就删除原有按钮,否则直接初始化长度、宽度和雷数,重新构建button按钮
7、点击菜单栏的难度选择按钮时,如果不是第一次开始,就删除原有按钮,否则直接初始化长度、宽度和雷数,重新构建button按钮
四、实验源代码:
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 WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Size s = new Size(250,300);
this.MaximumSize = this.MinimumSize = s;
this.Size = s;
}
Button start = new Button();
Button[,] buttonarray;
int[,] MileState;
int Miles = 10;
int widths = 9, heights = 9;
int remain;//剩余雷数
int notMiles;//剩余非雷数
int isfirst = 1;//是否是第一次
int[,] sign;//表示各点是否输出
private void Form1_Load(object sender, EventArgs e)
{
MenuStrip ms = new MenuStrip();
ToolStripMenuItem tsmione = new ToolStripMenuItem("开始");
ToolStripMenuItem tsmi1 = new ToolStripMenuItem("初级");
ToolStripMenuItem tsmi2 = new ToolStripMenuItem("中级");
ToolStripMenuItem tsmi3 = new ToolStripMenuItem("高级");
ToolStripMenuItem tsmi4 = new ToolStripMenuItem("退出");
tsmione.DropDownItems.Add(tsmi1);
tsmione.DropDownItems.Add(tsmi2);
tsmione.DropDownItems.Add(tsmi3);
tsmione.DropDownItems.Add(tsmi4);
ms.Items.Add(tsmione);
tsmi1.Click += new EventHandler(tsmi1_Click);
tsmi2.Click += new EventHandler(tsmi2_Click);
tsmi3.Click += new EventHandler(tsmi3_Click);
tsmi4.Click += new EventHandler(tsmi4_Click);
ToolStripMenuItem tsmitwo = new ToolStripMenuItem("帮助");
ToolStripMenuItem tsmi5 = new ToolStripMenuItem("游戏规则");
tsmi5.Click += new EventHandler(tsmi5_Click);
tsmitwo.DropDownItems.Add(tsmi5);
ms.Items.Add(tsmitwo);
this.Controls.Add(ms);
//笑脸按钮
start.Text = "????";
start.Location = new Point(75, 25);
start.Click += new EventHandler(start_Click);
this.Controls.Add(start);
}
private void tsmi1_Click(object sender, EventArgs e)
{
Size s = new Size(250, 300);
this.MaximumSize = this.MinimumSize = s;
this.Size = s;
if (isfirst == 1)
{
widths = 9; heights = 9; Miles = 10;
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
isfirst = 0;
return;
}
delete();
widths = 9; heights = 9; Miles = 10;
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
}
private void tsmi2_Click(object sender, EventArgs e)
{
Size s = new Size(400, 450);
this.MaximumSize = this.MinimumSize = s;
this.Size = s;
if (isfirst == 1)
{
widths = 16; heights = 16; Miles = 40;
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
isfirst = 0;
return;
}
delete();
widths = 16; heights = 16; Miles = 40;
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
}
private void tsmi3_Click(object sender, EventArgs e)
{
Size s = new Size(650, 450);
this.MaximumSize = this.MinimumSize = s;
this.Size = s;
if (isfirst == 1)
{
widths = 30; heights = 16; Miles = 99;
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
isfirst = 0;
return;
}
delete();
widths = 30; heights = 16; Miles = 99;
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
}
//删除控件
public void delete()
{
int i, j;
for (i = 0; i < heights; i++)
for (j = 0; j < widths; j++)
this.Controls.Remove(buttonarray[i, j]);
}
private void tsmi4_Click(object sender, EventArgs e)
{
Close();
}
private void tsmi5_Click(object sender, EventArgs e)
{
string str = "鼠标左键点开非雷点继续游戏,点开雷点游戏结束\r\n";
str += "鼠标右键一次标记雷点,右键两次标记问号,右键三次取消标记";
MessageBox.Show(str);
}
//设计扫雷界面,布雷
private void Initialize_button(object sender, EventArgs e)
{
//初始化游戏界面
//创建扫雷按钮,设计游戏界面
buttonarray = new Button[heights, widths];
MileState = new int[heights, widths];
notMiles = widths * heights - Miles;
remain = Miles;
int i, j;
for (i = 0; i < heights; i++)
{
for (j = 0; j < widths; j++)
{
buttonarray[i, j] = new System.Windows.Forms.Button();
buttonarray[i, j].Location = new System.Drawing.Point(20 + 20 * j, 60 + 20 * i);
buttonarray[i, j].Size = new System.Drawing.Size(20, 20);
buttonarray[i, j].UseVisualStyleBackColor = true;
buttonarray[i, j].Text = "";
buttonarray[i, j].MouseDown += new MouseEventHandler(but_MouseDown);
this.Controls.Add(buttonarray[i, j]);
}
}
int count = 0;
//雷区初始化,鼠标右键次数初始化
for (i = 0; i < heights; i++)
for (j = 0; j < widths; j++)
MileState[i, j] = 0;
//设置雷的位置
while (count < Miles)
{
Random r = new Random();
i = r.Next(heights);
j = r.Next(widths);
if (MileState[i, j] != -1)
{
MileState[i, j] = -1;
count++;
//雷点周围非雷的点各加1
if (i - 1 >= 0 && j - 1 >= 0 && MileState[i - 1, j - 1] != -1) MileState[i - 1, j - 1] += 1;
if (i - 1 >= 0 && MileState[i - 1, j] != -1) MileState[i - 1, j] += 1;
if (i - 1 >= 0 && j + 1 < widths && MileState[i - 1, j + 1] != -1) MileState[i - 1, j + 1] += 1;
if (j - 1 >= 0 && MileState[i, j - 1] != -1) MileState[i, j - 1] += 1;
if (j + 1 < widths && MileState[i, j + 1] != -1) MileState[i, j + 1] += 1;
if (i + 1 < heights && j - 1 >= 0 && MileState[i + 1, j - 1] != -1) MileState[i + 1, j - 1] += 1;
if (i + 1 < heights && MileState[i + 1, j] != -1) MileState[i + 1, j] += 1;
if (i + 1 < heights && j + 1 < widths && MileState[i + 1, j + 1] != -1) MileState[i + 1, j + 1] += 1;
}
}
}
//点击笑脸按钮
private void start_Click(object sender, EventArgs e)
{
if (isfirst == 1)
{
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
isfirst = 0;
return;
}
delete();
remain = Miles;
notMiles = widths * heights - Miles;
start.Text = "????";
Initialize_button(sender, e);
start.Location = new Point((buttonarray[0, 0].Location.X
+ buttonarray[0, widths - 1].Location.X + 20 - start.Size.Width) / 2, 25);
}
//按下鼠标键时
private void but_MouseDown(object sender, MouseEventArgs e)
{
//获取按钮坐标
int x = (this.PointToClient(MousePosition).Y - 60) / 20;
int y = (this.PointToClient(MousePosition).X - 20) / 20;
sign = new int[heights, widths];
//递归时表示是否访问
for (int i = 0; i < heights; i++)
for (int j = 0; j < widths; j++)
sign[i, j] = 0;
//鼠标左键点了一个大于0的数字
if (e.Button == MouseButtons.Left && buttonarray[x, y].Text != "" && buttonarray[x, y].Text != "×"
&& buttonarray[x, y].Text != "?" && buttonarray[x, y].Text != "-1")
{
int num = 0;
bool issigned = false;
//周围标记的地雷个数
if (x - 1 >= 0 && y - 1 >= 0)
{
if (buttonarray[x - 1, y - 1].Text == "×") num++;
else if (buttonarray[x - 1, y - 1].Text == "-1") issigned = true;
}
if (x - 1 >= 0)
{
if (buttonarray[x - 1, y].Text == "×") num++;
else if (buttonarray[x - 1, y].Text == "-1") issigned = true;
}
if (x - 1 >= 0 && y + 1 < widths)
{
if (buttonarray[x - 1, y + 1].Text == "×") num++;
else if (buttonarray[x - 1, y + 1].Text == "-1") issigned = true;
}
if (y - 1 >= 0)
{
if (buttonarray[x, y - 1].Text == "×") num++;
else if (buttonarray[x, y - 1].Text == "-1") issigned = true;
}
if (y + 1 < widths)
{
if (buttonarray[x, y + 1].Text == "×") num++;
else if (buttonarray[x, y + 1].Text == "-1") issigned = true;
}
if (x + 1 < heights && y - 1 >= 0)
{
if (buttonarray[x + 1, y - 1].Text == "×") num++;
else if (buttonarray[x + 1, y - 1].Text == "-1") issigned = true;
}
if (x + 1 < heights)
{
if (buttonarray[x + 1, y].Text == "×") num++;
else if (buttonarray[x + 1, y].Text == "-1") issigned = true;
}
if (x + 1 < heights && y + 1 < widths)
{
if (buttonarray[x + 1, y + 1].Text == "×") num++;
else if (buttonarray[x + 1, y + 1].Text == "-1") issigned = true;
}
if (buttonarray[x, y].Text == Convert.ToString(num))
{
if (issigned == false) { print(x, y, sign); notMiles++; }
else MessageBox.Show("哎呀,点错了,重新开始吧");
}
}
//鼠标左键,周围没雷
if (e.Button == MouseButtons.Left && MileState[x, y] == 0)
{
if (sign[x, y] == 0) print(x, y, sign);
if (notMiles == 0)
MessageBox.Show("恭喜你,扫雷成功,回去领赏吧", "成功");
}
//鼠标左键,周围有雷
if (e.Button == MouseButtons.Left && MileState[x, y] > 0)
{
if (sign[x, y] == 0 && --notMiles == 0)
MessageBox.Show("恭喜你,扫雷成功,回去领赏吧", "成功");
sign[x, y] = 1;
buttonarray[x, y].FlatStyle = FlatStyle.Popup;
buttonarray[x, y].Text = Convert.ToString(MileState[x, y]);
}
//鼠标左键,错误
if (e.Button == MouseButtons.Left && MileState[x, y] == -1)
{
for (x = 0; x < heights; x++)
for (y = 0; y < widths; y++)
{
if (MileState[x, y] != 0)
buttonarray[x, y].Text = Convert.ToString(MileState[x, y]);
else
buttonarray[x, y].FlatStyle = FlatStyle.Popup;
}
start.Text = "????";
MessageBox.Show("哎呀,点错了,重新开始吧!");
}
//鼠标右键
if (e.Button == MouseButtons.Right)
{
//第一次鼠标右键
if (buttonarray[x, y].Text == "" && sign[x, y] == 0)
{
//用X表示雷
buttonarray[x, y].Text = "×";
sign[x, y] = 1;
if (MileState[x, y] == -1)
{
if (--remain == 0) MessageBox.Show("恭喜你,扫雷成功,回去领赏吧", "成功");
}
}
//第二次鼠标右键
else if (buttonarray[x, y].Text == "×")
{
buttonarray[x, y].Text = "?";
remain++;
}
//第三次鼠标右键
else if (buttonarray[x, y].Text == "?")
{
buttonarray[x, y].Text = "";
sign[x, y] = 0;
}
}
}
//显示周围雷区的情况,递归
private void print(int x, int y, int[,] sign)
{
buttonarray[x, y].FlatStyle = FlatStyle.Popup;
sign[x, y] = 1;
notMiles--;
if (x - 1 >= 0 && y - 1 >= 0 && sign[x - 1, y - 1] == 0)
if (MileState[x - 1, y - 1] > 0)
{
buttonarray[x - 1, y - 1].Text = Convert.ToString(MileState[x - 1, y - 1]);
buttonarray[x - 1, y - 1].FlatStyle = FlatStyle.Popup;
sign[x - 1, y - 1] = 1;
}
else if (MileState[x - 1, y - 1] == 0) print(x - 1, y - 1, sign);
if (x - 1 >= 0 && sign[x - 1, y] == 0)
if (MileState[x - 1, y] > 0)
{
buttonarray[x - 1, y].Text = Convert.ToString(MileState[x - 1, y]);
buttonarray[x - 1, y].FlatStyle = FlatStyle.Popup;
sign[x - 1, y] = 1;
}
else if (MileState[x - 1, y] == 0) print(x - 1, y, sign);
if (x - 1 >= 0 && y + 1 < widths && sign[x - 1, y + 1] == 0)
if (MileState[x - 1, y + 1] > 0)
{
buttonarray[x - 1, y + 1].Text = Convert.ToString(MileState[x - 1, y + 1]);
buttonarray[x - 1, y + 1].FlatStyle = FlatStyle.Popup;
sign[x - 1, y + 1] = 1;
}
else if (MileState[x - 1, y + 1] == 0) print(x - 1, y + 1, sign);
if (y - 1 >= 0 && sign[x, y - 1] == 0)
if (MileState[x, y - 1] > 0)
{
buttonarray[x, y - 1].Text = Convert.ToString(MileState[x, y - 1]);
buttonarray[x, y - 1].FlatStyle = FlatStyle.Popup;
sign[x, y - 1] = 1;
}
else if (MileState[x, y - 1] == 0) print(x, y - 1, sign);
if (y + 1 < widths && sign[x, y + 1] == 0)
if (MileState[x, y + 1] > 0)
{
buttonarray[x, y + 1].Text = Convert.ToString(MileState[x, y + 1]);
buttonarray[x, y + 1].FlatStyle = FlatStyle.Popup;
sign[x, y + 1] = 1;
}
else if (MileState[x, y + 1] == 0) print(x, y + 1, sign);
if (x + 1 < heights && y - 1 >= 0 && sign[x + 1, y - 1] == 0)
if (MileState[x + 1, y - 1] > 0)
{
buttonarray[x + 1, y - 1].Text = Convert.ToString(MileState[x + 1, y - 1]);
buttonarray[x + 1, y - 1].FlatStyle = FlatStyle.Popup;
sign[x + 1, y - 1] = 1;
}
else if (MileState[x + 1, y - 1] == 0) print(x + 1, y - 1, sign);
if (x + 1 < heights && sign[x + 1, y] == 0)
if (MileState[x + 1, y] > 0)
{
buttonarray[x + 1, y].Text = Convert.ToString(MileState[x + 1, y]);
buttonarray[x + 1, y].FlatStyle = FlatStyle.Popup;
sign[x + 1, y] = 1;
}
else if (MileState[x + 1, y] == 0) print(x + 1, y, sign);
if (x + 1 < heights && y + 1 < widths && sign[x + 1, y + 1] == 0)
if (MileState[x + 1, y + 1] > 0)
{
buttonarray[x + 1, y + 1].Text = Convert.ToString(MileState[x + 1, y + 1]);
buttonarray[x + 1, y + 1].FlatStyle = FlatStyle.Popup;
sign[x + 1, y + 1] = 1;
}
else if (MileState[x + 1, y + 1] == 0) print(x + 1, y + 1, sign);
}
}
}
五、实验结果:
1、用”×”标记雷点,用”?”标记疑问点,空白点表示周围无雷点或者该点还未点开,根据颜色区别二者。
2、游戏胜利和游戏结束显示messagebox。
3、第一次开始点击笑脸按钮,重新开始点击哭脸按钮。
4、点击开始菜单栏的子菜单栏选择游戏难度,初级、中级、高级的雷点分别为10、40、99个
(初级)
(中级)
(高级)
点击雷点,显示游戏错误,游戏结束
六、总结
通过本次实验,对c#控件和窗体有了更深入的了解,懂得如何根据各个控件的特点实现扫雷对应的功能,希望在以后能更加熟练地使用各个控件。
上一篇: 医学图像语义分割--Unet