WEB开发网
开发学院WEB开发ASP 【基于.NET平台网络编程入门实战系列二】----... 阅读

【基于.NET平台网络编程入门实战系列二】------让单机版的扫雷跑起来【附源码下载】

 2010-01-06 10:43:14 来源:WEB开发网   
核心提示:今天的主要任务就是把单击版的搞定,这是过渡到网络版的必备过程,【基于.NET平台网络编程入门实战系列二】------让单机版的扫雷跑起来【附源码下载】,如果没有玩过扫雷的,建议先去体验一下;体验完后,但也是扫雷的核心算法, 【三】遍历周围8格代码 1 private void CheckLable(int x, in
今天的主要任务就是把单击版的搞定,这是过渡到网络版的必备过程。

如果没有玩过扫雷的,建议先去体验一下;体验完后,自己尝试写出扫雷的算法;经过思考揣摩推敲才能有收获。不建议一上来就下载源码剖析,跟踪代码!



现在我来说下我的思路,如果有更优雅的算法,欢迎大家分享------竞争引发技术进步,分享推动技术进步!



【一】单机版扫雷划为两层

第一层为Button,Button盖在Lable上,Lable被隐藏在Button下面;

第二层为Lable, Lable上的背景图片改成地雷图案表示有雷。

雷区的大家我定为20*20.

    PRivate const int Xcount = 20;
    private const int Ycount = 20;
添加Lable的代码如下:

代码
1 private Label[] labels2 = new Label[Xcount * Ycount];
2 private Label[,] labels = new Label[Xcount, Ycount];
3     int indexOfLable = 0;
4     private void CreateLable()
5     {
6       int[] ints = new int[400];
7       Random rd = new Random();
8       for (int i = 0; i < 400; i++)
9       {
10        
11         ints[i] = rd.Next(1, 400);
12       }
13       for (int i = 0; i < Xcount; i++)
14       {
15         for (int j = 0; j < Ycount; j++)
16         {
17           Label lb = new Label();
18           lb.Location = new Point(i * 30, 30 * j);
19           lb.Size = new Size(30, 30);
20           lb.BorderStyle = BorderStyle.Fixed3D;
21           this.Controls.Add(lb);
22           labels[i, j] = lb;
23           labels2[indexOfLable] = lb;
24           indexOfLable++;
25         }
26       }
27       for (int i = 0; i < ints.Length; i++)
28       {
29         if (ints[i] < 40)
30         {
31           labels2[i].Image = Properties.Resources.标准地雷;
32         }
33       }
34     }


添加Button的代码如下:

代码
1  private Button[,] buttons = new Button[Xcount, Ycount];   
2     private void AddButton()
3     {
4       for (int i = 0; i < Xcount; i++)
5       {
6         for (int j = 0; j < Ycount; j++)
7         {
8           Button btn = new Button();
9           btn.Click += new EventHandler(btn_Click);
10           //btn.Click +=new EventHandler(btn_MouseDown);
11           btn.MouseUp += new MouseEventHandler(btn_MouseUp);
12           btn.Location = new Point(i * 30, 30 * j);
13           btn.Size = new Size(30, 30);
14           this.Controls.Add(btn);
15           //利用Tag使按钮和坐标建立联系
16           Point pt = new Point(i, j);
17           btn.Tag = pt;
18           buttons[i, j] = btn;
19         }
20       }
21     }


实现按钮注册的事件,代码如下:

代码
1  void btn_MouseUp(object sender, MouseEventArgs e)
2     {
3       if (e.Button == MouseButtons.Right)
4       {
5         Button btn = (Button)sender;
6         if (btn.BackgroundImage == null)
7         {
8           btn.BackgroundImage = Properties.Resources.挖雷工兵;
9         }
10         else
11         {
12           btn.BackgroundImage = null;
13         }
14       }
15     }
16
17
18 void btn_Click(object sender, EventArgs e)
19     {
20       Button btn = (Button)sender;
21       this.Controls.Remove(btn);
22       Point pt = (Point)btn.Tag;
23       x = pt.X;
24       y = pt.Y;
25       if (labels[x, y].Image != null)
26       {
27         MessageBox.Show("游戏结束,果然是踩雷高手");
28         ReStart();
29         return;
30       }
31       CheckLable(x, y);
32     }




单击Button按钮判断在其下面的Lable上的图像是否为地雷,图像为空------递归寻找,图像不为空------游戏失败!

代码
1   void btn_Click(object sender, EventArgs e)
2     {
3       Button btn = (Button)sender;
4       this.Controls.Remove(btn);
5       Point pt = (Point)btn.Tag;
6       x = pt.X;
7       y = pt.Y;
8       if (labels[x, y].Image != null)
9       {
10         MessageBox.Show("游戏结束,果然是踩雷高手");
11         ReStart();
12         return;
13       }
14       CheckLable(x, y);
15     }




【二】单击的后果

这里是指左键的单击,右键的很简单,仅仅改变一下Button的背景图片而已,表示你任务下面有地雷。

左键单击后------1.移除被单击的按钮(大家都知道!)

1  void btn_Click(object sender, EventArgs e)
2     {
3       Button btn = (Button)sender;
4       this.Controls.Remove(btn);
5     }




       ------2.判断周围8格有没有雷,如果有---计算出有多少个,显示在lable上,并且自动判断周围的8格中没有地雷的单格的周围8格是否有地雷,一直递归下去!

                           如果没有---则移除周围8个button,并自动判断周围的8格的周围8格是否有地雷,一直递归下去!

上面两句虽然很绕口,但也是扫雷的核心算法。



【三】遍历周围8格

代码
1   private void CheckLable(int x, int y)
2     {
3       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
4       {
5         num = 0;
6         num = GetCount(x, y);
7         if (num == 8)
8         {
9           num = 0;
10           string tag = buttons[x, y].Tag.ToString();
11           buttons[x, y].Tag = 0;
12           if (labels[x, y].Image == null && tag != "0")
13           {
14             x++;
15             RemoveButton(x, y);
16             y++;
17             RemoveButton(x, y);
18             x--;
19             RemoveButton(x, y);
20             x--;
21             RemoveButton(x, y);
22             y--;
23             RemoveButton(x, y);
24             y--;
25             RemoveButton(x, y);
26             x++;
27             RemoveButton(x, y);
28             x++;
29             RemoveButton(x, y);
30             if (tag != "0")
31             {
32               num = 0;
33               Recursion(x, y);
34             }
35           }
36         }
37         else
38         {
39           if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
40           {
41             labels[x, y].Text = (8 - num).ToString();
42
43             num = 0;
44             return;
45           }
46         }
47       }
48     }




【四】计算雷的个数

代码
1  private int GetCount(int x, int y)
2     {
3
4       temp2 = 0;
5       x++;
6       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
7       {
8         if (labels[x, y].Image == null)
9         {
10           temp2++;
11         }
12       }
13       else
14       { temp2++; }
15
16       y++;
17       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
18       {
19         if (labels[x, y].Image == null)
20         {
21           temp2++;
22         }
23       }
24       else
25       { temp2++; }
26
27       x--;
28       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
29       {
30         if (labels[x, y].Image == null)
31         {
32           temp2++;
33         }
34       }
35       else
36       { temp2++; }
37       x--;
38       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
39       {
40         if (labels[x, y].Image == null)
41         {
42           temp2++;
43         }
44       }
45       else
46       { temp2++; }
47       y--;
48       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
49       {
50         if (labels[x, y].Image == null)
51         {
52           temp2++;
53         }
54       }
55       else
56       { temp2++; }
57       y--;
58       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
59       {
60         if (labels[x, y].Image == null)
61         {
62           temp2++;
63         }
64       }
65       else
66       { temp2++; }
67       x++;
68       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
69       {
70         if (labels[x, y].Image == null)
71         {
72           temp2++;
73         }
74       }
75       else
76       { temp2++; }
77       x++;
78       if (x < Xcount && x >= 0 && y >= 0 && y < Ycount)
79       {
80         if (labels[x, y].Image == null)
81         {
82           temp2++;
83         }
84       }
85       else
86       { temp2++; }
87
88       return temp2;
89     }


  

【五】递归

代码
1  private void Recursion(int x, int y)
2     {
3       CheckLable(x, y);
4       y++;
5       CheckLable(x, y);
6       y++;
7       CheckLable(x, y);
8       x--;
9       CheckLable(x, y);
10       x--;
11       CheckLable(x, y);
12       y--;
13       CheckLable(x, y);
14       y--;
15       CheckLable(x, y);
16       x++;
17       CheckLable(x, y);
18
19     }




【六】重新来一盘

代码
1  public void ReStart()
2     {
3       this.Controls.Clear();
4       InitializeComponent();
5       temp2 = 0;
6       x = 0;
7       y = 0;
8       indexOfLable = 0;
9       num = 0;
10       AddButton();
11       CreateLable();
12     }




留两件事情给大家做,一改成用户控件,二给Lable添加双击事件(左右键一起按)!源码下载 ==> /Files/zhanglei644213943/单机版扫雷.rar

Tags:基于 NET 平台

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接