⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form1.cs

📁 自己设计的扫雷 大家可以玩玩 蛮有意思的
💻 CS
📖 第 1 页 / 共 2 页
字号:
		private void makeRandomData()
		{
			Random rand = new Random();         //用于产生雷区分步
			int i;   //用于标记产生有雷区域的行下标
			int j;   //用于标记产生有雷区域的列下标

			//产生BombNumber个地雷
			for( int k = 0; k < BombNumber; k++ )
			{
				i = rand.Next( 1, 20 );   //产生有雷区域的行下标
				j = rand.Next( 1, 20 );   //产生有雷区域的列下标

				if( bombs[i,j] == 0xFF )      //表示该区域已经设置有雷,需要重新设置其他区域
					k--;
				else
					bombs[i,j] = 0xFF;
			}

			//用于计算每个雷区bombs[i,j]附近的地雷数
			for( i = 1; i < 21; i ++ )
				for( j = 1; j < 21; j++ )
				{
					//对于每个无雷区域,对其周围8个区域进行监测
					if( bombs[i,j] != 0xFF )
					{
						for( int m = -1; m < 2; m ++ )
							for( int n = -1; n < 2; n++ )
							{
								//如果发现周围有雷区域,bombs[i,j]的值加1
								if( bombs[ i + m, j +n ] == 0xFF )
									bombs[i,j]++;
							}
					}
				}
		}

		//对鼠标弹起事件的处理
		private void Form1_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			//如果游戏可以开始,则开始该游戏,并且开始用计时器计时
			if( !timer.Enabled && gameReady && !gOver)
			{
				timer.Enabled = true;
			}
			
			//左键起
			if( e.Button == MouseButtons.Left )
			{
				//触雷,游戏结束
				if( this.bombs[arrayX,arrayY] == 0xFF )
				{
					gameOver();
				}

				//该雷区无雷,显示附近雷区雷数
				else if( bombs[arrayX,arrayY] == 0 )
				{
					if( bombState[arrayX,arrayY] == 0 )
					    banging( arrayX, arrayY );
				}

				//该雷区附近无雷,显示附近所有无雷区
				else
				{
					fillBombArea( eventX, eventY, arrayX, arrayY, 2 );
				}
			}
			
			//其他键起并且游戏已经开始
			else if( e.Button == MouseButtons.Right && gameReady  && !gOver)
			{
				//如果该区域已经判定为有雷区,用户再次用鼠标单击,将状态修改为可能有雷区
				if( bombState[arrayX,arrayY] == 0x02 )
				{
					//fillType为4,有雷区变为可能的有雷区
					fillBombArea( eventX, eventY, arrayX, arrayY, 4 );
				}

				//该区域已标志为可能有雷区域,如果玩家再次用右键单击,将状态改为未判定状态
				else if( bombState[arrayX,arrayY] == 0x03 )
				{
					//fillType为5,转变为未判定区
					fillBombArea( eventX, eventY, arrayX, arrayY, 5 );
				}

				//该区域为未判定作态,如果玩家用右键单击,将作态改为用户判定的有雷区状态
				else if( bombState[arrayX,arrayY] == 0 )
				{
					fillBombArea( eventX, eventY, arrayX, arrayY, 3 );
				}
			}

		}

		//游戏结束,向玩家显示所有有雷区域的位置
		private void gameOver()
		{
			int i; //标志行坐标
			int j; //标志列坐标
			
			//对于每个有雷区域,用黑色标志
			for( i = 1; i < 21; i++ )
				for( j = 1; j < 21; j++ )
				{
					if( bombs[i,j] == 0xFF && bombState[i,j] == 0 )
					{
						this.fillBombArea( ( i - 1 ) * 20 + 2 , ( j - 1 ) * 20 + 2, i, j, 7 );
					}
				}
			//停止计时器
			timer.Enabled = false;
			//游戏未开始
			gameReady = false;
			//游戏已经结束
			gOver = true;
		}

		//玩家开始游戏
		private void mnuBegin_Click(object sender, System.EventArgs e)
		{
			this.replay();
		}

		//玩家重新开始游戏,对游戏重新进行初始化
		private void replay()
		{
			Refresh();
			Pen pen = new Pen( Color.Goldenrod, 4 );              //用于绘制边界
			//重新绘制雷区
			for( int i = 0; i <= 400; i += 20 )
			{
				g.DrawLine( pen, 0, i, 400, i );
				g.DrawLine( pen, i, 0, i, 400 );
			}
			//计时器重新置0
			time = 0;
			//向玩家显示当前时间
			lbTime.Text = time.ToString();
			//显示本次游戏的地雷个数
			lbBombNum.Text = BombNumber.ToString();
			//记忆实际剩余地雷个数
			rightCheck = BombNumber;
			//用户判定的剩余个数
			userCheck = BombNumber;
			this.btnReplay.Text = "重新开始";
			//计时器尚未开始
			timer.Enabled = false;
			//将地雷数组重新初始化为0
			Array.Clear( this.bombs, 0, this.bombs.Length );
			//将雷区状态重新初始化为0
			Array.Clear( this.bombState, 0, this.bombState.Length );
            //产生雷区
			makeRandomData();
			//初始化完毕,可以开始游戏
			gameReady = true;
			//游戏尚未结束
			gOver = false;
		}

		//用户点击附近无雷区域,显示所有周围为无雷的区域
		private void banging( int x, int y )
		{
			fillBombArea( ( x - 1) * 20 + 2, ( y - 1 ) * 20 + 2, x, y, 1 );

			//处理右方雷区情况
			if( x + 1 < 21)   //如果不是最右方
			{
				//如果该区域附近也无雷,则递规
				if( bombs[ x + 1, y ] == 0 && bombState[ x + 1, y ] == 0 )
					banging( x + 1, y );
				//如果该区域附近有雷
				else if( bombs[ x + 1, y] < 0xFF  && bombState[ x + 1, y ] == 0 )
				{
					fillBombArea( x * 20 + 2, ( y - 1 ) * 20 + 2, x + 1, y, 2 );
				}
			}

			//对左方雷区的处理
			if( x - 1 > 0 )    //如果不是最左方
			{
				//如果该区域附近也无雷,则递规
				if( bombs[ x - 1, y ] == 0  && bombState[ x - 1, y ] == 0 )
					banging( x - 1, y );
				//如果该区域附近有雷
				else if( bombs[ x - 1, y ] < 0xFF && bombState[ x - 1, y ] == 0 )
				{
					fillBombArea( ( x - 2 ) * 20 + 2, ( y - 1 ) * 20 + 2, x - 1, y, 2 );
				}
			}

			//对上方雷区的处理
			if( y - 1 > 0 )   //如果不是最上方
			{
				//如果该区域附近也无雷,则递规
				if( bombs[ x, y - 1] == 0  && bombState[ x, y - 1] == 0 )
					banging( x, y -1 );
				//如果该区域附近有雷
				else if( bombs[ x, y - 1 ] < 0xFF  && bombState[ x, y - 1] == 0 ) 
				{				
					fillBombArea( ( x - 1) * 20 + 2, ( y - 2 ) * 20 + 2, x, y - 1, 2 );
				}
			}

			//对下方雷区的处理
			if( y + 1 < 21 )   //如果不是最下方
			{
				//如果该区域附近也无雷,则递规
				if( bombs[ x, y + 1] == 0  && bombState[ x, y + 1] == 0 )
					banging( x, y + 1 );
				//如果该区域附近有雷
				else if( bombs[ x, y + 1 ] < 0xFF && bombState[ x, y + 1] == 0)
				{
					fillBombArea( ( x - 1) * 20 + 2, y * 20 + 2, x, y + 1, 2 );
				}
			}
		}

		//用户选择中级难度
		private void mmuMiddle_Click(object sender, System.EventArgs e)
		{
			BombNumber = 60; //地雷数为60
			rightCheck = 60; //实际剩余的地雷数为60
			userCheck =60;   //用户判定的剩余地雷数为60
			lbBombNum.Text = this.BombNumber.ToString();  //向用户显示判定的剩余地雷数
			mnuBegenner.Checked = false;  //未选定初级
			mmuAdvanced.Checked = false;  //未选定高级
			mmuMiddle.Checked = true;     //选定了中级
			//重新开始游戏
			this.replay();
		}

		private void mnuBegenner_Click(object sender, System.EventArgs e)
		{
			BombNumber = 40;
			rightCheck = 40;
			userCheck = 40;
			lbBombNum.Text = this.BombNumber.ToString();
			mnuBegenner.Checked = true;
			mmuAdvanced.Checked = false;
			mmuMiddle.Checked = false;
			replay();
		}

		private void mmuAdvanced_Click(object sender, System.EventArgs e)
		{
			this.BombNumber = 80;
			this.lbBombNum.Text = this.BombNumber.ToString();
			this.mnuBegenner.Checked = false;
			this.mmuAdvanced.Checked = true;
			this.mmuMiddle.Checked = false;
			this.rightCheck = 80;
			this.userCheck = 80;
			this.replay();
		}

		private void btnReplay_Click(object sender, System.EventArgs e)
		{
			this.replay();
		}

		private void timer_Tick(object sender, System.EventArgs e)
		{
			time++;
			this.lbTime.Text = time.ToString();
		}

		private void menuItem6_Click(object sender, System.EventArgs e)
		{
			MessageBox.Show("左键点击你认为没有地雷的雷区\n右键点击你认为有雷的雷区\n右键点击标志有雷的雷区后,该区域显示“?”表示不能确定\n右键点击“?”雷区取消判定\n右键点击已经判定的无雷区,如果该雷区附近所有地雷都\n标志过,则自动翻开未判定雷区",
               "玩法帮助",MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		private void menuItem7_Click(object sender, System.EventArgs e)
		{
			MessageBox.Show("  游戏名称:飞天扫雷   \n  版本:V1.2   2005-4-11   \n  作者:冯东伟   ", "关于飞天",MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		private void mmuExit_Click(object sender, System.EventArgs e)
		{
			this.Close();
		}

		//雷区填充函数
		//xCo表示要填充区域的左上X坐标
		//yCo表示要填充区域的左上Y坐标
		//xArr表示雷区对应的数组行下标
		//yArr表示雷区对应的数组列下标
		//fillType表示填充类型
		private void fillBombArea( int xCo, int yCo, int xArr, int yArr, int fillType)
		{
			switch ( fillType )
			{
				case 1: 
				{
					//附近无雷的无雷区,仅用绿色刷子填充该区域
					SolidBrush greenBrush = new SolidBrush( Color.Green );   //绿刷子,用于标志玩家已打开的区域
					g.FillRectangle( greenBrush, xCo, yCo, 16, 16 ); 
					bombState[xArr,yArr] = 0x01;
					break;            
				}
				case 2:                 //附近有雷的无雷区,用绿色刷子填充该区域,并显示附近雷区地雷数
				{
					SolidBrush greenBrush = new SolidBrush( Color.Green );   //绿刷子,用于标志玩家已打开的区域
					//用绿色刷子填充太雷区,表示无雷
					g.FillRectangle( greenBrush,  xCo, yCo, 16, 16 );
					SolidBrush stringBrush = new SolidBrush( Color.Yellow );   //灰刷子,用于书写附近雷区地雷数
					//显示附近雷区的地雷个数
					g.DrawString( bombs[xArr,yArr].ToString(), new Font("Times New Roman",12), stringBrush,  xCo, yCo );
					//标志该状态已经正确判断为无雷区
					bombState[xArr,yArr] = 0x01;
					break;
				}
				case 3:                 //用户标志的有雷区,仅用蓝色刷子填充该区域
				{
					SolidBrush blueBrush = new SolidBrush( Color.Blue );  //蓝刷子,用于标志玩家判定有雷区
					//用蓝色刷子标志该区域为有雷区
					g.FillRectangle( blueBrush, xCo, yCo, 16, 16 );
					//将作态改为用户判定的有雷区
					bombState[xArr,yArr] = 0x02;
					--userCheck;
					lbBombNum.Text = userCheck.ToString(); 
					if( bombs[xArr,yArr] == 0xFF )
						rightCheck--;
					if( rightCheck == 0 )
					{
						btnReplay.Text = "您赢了!";
						gOver = true;
						timer.Enabled = false;
					}
					break;     
				}
				case 4:                 //用户判定的可能有雷区,用问号标志
				{
					//由已判定变为不能判定,实际剩余的雷区个数加1
					rightCheck ++;
					//由已判定变为不能判定,用户判定的雷区剩余个数加1
					userCheck++;
					//向玩家显示玩家判定的还剩余的地雷个数
					lbBombNum.Text = userCheck.ToString();
					//显示"?",提醒玩家
					SolidBrush stringBrush = new SolidBrush( Color.Yellow );   //灰刷子,用于书写附近雷区地雷数
					g.DrawString( "?",new Font("Times New Roman",12), stringBrush, xCo, yCo );
					bombState[xArr,yArr] = 0x03;
					break;
				}
				case 5:                 //用户将该区域设置为未判定区域
				{
					SolidBrush backBrush = new SolidBrush( Color.FromArgb(255,255,200) ); //背景刷子,用于恢复状态
					//用背景刷子填充,回复为未判定状态
					g.FillRectangle( backBrush, xCo, yCo, 16, 16 );
					//除去显示的"?"
					g.DrawString( "?",new Font("Times New Roman",12), backBrush, xCo, yCo );
					//将该雷区状态该为未判定状态
					bombState[xArr,yArr] = 0;
					break;
				}
				case 6:                 //用户按下鼠标,用红色提示用户点击的雷区
				{
					SolidBrush redBrush = new SolidBrush( Color.Red ); //红刷子,用于显示玩家左键按下的雷区
					g.FillRectangle( redBrush, xCo, yCo, 16, 16 );
					break;
				}
				case 7:                 //玩家失败后,用黑色标识所有有雷区域
				{
					SolidBrush blackBrush = new SolidBrush( Color.Black ); //黑刷子,用于显示玩家左键按下的雷区
					g.FillRectangle( blackBrush, xCo, yCo, 16, 16 );
					break;
				}
			}
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -