using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace _2扫雷
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
//在外面定义一个变量,用来循环10次,原因是行循环10次,列循环10次
int rows = 10;
//随机数
Random r = new Random();
//这个二维数组分别放行和列
int[,] mines;
//放图片的数组
Image[,] images;
//在外面定义一个判断值 //当前位置默认为false
bool[,] overList;
//定义10个炸弹
int mineCount = 10;
//计时器
DispatcherTimer timer = new DispatcherTimer();
//时间倒数
int num = 60;
//按钮记时
Button kaishi = new Button();
//记录步数
Label Puji = new Label();
//记录步数
int x = 0;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
/* for (int i = 0; i < rows; i++)
{
//把网格的行和列分成10*10的格子
//创建行数
RowDefinition row = new RowDefinition();
GameBG.RowDefinitions.Add(row);
//创建列数
ColumnDefinition column = new ColumnDefinition();
GameBG.ColumnDefinitions.Add(column);
}
//表示网格的线是否显示显示
GameBG.ShowGridLines = true;*/
Ge();
//创建一个方法,用这个方法显示每个格子的东西显示
InitialGame();
//计时器
// DispatcherTimer timer = new DispatcherTimer();
//timer.Start();
timer.Interval = TimeSpan.FromMilliseconds(1000);
timer.Tick += Timer_Tick;
/*//按钮记时
Button kaishi = new Button();*/
kaishi.Width = 200;
kaishi.Height = 100;
kaishi.Content = "开始游戏";
kaishi.FontSize = 30;
//表示把某个东西放在网格的那个具体格子
Grid.SetColumn(kaishi, 1);
Grid.SetRow(kaishi, 2);
DA.Children.Add(kaishi);
kaishi.Click += Kaishi_Click;
/* //记录步数
Label Puji = new Label();*/
Puji.FontSize = 15;
Puji.Content = "记录第" + x + "步";
Puji.Margin = new Thickness(100,35,0,0);
SK.Children.Add(Puji);
}
Label jifen = new Label();//这样指改变指不会创建多个
private void Timer_Tick(object sender, EventArgs e)
{
/*Label jifen = new Label();*/
num--;
jifen.Content = "还剩" + num + "秒后结束";
jifen.FontSize = 15;
//设置外边距,上下左右距离
jifen.Margin = new Thickness(230,-30,0,0);
//不能放在这里,原因是每次回创建多个GameBG,所以里面含又多个
//GameBG.Children.Add(jifen);
if (num <= 1)
{
num =1;
//MessageBox.Show("游戏时间到了");
MessageBoxResult YX=MessageBox.Show("游戏时间到了,是否从新开始","警示", MessageBoxButton.YesNo,MessageBoxImage.Question);
x = -1;
if (YX==MessageBoxResult.Yes)
{
x++;
Puji.Content = "记录第" + x + "步";
num = 60;
timer.Start();
GameBG.Children.Clear();//先清除
//SK.Children.Add(jifen);//每添加一次,就直接放进去
//Ge();//先把每个格子从新放入
InitialGame();//从新调用
}
else
{
//关闭页面
this.Close();
}
}
}
private void Kaishi_Click(object sender, RoutedEventArgs e)
{
timer.Start();
SK.Children.Add(jifen);//每添加一次,就直接放进去
DA.Children.Remove(kaishi);
}
//总的网格数
private void Ge()
{
for (int i = 0; i < rows; i++)
{
//把网格的行和列分成10*10的格子
//创建行数
RowDefinition row = new RowDefinition();
GameBG.RowDefinitions.Add(row);
//创建列数
ColumnDefinition column = new ColumnDefinition();
GameBG.ColumnDefinitions.Add(column);
}
//表示网格的线是否显示显示
GameBG.ShowGridLines = true;
}
private void InitialGame()
{
//把每个网格的行和列放在mines数组里
mines = new int[rows, rows];
//给每个图片添加网格
images = new Image[rows, rows];
//当前位置默认为全是false
overList = new bool[rows, rows];
//用1数字来记录10个炸弹
for (int i = 0; i < mineCount; i++)//循环10次炸弹
{
//GetLength表示指定元素的索引
//随机出网格0代表行,1来表列
int row = r.Next(0,mines.GetLength(0));
int colmun = r.Next(0,mines.GetLength(1));
//表示当行和列,标记==1,这个的值==1
//当记录数字等于等于1时候表示以及记录过了,所以i循环的时候i--回去,从新随机,else不等于记录的数组时就为1
if (mines[row,colmun]==1)
{
i--;
}
else
{
mines[row, colmun] = 1;
}
}
//初始情况下所有的Image全部装zhuan
for (int i = 0; i < mines.GetLength(0); i++)//控制行
{
for (int j = 0; j < mines.GetLength(1); j++)//控制列
{
//实例化一下图片
images[i, j] = new Image();
//然后给每个位置添加图片
images[i, j].Source = new BitmapImage(new Uri("img/zhuan.gif", UriKind.Relative));
//每个小格子的间距
images[i, j].Margin = new Thickness(2,2,2,2);
//附加属性设置为指定的对象,把这个图片添加到指定的x,y的具体位置上
Grid.SetRow(images[i,j],i);//把每个图片放在每个对应图片
Grid.SetColumn(images[i,j],j);//把图片平铺
//给每个图片定义一个tag值,用一个数组定义,索引0,1
//如果给成具体数字表示这张图片的tag值是什么数字代表
images[i, j].Tag = new int[2] { i, j };
//把每个图片添加到GameBG里面
GameBG.Children.Add(images[i, j]);
//鼠标的左键
images[i, j].MouseLeftButtonDown += MainWindow_MouseLeftButtonDown;
//鼠标的右键
images[i, j].MouseRightButtonDown += MainWindow_MouseRightButtonDown;
}
}
}
//鼠标右键,表示有雷放个旗子
private void MainWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
//因为是局部变量,所以想要获取image具体的图片要用一个具体的事件触发者,谁创建的这个事件谁就是事件触发者
Image img = sender as Image;
//添加红旗图片
img.Source = new BitmapImage(new Uri("img/qizi.gif", UriKind.Relative));
}
//鼠标左键
private void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//因为是局部变量,所以想要获取image具体的图片要用一个具体的事件触发者,谁创建的这个事件谁就是事件触发者
Image img = sender as Image;
//获取图片的tag值,类型是数组
int[] index=img.Tag as int[];
x++;
Puji.Content = "记录第" + x + "步";
//点击的这个是一个安全地区
//首先在执行这里时,在外面定义一个bool,用形参来判断满足的条件IsMine
//IsMine(index[0],index[1]);
if (!IsMine(index[0], index[1]))//true//返回不正确时进入//判断雷数
{
//要判断周围的地雷数,基本上所有的雷周围至少有3个,最多有8个相邻
//假设当前这个是i,j,则需要考虑周围的(i-1,j),(i-1,j-1),(i,j-1),(i+1,j-1),(i+1,j),(i+1,j+1),(i,j+1),(i-1,j+1)
//int count = CountMine(index[0], index[1]);\
//调用x,y具体图片的位置tagzhi
CountMine(index[0], index[1], img);//放雷数
//判断剩下格子数量
int left = 0;
for (int i = 0; i < overList.GetLength(0); i++)
{
for (int j = 0; j < overList.GetLength(1); j++)
{
if (overList[i, j] == false)
{
left++;
}
}
}
if (left == mineCount)
{
MessageBoxResult SL=MessageBox.Show("获胜,是否进行下一关","闯关成功", MessageBoxButton.YesNo, MessageBoxImage.Question);
x = -1;
if (SL==MessageBoxResult.Yes)
{
x++;
Puji.Content = "记录第" + x + "步";
//从新下一关倒数从新开始记录
num = 60;
GameBG.Children.Clear();
//先清除行和列
GameBG.RowDefinitions.Clear();
GameBG.ColumnDefinitions.Clear();
GameBG.Children.Clear();
//然后给增加行和列
rows += 5;
mineCount += 5;
//然后在清除整个页面的内容
//调用网格数
Ge();
//调用图片
InitialGame();
}
else
{
GameBG.Children.Clear();
//调用网格数
Ge();
//调用图片
InitialGame();
}
}
}
else
{
for (int i = 0; i < mines.GetLength(0); i++)
{
for (int j = 0; j < mines.GetLength(1); j++)
{
if (mines[i, j] == 1)
{
images[i, j].Source = new BitmapImage(new Uri("img/lei.gif", UriKind.Relative));
}
}
}
/* MessageBox.Show("失败!");
//失败后先清除失败之前的
GameBG.Children.Clear();
Ge();
InitialGame();*/
timer.Stop();
MessageBoxResult shibai=MessageBox.Show("失败!是否从新开始游戏", "失败!", MessageBoxButton.YesNo, MessageBoxImage.Question);
x = -1;
if (shibai==MessageBoxResult.Yes)
{
x++;
num = 60;
Puji.Content = "记录第" + x + "步";
GameBG.Children.Clear();
timer.Start();//把记录倒数的数字,从新开始
/*Ge();*/
InitialGame();
}
else
{
this.Close();//关闭整个游戏窗口
}
}
}
void CountMine(int i, int j, Image img)
{
//判断死循环,判断当前位置被判断过了,在外面定义一个overList
//因为外面默认值是false,所以if判断进来为true,然后return,下面的都不会执行
/*1.先点击MainWindow_MouseLeftButtonDown
* 2.判断雷数
* 3. CountMine(index[0], index[1], img);进来overList[i,j]==false,不进入if(overList[i,j]==true)
* 4.直接改变默认值false为overList[i, j] = true;
* 5.第二次点击重复1、2、进入CountMine在判断,这个时候就可以进入overList[i,j]==true,return后面的就不会再执行了
*/
if (overList[i,j]==true)
{
return;
}
//点击后改为true
overList[i, j] = true;
//用一个数字记录周围的雷数,如果还是0的话翻其他周围的牌子
int count = 0;
if (IsMine(i - 1, j))//为
{
//如果满足条件count++;加成1
count++;
}
if (IsMine(i - 1, j - 1))
{
count++;
}
if (IsMine(i, j - 1))
{
count++;
}
if (IsMine(i + 1, j - 1))
{
count++;
}
if (IsMine(i + 1, j))
{
count++;
}
if (IsMine(i + 1, j + 1))
{
count++;
}
if (IsMine(i, j + 1))
{
count++;
}
if (IsMine(i - 1, j + 1))
{
count++;
}
if (count == 0)//不是炸弹
{
//消除地板砖
GameBG.Children.Remove(img);
//八个方向,判断界限不能超过界限
if (i > 0)
{
//又递归一下,判断周围的地板,并改图片
CountMine(i - 1, j, images[i - 1, j]);
}
if (j > 0)
{
CountMine(i, j - 1, images[i, j - 1]);
}
if (i > 0 && j > 0)
{
CountMine(i - 1, j - 1, images[i - 1, j - 1]);
}
if (i < mines.GetLength(0) - 1)
{
CountMine(i + 1, j, images[i + 1, j]);
}
if (j < mines.GetLength(1) - 1)
{
CountMine(i, j + 1, images[i, j + 1]);
}
if (i > 0 && j < mines.GetLength(1) - 1)
{
CountMine(i - 1, j + 1, images[i - 1, j + 1]);
}
if (i < mines.GetLength(0) - 1 && j < mines.GetLength(1) - 1)
{
CountMine(i + 1, j + 1, images[i + 1, j + 1]);
}
if (i < mines.GetLength(0) - 1 && j > 0)
{
CountMine(i + 1, j - 1, images[i + 1, j - 1]);
}
}
else
{
GameBG.Children.Remove(img);
Label lb = new Label();
//文本的
lb.Content = count.ToString();
Grid.SetColumn(lb, j);
Grid.SetRow(lb, i);
lb.FontSize = 15;
lb.HorizontalContentAlignment = HorizontalAlignment.Center;
lb.VerticalContentAlignment = VerticalAlignment.Center;
GameBG.Children.Add(lb);
}
}
bool IsMine(int i,int j)//默认是false
{
//表示i、j不能为负数或0,i\j不能大于数组的限度,防止死循环和报错(限度会超出)
if (i<0||j<0||i>=mines.GetLength(0)||j>=mines.GetLength(1))
{
return false;
}
else
{
//表示炸弹时返回正确的
if (mines[i,j]==1)//mines[i,j]==1是正确的
{
return true;
}
else
{
return false;
}
}
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
rows +=5 ;
mineCount += 5;
//先清除行和列
GameBG.RowDefinitions.Clear();
GameBG.ColumnDefinitions.Clear();
//然后在清除整个页面的内容
GameBG.Children.Clear();
//调用网格数
Ge();
//调用图片
InitialGame();
}
}}
// using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using System.Windows;
//using System.Windows.Controls;
//using System.Windows.Data;
//using System.Windows.Documents;
//using System.Windows.Input;
//using System.Windows.Media;
//using System.Windows.Media.Imaging;
//using System.Windows.Navigation;
//using System.Windows.Shapes;
//namespace _2扫雷
// {
// /// <summary>
// /// MainWindow.xaml 的交互逻辑
// /// </summary>
// public partial class MainWindow : Window
// {
// public MainWindow()
// {
// InitializeComponent();
// }
// //在外面定义一个变量,用来循环10次,原因是行循环10次,列循环10次
// int rows = 10;
// //随机数
// Random r = new Random();
// //这个二维数组分别放行和列
// int[,] mines;
// //放图片的数组
// Image[,] images;
// //在外面定义一个判断值 //当前位置默认为false
// bool[,] overList;
// //定义10个炸弹
// int mineCount = 10;
// private void Window_Loaded(object sender, RoutedEventArgs e)
// {
// for (int i = 0; i < rows; i++)
// {
// //把网格的行和列分成10*10的格子
// //创建行数
// RowDefinition row = new RowDefinition();
// GameBG.RowDefinitions.Add(row);
// //创建列数
// ColumnDefinition column = new ColumnDefinition();
// GameBG.ColumnDefinitions.Add(column);
// }
// //表示网格的线是否显示显示
// GameBG.ShowGridLines = true;
// //创建一个方法,用这个方法显示每个格子的东西显示
// InitialGame();
// }
//
// private void InitialGame()
// {
// //把每个网格的行和列放在mines数组里
// mines = new int[rows, rows];
// //给每个图片添加网格
// images = new Image[rows, rows];
// //当前位置默认为全是false
// overList = new bool[rows, rows];
// //用1数字来记录10个炸弹
// for (int i = 0; i < mineCount; i++)//循环10次炸弹
// {
// //GetLength表示指定元素的索引
// //随机出网格0代表行,1来表列
// int row = r.Next(0, mines.GetLength(0));
// int colmun = r.Next(0, mines.GetLength(1));
// //表示当行和列,标记==1,这个的值==1
// //当记录数字等于等于1时候表示以及记录过了,所以i循环的时候i--回去,从新随机,else不等于记录的数组时就为1
// if (mines[row, colmun] == 1)
// {
// i--;
// }
// else
// {
// mines[row, colmun] = 1;
// }
// }
// //初始情况下所有的Image全部装zhuan
// for (int i = 0; i < mines.GetLength(0); i++)//控制行
// {
// for (int j = 0; j < mines.GetLength(1); j++)//控制列
// {
// //实例化一下图片
// images[i, j] = new Image();
// //然后给每个位置添加图片
// images[i, j].Source = new BitmapImage(new Uri("img/zhuan.gif", UriKind.Relative));
// //每个小格子的间距
// images[i, j].Margin = new Thickness(2, 2, 2, 2);
// //附加属性设置为指定的对象,把这个图片添加到指定的x,y的具体位置上
// Grid.SetRow(images[i, j], i);
// Grid.SetColumn(images[i, j], j);
// //给每个图片定义一个tag值,用一个数组定义,索引0,1
// //如果给成具体数字表示这张图片的tag值是什么数字代表
// images[i, j].Tag = new int[2] { i, j };
// //把每个图片添加到GameBG里面
// GameBG.Children.Add(images[i, j]);
// //鼠标的左键
// images[i, j].MouseLeftButtonDown += MainWindow_MouseLeftButtonDown;
// //鼠标的右键
// images[i, j].MouseRightButtonDown += MainWindow_MouseRightButtonDown;
// }
// }
// }
// //鼠标右键,表示有雷放个旗子
// private void MainWindow_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
// {
// //因为是局部变量,所以想要获取image具体的图片要用一个具体的事件触发者,谁创建的这个事件谁就是事件触发者
// Image img = sender as Image;
// //添加红旗图片
// img.Source = new BitmapImage(new Uri("img/qizi.gif", UriKind.Relative));
// }
// //鼠标左键
// private void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
// {
// //因为是局部变量,所以想要获取image具体的图片要用一个具体的事件触发者,谁创建的这个事件谁就是事件触发者
// Image img = sender as Image;
// //获取图片的tag值,类型是数组
// int[] index = img.Tag as int[];
// //点击的这个是一个安全地区
// //首先在执行这里时,在外面定义一个bool,用形参来判断满足的条件IsMine
// //IsMine(index[0],index[1]);
// if (!IsMine(index[0], index[1]))//true//返回不正确时进入//判断雷数
// {
// //要判断周围的地雷数,基本上所有的雷周围至少有3个,最多有8个相邻
// //假设当前这个是i,j,则需要考虑周围的(i-1,j),(i-1,j-1),(i,j-1),(i+1,j-1),(i+1,j),(i+1,j+1),(i,j+1),(i-1,j+1)
// //int count = CountMine(index[0], index[1]);\
// //调用x,y具体图片的位置tagzhi
// CountMine(index[0], index[1], img);//放雷数
// //判断剩下格子数量
// int left = 0;
// for (int i = 0; i < overList.GetLength(0); i++)
// {
// for (int j = 0; j < overList.GetLength(1); j++)
// {
// if (overList[i, j] == false)
// {
// left++;
// }
// }
// }
// if (left == mineCount)
// {
// MessageBox.Show("获胜");
// }
// }
// else
// {
// for (int i = 0; i < mines.GetLength(0); i++)
// {
// for (int j = 0; j < mines.GetLength(1); j++)
// {
// if (mines[i, j] == 1)
// {
// images[i, j].Source = new BitmapImage(new Uri("img/lei.gif", UriKind.Relative));
// }
// }
// }
// MessageBox.Show("失败!");
//
// }
// }
// void CountMine(int i, int j, Image img)
// {
// //判断死循环,判断当前位置被判断过了,在外面定义一个overList
// //因为外面默认值是false,所以if判断进来为true,然后return,下面的都不会执行
// /*1.先点击MainWindow_MouseLeftButtonDown
// * 2.判断雷数
// * 3. CountMine(index[0], index[1], img);进来overList[i,j]==false,不进入if(overList[i,j]==true)
// * 4.直接改变默认值false为overList[i, j] = true;
// * 5.第二次点击重复1、2、进入CountMine在判断,这个时候就可以进入overList[i,j]==true,return后面的就不会再执行了
// */
// if (overList[i, j] == true)
// {
// return;
// }
// //点击后改为true
// overList[i, j] = true;
// //用一个数字记录周围的雷数,如果还是0的话翻其他周围的牌子
// int count = 0;
// if (IsMine(i - 1, j))//为
// {
// //如果满足条件count++;加成1
// count++;
// }
// if (IsMine(i - 1, j - 1))
// {
// count++;
// }
// if (IsMine(i, j - 1))
// {
// count++;
// }
// if (IsMine(i + 1, j - 1))
// {
// count++;
// }
// if (IsMine(i + 1, j))
// {
// count++;
// }
// if (IsMine(i + 1, j + 1))
// {
// count++;
// }
// if (IsMine(i, j + 1))
// {
// count++;
// }
// if (IsMine(i - 1, j + 1))
// {
// count++;
// }
// if (count == 0)//不是炸弹
// {
// //消除地板砖
// GameBG.Children.Remove(img);
// //八个方向,判断界限不能超过界限
// if (i > 0)
// {
// //又递归一下,判断周围的地板,并改图片
// CountMine(i - 1, j, images[i - 1, j]);
// }
// if (j > 0)
// {
// CountMine(i, j - 1, images[i, j - 1]);
// }
// if (i > 0 && j > 0)
// {
// CountMine(i - 1, j - 1, images[i - 1, j - 1]);
// }
// if (i < mines.GetLength(0) - 1)
// {
// CountMine(i + 1, j, images[i + 1, j]);
// }
// if (j < mines.GetLength(1) - 1)
// {
// CountMine(i, j + 1, images[i, j + 1]);
// }
// if (i > 0 && j < mines.GetLength(1) - 1)
// {
// CountMine(i - 1, j + 1, images[i - 1, j + 1]);
// }
// if (i < mines.GetLength(0) - 1 && j < mines.GetLength(1) - 1)
// {
// CountMine(i + 1, j + 1, images[i + 1, j + 1]);
// }
// if (i < mines.GetLength(0) - 1 && j > 0)
// {
// CountMine(i + 1, j - 1, images[i + 1, j - 1]);
// }
// }
// else
// {
// GameBG.Children.Remove(img);
// Label lb = new Label();
// //文本的
// lb.Content = count.ToString();
// Grid.SetColumn(lb, j);
// Grid.SetRow(lb, i);
// lb.FontSize = 15;
// lb.HorizontalContentAlignment = HorizontalAlignment.Center;
// lb.VerticalContentAlignment = VerticalAlignment.Center;
// GameBG.Children.Add(lb);
// }
// }
// bool IsMine(int i, int j)//默认是false
// {
// //表示i、j不能为负数或0,i\j不能大于数组的限度,防止死循环和报错(限度会超出)
// if (i < 0 || j < 0 || i >= mines.GetLength(0) || j >= mines.GetLength(1))
// {
// return false;
// }
// else
// {
// //表示炸弹时返回正确的
// if (mines[i, j] == 1)//mines[i,j]==1是正确的
// {
// return true;
// }
// else
// {
// return false;
// }
// }
// }
// }
// }
WPF扫雷(注释+代码)
最新推荐文章于 2024-04-18 09:32:44 发布