程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> ASP編程 >> ASP技巧 >> 【基於.NET平台網絡編程入門實戰系列二】------讓單機版的掃雷跑起來【附源碼下載】

【基於.NET平台網絡編程入門實戰系列二】------讓單機版的掃雷跑起來【附源碼下載】

編輯:ASP技巧

今天的主要任務就是把單擊版的搞定,這是過渡到網絡版的必備過程。

如果沒有玩過掃雷的,建議先去體驗一下;體驗完後,自己嘗試寫出掃雷的算法;經過思考揣摩推敲才能有收獲。不建議一上來就下載源碼剖析,跟蹤代碼!

 

現在我來說下我的思路,如果有更優雅的算法,歡迎大家分享------競爭引發技術進步,分享推動技術進步!

 

【一】單機版掃雷劃為兩層

第一層為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添加雙擊事件(左右鍵一起按)!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved