C#编扫雷源码 08-5-02

 

C# 编扫雷源码  08-5-02
C#编扫雷源码 一2008年03月23日 星期日 21:53
 
源代码:
[Form1.CS]
using  System;
using  System.Drawing;
using  System.Collections;
using  System.ComponentModel;
using  System.Windows.Forms;
using  System.Data;

namespace  MineClearance
{
     
/// <summary>
     
/// Summary description for Form1.
     
/// </summary>

     public class Form1 : System.Windows.Forms.Form
     
{
         
private System.Windows.Forms.MainMenu mainMenu1;
         
private System.Windows.Forms.MenuItem menuItem1;
         
private System.Windows.Forms.MenuItem menuItem2;
         
private System.Windows.Forms.MenuItem menuItem3;
         
private System.Windows.Forms.MenuItem menuItem4;
         
private System.Windows.Forms.MenuItem menuItem5;
         
private System.Windows.Forms.MenuItem menuItem6;
         
private System.Windows.Forms.MenuItem menuItem7;
         
private System.Windows.Forms.MenuItem menuItem9;
         
private System.Windows.Forms.MenuItem menuItem12;
         
private System.Windows.Forms.MenuItem menuItem13;
         
private System.Windows.Forms.MenuItem menuItem14;
         
private System.ComponentModel.IContainer components;

         
private FaceControl faceControl1;
         
private MineCountControl mineCountControl1;
         
private TimerControl timerControl1;

         
private int [ , ] Mine;//==-2时,表示这个地雷已经爆炸;==-1时,代表这个位置是地雷;否则代表周围的地雷的数量
         private int [ , ] Turn;//==-1 表示这个位置已经翻开;==0 表示这个位置没有翻开;==1 表示这个位置插上红旗;
         private int BoardWidth;//宽度
         private int BoardHeight;//高度
         private uint MineCount;
         
private Point MP = new Point(00);//用来记录鼠标点击的方格
         private bool GameStartMark;//游戏开始标志
         private uint Count
         
{
             
get
             
{
                 
return MineCount;
             }

             
set
             
{
                 MineCount 
= value;
                 mineCountControl1.mineCount 
= (int)value;
             }

         }


         
public Form1()
         
{
             
//
             
// Required for Windows Form Designer support
             
//
             InitializeComponent();

             
//
             
// TODO: Add any constructor code after InitializeComponent call
             
//
             mineCountControl1 = new MineCountControl();
             faceControl1 
= new FaceControl();
             faceControl1.Click 
+= new EventHandler(ClickFace);
             timerControl1 
= new TimerControl();
             timerControl1.Rouse 
+= new EventHandler(RouseTime);
             timerControl1.rouseTime 
= 999;
             Reset(
9910);
             
this.CenterToScreen();

             
this.Controls.Add(faceControl1);
             
this.Controls.Add(mineCountControl1);
             
this.Controls.Add(timerControl1);
         }


         
/// <summary>
         
/// Clean up any resources being used.
         
/// </summary>

         protected override void Dispose( bool disposing )
         
{
             
if( disposing )
             
{
                 
if (components != null
                 
{
                     components.Dispose();
                 }

             }

             
base.Dispose( disposing );
         }


         
Windows Form Designer generated code
/// <summary>
         
/// The main entry point for the application.
         
/// </summary>

         [STAThread]
         
static void Main() 
         
{
             Application.Run(
new Form1());
         }


         
//鼠标坐标转换成雷区方格的坐标
         private Point MToA(int x, int y)
         
{
             x 
-= 13; y -= 53;
             
if(x < 0 || x > BoardWidth * 20 || y < 0 || y > BoardWidth * 20 )
             
{
                 
throw new Exception();
             }

             x 
= x / 20;
             y 
= y / 20;
             
return new Point(x , y);
         }


         
//鼠标坐标转换成雷区绝对坐标,进行坐标越界处理
         private Point MToAT(int x, int y)
         
{
             x 
= (x - 13/ 20;
             y 
= (y - 53/ 20;
             
if(x < 0) x = 0;
             
if(x > BoardWidth - 1) x = BoardWidth - 1;
             
if(y < 0) y = 0;
             
if(y > BoardHeight -1) y = BoardHeight -1;
             
return new Point(x , y);
         }


         
//判断一点是否在一区域内
         private bool InBox(System.Drawing.Rectangle rec1, System.Drawing.Point p1)
         
{
             
if( (rec1.Left <= p1.X && rec1.Top <= p1.Y) && (p1.X <= rec1.Right && p1.Y <= rec1.Bottom) ) return true;
             
else return false;
         }

        
         
//判断两区域是否交叉(有覆盖之处)
         private bool CrossBox(System.Drawing.Rectangle rec1, System.Drawing.Rectangle rec2)
         
{
             
//如果rec2有任何一个角在rec1中则视为交叉
             if( InBox(rec1, new Point(rec2.Left, rec2.Top)) == truereturn true;
             
if( InBox(rec1, new Point(rec2.Right, rec2.Top)) == truereturn true;
             
if( InBox(rec1, new Point(rec2.Left, rec2.Bottom)) == truereturn true;
             
if( InBox(rec1, new Point(rec2.Right, rec2.Bottom)) == truereturn true;

             
//如果rec1有任何一个角在rec2中则视为交叉
             if( InBox(rec2, new Point(rec1.Left, rec1.Top)) == truereturn true;
             
if( InBox(rec2, new Point(rec1.Right, rec1.Top)) == truereturn true;
             
if( InBox(rec2, new Point(rec1.Left, rec1.Bottom)) == truereturn true;
             
if( InBox(rec2, new Point(rec1.Right, rec1.Bottom)) == truereturn true;

             
if( (rec1.Left <= rec2.Left && rec2.Right <= rec1.Right) && (rec2.Top <= rec1.Top && rec1.Bottom <= rec2.Bottom) ) return true;
             
if( (rec2.Left <= rec1.Left && rec1.Right <= rec2.Right) && (rec1.Top <= rec2.Top && rec2.Bottom <= rec1.Bottom) ) return true;

             
return false;
         }


         
//画立体方框
         private void ColorBox(int x1, int y1, int x2, int y2, int PenWidth, bool Down, bool Fill, Color FillColor)
         
{
             System.Drawing.Graphics g 
= this.CreateGraphics();
             System.Drawing.Pen p 
= new Pen(Color.White, 1);//确定画笔的颜色和粗细
             for(; PenWidth > 0; PenWidth --)
             
{
                 p.Color 
= (Down == false)? Color.White: Color.Gray;
                 g.DrawLine( p, x1, y1, x2, y1);
                 g.DrawLine( p, x1, y1, x1, y2);
                 p.Color 
= (Down == false)? Color.Gray: Color.White;
                 g.DrawLine( p , x2, y2, x2, y1);
                 g.DrawLine( p , x2, y2, x1, y2);
                 x1 
++; y1 ++;
                 x2 
--; y2 --;
             }


             
if( Fill == true )     g.FillRectangle(new SolidBrush(FillColor), x1, y1, x2 - x1 + 1, y2 - y1 + 1);
         }

 
        
//自动清除无雷区
         private void ClearBoardMine(int nx, int ny)
         
{
             
if(InBox(new Rectangle(0,0,BoardWidth-1,BoardHeight-1), new Point(nx, ny)) == falsereturn;
             
if( Mine[ny, nx] == -1 || Turn[ny, nx] == -1return;
             Turn[ny, nx] 
= -1;
             ReDraw(
new Point(nx, ny), new Point(nx, ny) );
             
if( Mine[ny, nx] == 0)
             
{
                 
for(int i=ny-1; i<= ny+1; i++)
                 
{
                     
for(int j=nx-1; j<=nx+1; j++)
                     
{
                         ClearBoardMine(j, i);
                     }

                 }

             }

         }


         
//单击笑脸处理
         public void ClickFace(object sender, System.EventArgs e)
         
{
             ReStart();
         }


         
//超时处理
         public void RouseTime(object sender, System.EventArgs e)
         
{
             timerControl1.Stop();
             System.Windows.Forms.MessageBox.Show(
"时间到了,这次你输了! 没关系,别恢心,请继续努力!","游戏结束");
             ReStart();
         }


         
protected override void OnPaint(PaintEventArgs e)
         
{
             System.Drawing.Graphics g 
= e.Graphics;

             ColorBox(
00,this.ClientSize.Width, this.ClientSize.Height, 3falsefalse, Color.Gainsboro);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), 33this.ClientSize.Width - 57);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), 337this.ClientSize.Height - 5);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), this.ClientSize.Width - 9 , 37this.ClientSize.Height - 5);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), 341this.ClientSize.Width - 59);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), 3this.ClientSize.Height - 9this.ClientSize.Width - 57);
             ColorBox(
1010this.ClientSize.Width-10402truefalse, Color.Gainsboro);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), mineCountControl1.Right, 12, faceControl1.Left - mineCountControl1.Right, 27);
             g.FillRectangle(
new SolidBrush(Color.Gainsboro), faceControl1.Right, 12, timerControl1.Left - faceControl1.Right , 27);

             ColorBox(
1050this.ClientSize.Width-10this.ClientSize.Height-103truefalse, Color.Gainsboro);

             ReDraw( 
this.MToAT(e.ClipRectangle.Left, e.ClipRectangle.Top), this.MToAT(e.ClipRectangle.Right, e.ClipRectangle.Bottom) );
         }
 


         
protected override void OnMouseDown(MouseEventArgs e)
         
{
             Point p;
             
try
             
{
                 p 
= MToA(e.X, e.Y);
             }

             
catch
             
{
                 
return;
             }

             
if(Turn[p.Y, p.X] == -1 || GameStartMark == false)//方格被翻开或游戏结束
             {
                 
return;
             }

             timerControl1.Start();
             
switch(e.Button)
             
{
                 
case MouseButtons.Left:
                     faceControl1.faceState 
= FaceControl.FaceState.Startle;
                     
if(Turn[p.Y, p.X] != 1 )//未插红旗
                     {
                         DrawMine( p.X, p.Y, 
-4);
                         
//记录鼠标单击时按下的方格
                         MP.X = p.X;     MP.Y = p.Y;
                     }

                     
break;
                 
case MouseButtons.Right:
                     
if(Turn[p.Y, p.X] == 0)//未插红旗则插入红旗
                     {
                         Turn[p.Y, p.X] 
= 1;
                         mineCountControl1.mineCount 
--;
                     }

                     
else
                     
{
                         Turn[p.Y, p.X] 
= 0;
                         mineCountControl1.mineCount 
++;
                     }

                     ReDraw(p, p);
                     
break;
             }

         }


         
protected override void OnMouseUp(MouseEventArgs e)
         
{
             Point p;
             
try
             
{
                 p 
= MToA(e.X, e.Y);
             }

             
catch
             
{
                 
if(InBox(new System.Drawing.Rectangle(00, BoardWidth - 1, BoardHeight - 1), MP) == true) ReDraw(MP, MP);
                 faceControl1.faceState 
= FaceControl.FaceState.Up;
                 
return;
             }

             
if(GameStartMark == false)//如果游戏结束
             {
                 
return;
             }

             
switch(e.Button)
             
{
                 
case MouseButtons.Left:
                     
if(MP.X == p.X && MP.Y == p.Y && Turn[p.Y, p.X] != 1)//未插红旗
                     {
                         
if(Turn[p.Y, p.X] != -1 )//未被翻开
                         {
                             
if(Mine[p.Y, p.X] == 0)//如果这个位置周围没有地雷
                             {
                                 ClearBoardMine(p.X, p.Y);
//自动清除无雷区
                             }

                             
else
                             
{
                                 Turn[p.Y, p.X] 
= -1;
                                 
if(Mine[p.Y, p.X] == -1)//碰到地雷
                                 {
                                     timerControl1.Stop();
                                     Mine[p.Y, p.X] 
= -2;
                                     
//游戏结束
                                     for(int i=0; i< BoardHeight; i++)
                                     
{
                                         
for(int j=0; j< BoardWidth; j++)
                                         
{
                                             Turn[i, j] 
= -1;
                                         }

                                     }

                                     ReDraw(
new Point(00), new Point(BoardWidth-1, BoardHeight-1) );
                                     faceControl1.faceState 
= FaceControl.FaceState.Die;
                                     GameStartMark 
= false;
                                     
return;
                                 }

                                 ReDraw( p, p );
                             }

                             faceControl1.faceState 
= FaceControl.FaceState.Up;
                             
//统计游戏结果
                             int tn=0;
                             
for(int i=0; i< BoardHeight; i++)
                             
{
                                 
for(int j=0;j< BoardWidth; j++)
                                 
{
                                     
if(Turn[i,j] == -1) tn++;
                                 }

                             }

                             
if(tn == (BoardWidth * BoardHeight - MineCount) )//胜利
                             {
                                 timerControl1.Stop();
                                 System.Windows.Forms.MessageBox.Show(
"恭喜您凯旋归来!","游戏结束");
                                 ReStart();
                             }

                         }

                     }

                     
else
                     
{
                         
if(InBox(new System.Drawing.Rectangle(00, BoardWidth - 1, BoardHeight - 1), MP) == true) ReDraw(MP, MP);
                         faceControl1.faceState 
= FaceControl.FaceState.Up;
                     }

                     
break;
             }

         }

   
//重画
    private void ReDraw(Point p1, Point p2)
    
{
        
if (InBox(new Rectangle(00, BoardWidth - 1, BoardHeight - 1), p1) == false || InBox(new Rectangle(00, BoardWidth - 1, BoardHeight - 1), p2) == falsereturn;
        System.Drawing.Graphics g 
= this.CreateGraphics();
        
for (int i = p1.Y; i <= p2.Y; i++)
        
{
            
for (int j = p1.X; j <= p2.X; j++)
            
{
                
switch (Turn[i, j])
                
{
                    
case 0://未动过 
                        DrawMine(j, i, -3);
                        
break;
                    
case 1://插入红旗
                        DrawMine(j, i, -5);
                        
break;
                    
default:
                        DrawMine(j, i, Mine[i, j]);
                        
break;
                }

            }

        }

    }

    
//重画
    private void ReDraw()
    
{
        System.Drawing.Graphics g 
= this.CreateGraphics();
        System.Drawing.Rectangle rec 
= new Rectangle(00this.ClientRectangle.Right, this.ClientRectangle.Bottom);
        OnPaint(
new PaintEventArgs(g, rec));
    }

    
//重新开始
    private void ReStart()
    
{
        Reset(BoardWidth, BoardHeight, MineCount);
    }

    
//以指定的行、列和地雷数量初始化,重新开始
    private void Reset(int NWidth, int NHeight, uint NCount)
    
{
        System.Random ran 
= new Random(System.DateTime.Now.Second + (int)System.DateTime.Now.Ticks);
        BoardWidth 
= NWidth;
        BoardHeight 
= NHeight;
        Count 
= NCount;
        Mine 
= new int[NHeight, NWidth];
        Turn 
= new int[NHeight, NWidth];
        
//初始化地雷
        for (int i = 0; i < NHeight; i++)
        
{
            
for (int j = 0; j < NWidth; j++)
            
{
                Mine[i, j] 
= 0; Turn[i, j] = 0;
            }

        }

        
//生成 N 颗地雷 
        for (int i = 0; i < NCount; i++)
        
{
            
int nx, ny; do
            
{
                nx 
= ran.Next(0, NWidth); ny = ran.Next(0, NHeight);
            }

            
while (Mine[ny, nx] == -1); Mine[ny, nx] = -1;
            
//描述雷区 
            for (int j = nx - 1; j <= nx + 1; j++)
            
{
                
for (int k = ny - 1; k <= ny + 1; k++)
                
{
                    
if ((j >= 0 && j < NWidth) && (k >= 0 && k < NHeight))
                    
{
                        
if (Mine[k, j] != -1) Mine[k, j]++;
                    }

                }

            }

        }

        
this.ClientSize = new System.Drawing.Size(26 + BoardWidth * 2066 + BoardHeight * 20);
        
//设置窗体大小
        GameStartMark = true; mineCountControl1.Location = new Point(2013);
        faceControl1.Location 
= new Point(this.ClientSize.Width / 2 - 1015);
        timerControl1.Location 
= new Point(this.ClientSize.Width - 7013);
        timerControl1.Clear();
        ReDraw();
        faceControl1.faceState 
= FaceControl.FaceState.Up;
    }

    
//在指定位置画物件 
    private void DrawMine(int x, int y, int Value)
    
{
        System.Drawing.Graphics g 
= this.CreateGraphics();
        System.Drawing.Pen p 
= new Pen(Color.Black, 1);
        
//确定画笔的颜色和粗细 
        System.Drawing.Color textColor = new Color();
        x 
= 13 + x * 20; y = 53 + y * 20;
        
switch (Value)
        
{
            
case -5://画红旗   
                ColorBox(x, y, x + 19, y + 192falsetrue, Color.Gainsboro);
                g.DrawLine(p, x 
+ 8, y + 14, x + 12, y + 14);
                g.FillPolygon(
new SolidBrush(Color.Red), new Point[] new Point(x + 12, y + 11), new Point(x + 12, y + 2), new Point(x + 5, y + 7) });
                p.Width 
= 2; g.DrawLine(p, x + 5, y + 16, x + 15, y + 16);
                g.DrawLine(p, x 
+ 11, y + 11, x + 11, y + 14);
                
return;
            
case -4://画按下的区域 
                ColorBox(x, y, x + 19, y + 192truetrue, Color.Gainsboro);
                
return;
            
case -3://画未按下的区域   
                ColorBox(x, y, x + 19, y + 192falsetrue, Color.Gainsboro);
                
return;
            
case -2://画爆炸的地雷 
            case -1://画未爆炸的地雷 
                g.DrawRectangle(new Pen(System.Drawing.Color.Gray, 2), x + 1, y + 11919);
                g.FillRectangle(
new SolidBrush((Value == -2? Color.Red : Color.Gainsboro), x + 2, y + 21717);
                g.FillEllipse(
new SolidBrush(Color.Black), x + 4, y + 41212);
                g.DrawLine(p, x 
+ 4, y + 4, x + 16, y + 16); g.DrawLine(p, x + 10, y + 3, x + 10, y + 17);
                g.DrawLine(p, x 
+ 15, y + 4, x + 4, y + 15);
                g.DrawLine(p, x 
+ 3, y + 10, x + 18, y + 10);
                g.FillEllipse(
new SolidBrush(Color.White), x + 7, y + 733);
                
return;
            
default:
                
//确定字体颜色 
                switch (Value)
                
{
                    
case 0: textColor = Color.Gainsboro; break;
                    
case 1: textColor = Color.Blue; break;
                    
case 2: textColor = Color.Green; break;
                    
case 3: textColor = Color.Red; break;
                    
case 4: textColor = Color.DarkBlue; break;
                    
case 5: textColor = Color.DarkGreen; break;
                    
case 6: textColor = Color.DarkRed; break;
                    
case 7: textColor = Color.Fuchsia; break;
                    
case 8: textColor = Color.Black; break;
                }

                
//显示周围的雷数 
                g.DrawRectangle(new Pen(System.Drawing.Color.Gray, 2), x + 1, y + 11919);
                g.FillRectangle(
new SolidBrush(Color.Gainsboro), x + 2, y + 21717);
                g.DrawString(Value.ToString(), 
this.Font, new System.Drawing.SolidBrush(textColor), x + 2, y - 2);
                
return;
        }

    }

    
private void menuItem3_Click(object sender, System.EventArgs e)
    
{
        ReStart();
    }

    
private void menuItem4_Click(object sender, System.EventArgs e)
    
{
        Reset(
9910);
    }

    
private void menuItem6_Click(object sender, System.EventArgs e)
    
{
        Reset(
161640);
    }

    
private void menuItem7_Click(object sender, System.EventArgs e)
    
{
        Reset(
301699);
    }

    
private void menuItem13_Click(object sender, System.EventArgs e)
    
{
        
new Help().ShowDialog();
    }

    
private void menuItem14_Click(object sender, System.EventArgs e)
    
{
        
new About().ShowDialog();
    }

    
private void menuItem12_Click(object sender, System.EventArgs e)
    
{
        Application.Exit();
    }
}

       扫雷这个游戏我以前用Turb C做过,Dos界面,图像效果很差。而且我整整做了三个星期。这回用VS.Net重做感觉不同了,窗口编程容易了许多,做出来的效果也好了很多,几乎和Windows的扫雷差不了多少。直到现在我才明白为什么C#被称为用于编写"下一代窗口服务",由于平易近人的图形界面极大的减轻了源代码编程的负担,VS.Net可以在较短周期内开发应用程序,所开发的程序又具有良好的可移植性。我想C#至关重要的各种要素就是下面这些吧:简单 

C#中,没有C++中流行的指针。在C++中,有::、.、和->操作符,它们用于名字空间、成员和引用。对于新手来说,操作符至今仍是学习的一道难关。C#弃用其它操作符,仅使用单个操作符 "."。现在一个程序员所需要理解的就是嵌套名字的注解了。C#使用统一的类型系统,屏弃了C++多变的类型系统。这种系统充许您把各种类型作为一个对象查看,它是一个原始类型还是一个full-blown 类。和其它编程语言相比,由于加框(boxing)和消框(unboxing)的机制,把简单类型当作对象处理并不能获得性能的改善。
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值