不会的话复制粘贴
还不行直接上 链接:https://pan.baidu.com/s/1dzdRtTzoV7xfCGJY58tesw
提取码:rwu8
前言
因为本人还是入门的小白 所以写的代码比较乱 大佬别嘲笑 觉得适合许多小白 小白更懂小
提示:以下是本篇文章正文内容,下面案例可供参考
一、递归是什么?
一说起递归,我想每个人都不陌生。举个从小就听过的例子:从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山,山里有座庙,庙里有个和尚,和尚在讲故事,从前有座山...
参考 https://www.cnblogs.com/Pushy/p/8455862.html
二、使用步骤
1.难点思路
代码原理:使用递归 :假如点击一个格子就会判断周围八个格子有多少个地雷 然后又依次判断八个格子直到所判断到的格子附近没有地雷
代码思路难点:
递归结束条件
当到了上下左右边周围就不会有八个格子要单独判断处理
怎么判断结束赢了(我是使用判断背景颜色:如果这个格子被判断附近有多少地雷就会背景 当全部都是的话 就赢了
2.主要代码
代码如下(示例):
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;
using System.Collections;
namespace 扫雷程序
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int mine;
int time=0;
int row;//必须为row的倍数
int lin;
int chongmine = 0;
Random r = new Random();
public int[] arr;
int b; //截取后面的数字 button66
List<Button> list = new List<Button>();//按钮是从1开始的 所以后面都要减一
//现在的问题就是结果 和递归 我设置了递归次数但是那个次数只会在八个中的一个执行下去
private void Setmine(object sender, EventArgs e)
{
chongmine = mine;
List<int> b100 = new List<int>();
for (int i = 1; i <= 100; i++)
{
b100.Add(i);
}
Button button = (Button)sender;//只有点击开始才会调用此函数
for (int n = 0; n <mine; n++)
{
int mi = r.Next(1,(lin*row)+1);
int id = Array.IndexOf(arr,mi);
if (id == -1)
{
}
else
{
chongmine--;
}
arr[n] = mi;
//b100.Remove(arr[n]);方法2
//bool isa = ((IList)arr).Contains(arr[n]); 方法3
//if (isa)
//{
// n--;
//}
}
}
private void Result()
{
bool win = true;
for (int i=1; i <=lin * row; i++)//要判断的地雷序列
{
bool ifmine = false;
for (int j = 0; j < arr.Length; j++)//用来判断地雷的就自动省略这是地雷个数
{
if (i== arr[j])
{
ifmine = true;
}
}//如果有地雷可以不用底色
if (ifmine == true)
{
continue;//和下面else效果一样
}
//else {
if (list[i-1].BackColor!=Color.DarkGray)
{
win = false;
break; //其中有一个不是的话就说明没有走完
}
else
{ //list[i].Text = "淡定";
win = true;//多余是为了好看点
}
//}
}
if (win == true)
{
timer1.Enabled = false;
MessageBox.Show("恭喜你赢了呀!");
for (int u = 0; u < list.Count; u++)
{
list[u].Enabled = false;
}
for (int t = 0; t < arr.Length; t++)
{
list[arr[t] - 1].BackgroundImage = Image.FromFile("mine.gif");
list[arr[t] - 1].BackgroundImageLayout = ImageLayout.Stretch;
}
}
}
private void Picture(int count,int b)
{
if (count == 1)
{
list[b - 1].BackgroundImage = Image.FromFile("1.gif");
}
else if (count == 2)
{
list[b - 1].BackgroundImage = Image.FromFile("2.gif");
}
else if (count == 3)
{
list[b - 1].BackgroundImage = Image.FromFile("3.gif");
}
else if (count == 5)
{
list[b - 1].BackgroundImage = Image.FromFile("5.gif");
}
else if (count == 4)
{
list[b - 1].BackgroundImage = Image.FromFile("4.gif");
}
else if (count == 6)
{
list[b - 1].BackgroundImage = Image.FromFile("6.gif");
}
else if (count == 7)
{
list[b - 1].BackgroundImage = Image.FromFile("7.gif");
}
}
private void Link(int b)
{
//进来了要立刻增加 要不然下面递归会死循环
//string[] xian = new string[8];
int[] brr = { b + 1, b - (row+1), b + row, b - row, b - 1, b - (row-1), b + (row-1), b + (row+1) };//附近的 如果没有地雷就显示出来
//for (int i = 0; i <brr.Length; i++)
int d = b % row;//加这个是为了 假如点的按钮是10 那12就会到下一行取了 //{
int[] crr = { b - 1, b + row, b - row, b + (row-1), b - (row+1) }; // for (int j = 0; j <arr.Length; j++)//这是地雷
// {
int e = (b -1)% row; //这个要变了16行列 但是16和10不一样 所以要判断 (b-1)%16=0的话 这里只有17 33 等减一才能 都可以用 11减去1等于0 // if (arr[j] == brr[i])
// {//return;//不运行这个函数
int[] frr = { b + 1, b - row, b + row, b + (row+1), b - 9 }; // MessageBox.Show("有地雷");
// }
// }
//}
int count = 0;
//装附近的
//if (brr[i] <= 0 || brr[i] > 100)//如果小于0或者大于100就没有
//{
//}
//else
//{
// link(brr[i].ToString(),brr[i]);
// list[brr[i]-1].Text = "0";
// /* MessageBox.Show("0");*///改的还是这一个按钮 所以可以试试返回一个数组
//}
if (d == 0)
{
Compar(crr, count,b);
}
else if (e == 0)
{
Compar(frr, count,b);
}
else
{
Compar(brr, count,b);
}
Result();
}
private void Compar(int [] xrr,int count,int b)
{
for (int i = 0; i < xrr.Length; i++)
{
if (xrr[i] < 1 || xrr[i] > row * lin)//防止边上没有
{
}
else
{
for (int v = 0; v < arr.Length; v++)
{
if (xrr[i] == arr[v])
{
count++;
}
}
}
}
list[b - 1].BackColor = Color.DarkGray;
if (count == 0)//如果这个count等于0的话就可以在循环一次 直到不等于零就结束
{
list[b - 1].BackgroundImage = Image.FromFile("0.gif");
for (int i = 0; i < xrr.Length; i++)
{
if (xrr[i] >= 1 &&xrr[i] <= row * lin)
{
while (list[xrr[i] - 1].BackColor != Color.DarkGray)
{
Link(xrr[i]);
}
}
}
}
else
{
Picture(count,b);
}
}
private void Display(object sender, EventArgs e)
{
if (isstar == true)
{
Button button = (Button)sender;
string str = button.Name.Substring(6);
b = Convert.ToInt32(str);//截取后面的数字 button66
for (int i = 0; i < arr.Length; i++)//判断在随机地雷中是否与现在按钮相等
{
if (b == arr[i])
{
button.Text = "炸弹";
button.ForeColor = Color.Red;
button.BackgroundImage = Image.FromFile("blood.gif");
timer1.Enabled = false;
MessageBox.Show("你挂了!用时"+time+"s");
for (int t = 0; t < arr.Length; t++)
{
list[arr[t] - 1].Image = Image.FromFile("mine.gif");
}
for (int u = 0; u < list.Count; u++)
{
list[u].Enabled = false;
}
button.Image = Image.FromFile("blood.gif");
return;
}
}
//button.Text = "0";//如果不是地雷就显示0
// button.BackgroundImage = Image.FromFile("0.gif");//点击后的图片
// button.BackgroundImageLayout = ImageLayout.Stretch;
//button.BackColor = Color.DarkGray;//只要地雷打开了就是灰色 这样后面可以当作判断
Link( b);
}
else
{
MessageBox.Show("请开始游戏");
}
}
private void Board()
{
int i;
int x = 0, y = 80;
for (i = 1; i <= row * lin; i++)
{
Button bt = new Button();
string a = i.ToString();
bt.Name = "button" + a;
bt.Size = new Size(25, 25);
bt.Location = new Point(x, y);
this.Controls.Add(bt);
list.Add(bt);
x += 25;
bt.BackColor = Color.Silver;
bt.BackgroundImage = Image.FromFile("blank.gif");
bt.BackgroundImageLayout = ImageLayout.Stretch;
if (i % lin == 0)
{
x = 0;
y += 25;
}
bt.Click += Display;
bt.KeyPress += q;
bt.MouseMove += Float;
bt.MouseDown += MouseRight;
}
}
int l = 1;
private void MouseRight(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)//判断是否是右键
{
l++;
Button bt = (Button)sender;
if (l % 2 == 0)
{
bt.Image = Image.FromFile("flag.gif");
}
else
{
bt.Image = null;
}
}
}
private void Bt_MouseDown(object sender, MouseEventArgs e)
{
throw new NotImplementedException();
}
private void Float(object sender, MouseEventArgs e)
{
}
int ll;
private void q(object sender, KeyPressEventArgs e)
{
ll++;
Button bt = (Button)sender;
if (l % 2 == 0)
{
bt.Image = Image.FromFile("d0.gif");
}
else
{
bt.Image = null;
}
}
bool isstar = true;
private void button1_Click(object sender, EventArgs e)
{
arr = new int[mine];
Setmine(sender, e);//设置地雷
//for (int i = 0; i < arr.Length; i++)
//{
// list[arr[i] - 1].Image = Image.FromFile("mine.gif");
//}
//for (int n = 0; n< 10; n++)
//{
// MessageBox.Show(arr[n].ToString()); }
if (isstar==true)
{
MessageBox.Show("请选择难度");
}
if(comboBox1.Enabled==false)
{
button1.Enabled = false;
isstar = true;
timer1.Enabled = true;
}
chongmine = mine - chongmine;
label2.Text ="实际雷:" +mine+"颗\n重复雷: " + chongmine+"颗";
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.SelectedIndex == 0)
{
row = 10;
lin = 10;
mine = 10;
Board();
comboBox1.Enabled = false;
}
else if (comboBox1.SelectedIndex == 1)
{
row = 16;
lin = 16;
mine = 40;
Board();
comboBox1.Enabled = false;
}
else if (comboBox1.SelectedIndex == 2)
{
row = 30;
lin = 30;
mine = 300;
Board();
comboBox1.Enabled = false;
}
groupBox1.Width = this.ClientSize.Width;
isstar = false;
button1.PerformClick();
}
private void button2_Click(object sender, EventArgs e)
{
this.Hide();
Form1 fm = new Form1();
fm.Show();
}
private void button3_Click(object sender, EventArgs e)
{
Dispose();
Application.Exit();
Application.ExitThread();
}
private void button4_Click(object sender, EventArgs e)
{
MessageBox.Show("1.鼠标右键插旗子 两下取消\n2.长按鼠标左键然后再按q键表明两颗以上的雷\n3.重复雷是一个位置有两颗雷比普通扫雷难一点");
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
int sec=0;
private void timer1_Tick(object sender, EventArgs e)
{
time++;
if (time>60)
{
sec=time/60;
label3.Text = "时间:" + sec + ":" + (time % 60)+"s";
}
else
{
label3.Text = "时间:" + time + "s";
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
void Form1_Resize(object sender, EventArgs e)
{
}
}
}
总结
摸索摸索摸索 !!!!!!!!!!!!
中间还有很多可以优化的地方,比如将扫雷的逻辑代码抽离Form类独立出来等,这些都靠读者自行去优化了。还有为了提高难度我设置了重复雷 就是随机产生雷的时候一个格子有可能不止一个雷 修改的话很简单