• 单机版扫雷



    今天的主要任务就是把单击版的搞定,这是过渡到网络版的必备过程。

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

     

     

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

    第一层为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(1400);
    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 * 3030 * j);
    19                     lb.Size = new Size(3030);
    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 * 3030 * j);
    13                     btn.Size = new Size(3030);
    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个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

  • 相关阅读:
    苹果MAC OS查看MAC地址及修改ip
    win10系统绑定本地IP和mac地址
    CentOS7 配置阿里云yum源,非常之简单
    Prism框架研究(一)
    如何建立一个WCF服务并将其发布到IIS上
    SQL Server2012如何导出sql脚本并且还原数据库
    WPF设置软件界面背景为MediaElement并播放视频
    一个加载时带动画效果的ListBoxItem
    无法将从VSS中的解决方案添加到TFS的源代码管理器中
    关于WPF中Popup中的一些用法的总结
  • 原文地址:https://www.cnblogs.com/iamzhanglei/p/1639899.html
Copyright © 2020-2023  润新知