扫雷的最基础版本(小白看了都会(有源码哟~))

目录


前言:

这个版本的扫雷是最基础的版本,想要实现更多功能就要亲自动手哟。哈哈哈,这里的小白是要至少会函数和数组的知识才行哟~!源码在最下边。




扫雷的原理

1.1简单说明

相信大家,都玩过扫雷。如果玩过的兄弟就不用看这了,如果还没玩过的话。建议大家去玩一下,再来看这篇博客。这样,也会有更深的理解yo~。

1.2代码扫雷如何实现

首先我们还是来看几张图

我在实现时这是我们能看到的部分每个*代表雷,这是一个9*9的雷图。我们知道当我们排雷时会返回对应位置周围的雷的个数。

这时就有人问最周边的位置怎么办?带着这个疑问我们再看一张图。

其实在我们箭头指的方向其实还有隐藏的一排,只是我们没有让它显示出来。

然后我们又是怎样输入一个雷的坐标后返回周围雷的个数的呢?

我们看图其中1就是表示有雷的地方,我们也隐藏了它周围的一排,其中这周围的一排全部都为0。但是我们再玩这个扫雷时,我们是看不见的。这时候你大概就有点悟了,但又没有完全悟。知道你很急,但是你先别急。

ok这是我们能看到棋盘和我们不能看见的内部的简单说明。可能现在你已经汗流浃背了。但是你再往下看,可能就看懂了。



 初始化设计

2.1 头文件 源文件

我们创建了的一个扫雷的头文件,用来声明函数。

创建一个game.cpp文件来实现我们的部分函数。

再创建一个text.cpp文件来实现我们的主要功能。

此时我们只需要在扫雷.h里面引头文件。在源文件里引头文件就行了。(如果在头文件已经引了头文件,在源文件中引了头文件,就不用引新的头文件)。



游戏的初步设计

3.1游戏界面设计

void menu()
{
	printf("########################\n");
	printf("####   1.  paly  #######\n");//提示按1进入游戏
	printf("####   0.  exit  #######\n");//提升按1退出游戏
	printf("########################\n");
}

void game()
{
}

void test()
{
	int input = 0;//创建一个输入数input
	do            //do while循环至少运行一次
	{
		menu();               // 打印选选
		printf("请选择->");
		scanf("%d", &input);//输入input
		switch (input)
		{
		case 1:   //输入1就进入游戏
		{
			printf("------扫雷------\n");
			game();
			break;
		}
		case 0:
			printf("退出游戏\n");  //输入0跳出
			break;
		default:
			printf("选择错误,从新选择喵~\n");//如果选择其他数就会让你重新选择。
			break;
		}

	} while (input);  //输入0时就退出
}

int main(){
	test();          //我们把游戏放在一个test函数里面实现
	return 0;
}

这就是游戏的初步设计,主要是创建创建一个menu菜单,根据菜单实现它的基本功能。再在基本功能之上去实现游戏函数。所以初始化的步骤里我们还没有去实现扫雷游戏的函数。

当我们运行代码时

就可以打印菜单了。

实现扫雷

4.1扫雷的棋盘和雷的布置

首先我们在上边已经说明我们在打印时是少打印了一圈的。

我们看到的是9*9的棋盘所以在当我们初始化棋盘时我们要多初始化两行两列,也就是初始化11*11的棋盘和雷的布置。

看图理解,我们主要看6 7 8 9行代码。

我们定义两组数

6 7,打印的数(后面要用)。

8 9,生成棋盘的行数和列的数。


这里我们直接在game函数里来生成我们的两个棋盘

我们初始化生成一个雷的棋盘(这个部分在运行当中玩家是看不到的)和一个玩家能看到的棋盘。我们命名为mine(雷) 和 show

然后就是初始化两个棋盘。我们用一个函数来实现


我们来看函数(不要忘是在game。cpp中实现的)

void initboard(char ROW[][rows],  int R, int C,char set)//传入要初始化的数组,R为行(横着的) 
                                                          的长度,C为列(竖着的),set为初始化 
                                                          的参数。
{
	int i = 0;
	for (i = 0; i < R; i++)
	{
		int j = 0;
		for (j = 0; j < C; j++)
		{
			ROW[i][j] = set;     //全部为set
		}
	
	}
}

然后要在头文件中声明,就像这样。


4.2棋盘的打印

我们在这看6 7行代码


我们用一个print函数来打印棋盘。

注意row,col 是9哟


我们要打印成这个样子。


所以请跟着我这样做(不要忘是在game。cpp中实现的)

void print(char arr[][rows], int R, int C)//传入要打印的数组,R为行(横着的) 
                                                          的长度,C为列(竖着的)
{
	int i = 0;
	for (i = 0; i <=col; i++)         //先在第一排打印0-9,打印后添加一个空格,
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= R; i++)           //从每行的第二开始打印(横着的),打印到第九列
	{
		int j = 1;                     //打印之前打印每行的行数。
		printf("%d", i);
		for (j = 1; j <=C; j++)        //从每列的第二个开始打印(竖着的),打印到第九列
		{
			printf(" %-1c", arr[i][j]);//用-1空一格。
		}
		printf("\n");                   //每打印一列换行
	}
}

不要忘在头文件声明函数


4.3布置雷

我们还是用函数来实现布置雷

注意我们的雷只能在九行九列中生成,所以传row,和col。


我们先在头文件中定义一个要生成雷的个数(第十行)


我们再来看实现的函数(在game.cpp中实现的)

void setmine(char arr[][cols], int R, int C)//传的mine字符数组,R为9,C为9
{
	int count = EASR_COUNT;                 //十个雷
	while (count)
	{
		int x = rand() % row + 1;           //x为竖着的坐标,y为横着的坐标
		int y = rand() % col + 1;           //rand()生成随机数。%row为0-8,加1变成1-9;
		if (arr[x][y] == '0')               //判断是否已经生成过雷
		{ 
			arr[x][y] = '1';                //用1来表示雷。
			count--;                        //每生成一个雷count就减一,直到生成10个1
		}
	}
}

为了使生成的随机数为正数且更随机。我们再main函数中这样写 

注意不要忘引头文件和声明函数 

4行 rand(),srand()的头文件

5行 time的函数的头文件。


打印一下生成雷的棋盘看看(意味着可以作弊哟~)


4.4找雷

我们还是用一个函数来实现

传入我们的mine,和show的棋盘,找的是9*9的棋盘所以都传的是九。


我们来看实现的函数(game.cpp中实现)

static int get_mine_conut(char mine[][cols], int x, int y)//static只在本源文件用
{
	return mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1]
		+ mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1]-8*'0';
//返回周围坐标的ascall码
}

 void findmine(char mine[][cols], char show[][cols], int R, int C)
{
	 int win = 0;//win用来判断是否胜利。
     //基本逻辑
	 //1.输入坐标
	 //2.检查坐标是不是雷
	 //(1).是雷--被炸死,游戏结束
	 //(2).不是雷--统计周边有多少个雷--存储排查雷的信息到数组
	 while (win<row*col-EASR_COUNT)//row*col-EASR_COUNT为71,win开始为0,走71步就跳出循环了
	 {
		 printf("请输入要排查的坐标->");              //输入坐标x为竖着的,y为横着的。
		 int x = 0;
		 int y = 0;
		 scanf("%d %d", &x, &y);//(取值为1到9)
		                                               //判断合法性
		 if (x >= 1 && x <= 9 && y >= 1 && y <= 9)
		 {
			  if (mine[x][y] == '1')                  //如果为1就被炸死    
			 {
				 printf("被炸死了喵~\n");
				 print(mine, row, col);              //让你死得瞑目,给你打印一下生成雷的棋盘
				 break;                              //跳出循环
			 }
			 else
			 {
				                               //不是雷,统计坐标周围的雷的个数
				int count= get_mine_conut(mine, x, y);//用一个函数来实现
				show[x][y] = count+'0';   //注意看这是字符的数字哟!所以我们要加个'0',不是0哟
				                          //有几个就是对应的ascall码(字符对应的数字)。
                print(show, row, col);    //打印一下棋盘(玩家能看见的棋盘)     
				win++;                    //每排除一个win就加1
			 }
		 }
		 else
		 {
			 printf("坐标不合法喵~\n");//如果不为1-9的化就重新输入。
		 }
	 }
	 if (win == row * col - EASR_COUNT)//win为71就胜利了
	 {
		 printf("恭喜喵~你太有耐心了,简直就是卡密撒嘛");//夸夸你
	 }
 }

注意声明函数


至此我们的扫雷代码就实现了哟~,其实并不复杂。

如果你没看懂,可能是我的问题,不用怀疑自己

如果有任何问题都可以私信我(ᕑᗢᓫ∗)˒
喵~

源码在这哟

源码地址:icon-default.png?t=N7T8https://github.com/zgw486/zgw486/

我知道你想要源码。

  • 25
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于Java的Android扫雷游戏源码示例,你可以参考一下: ```java public class MainActivity extends AppCompatActivity { private static final int NUM_ROWS = 10; private static final int NUM_COLS = 10; private static final int NUM_MINES = 15; private Button[][] buttons = new Button[NUM_ROWS][NUM_COLS]; private int[][] counts = new int[NUM_ROWS][NUM_COLS]; private boolean[][] revealed = new boolean[NUM_ROWS][NUM_COLS]; private boolean[][] flagged = new boolean[NUM_ROWS][NUM_COLS]; private int numMines = NUM_MINES; private boolean gameOver = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); generateMines(); for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS; col++) { Button button = new Button(this); button.setLayoutParams(new LinearLayout.LayoutParams(100, 100)); button.setBackgroundResource(R.drawable.button_bg); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (gameOver) { return; } Button button = (Button) v; int row = (int) button.getTag(R.id.row); int col = (int) button.getTag(R.id.col); if (flagged[row][col]) { return; } if (counts[row][col] == -1) { gameOver(); } else { reveal(row, col); checkWin(); } } }); button.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { if (gameOver) { return true; } Button button = (Button) v; int row = (int) button.getTag(R.id.row); int col = (int) button.getTag(R.id.col); if (!revealed[row][col]) { flagged[row][col] = !flagged[row][col]; updateButton(button, row, col); checkWin(); } return true; } }); LinearLayout rowLayout = findViewById(getResources().getIdentifier("row_" + row, "id", getPackageName())); rowLayout.addView(button); buttons[row][col] = button; button.setTag(R.id.row, row); button.setTag(R.id.col, col); } } } private void generateMines() { Random random = new Random(); for (int i = 0; i < NUM_MINES; i++) { int row, col; do { row = random.nextInt(NUM_ROWS); col = random.nextInt(NUM_COLS); } while (counts[row][col] == -1); counts[row][col] = -1; for (int r = row - 1; r <= row + 1; r++) { for (int c = col - 1; c <= col + 1; c++) { if (r >= 0 && r < NUM_ROWS && c >= 0 && c < NUM_COLS && counts[r][c] != -1) { counts[r][c]++; } } } } } private void reveal(int row, int col) { if (revealed[row][col]) { return; } revealed[row][col] = true; Button button = buttons[row][col]; updateButton(button, row, col); if (counts[row][col] == 0) { for (int r = row - 1; r <= row + 1; r++) { for (int c = col - 1; c <= col + 1; c++) { if (r >= 0 && r < NUM_ROWS && c >= 0 && c < NUM_COLS && (r != row || c != col)) { reveal(r, c); } } } } } private void updateButton(Button button, int row, int col) { if (flagged[row][col]) { button.setText("F"); } else if (revealed[row][col]) { int count = counts[row][col]; if (count == 0) { button.setText(""); } else { button.setText(String.valueOf(count)); } } else { button.setText(""); } } private void gameOver() { gameOver = true; for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS; col++) { if (counts[row][col] == -1) { revealed[row][col] = true; updateButton(buttons[row][col], row, col); } } } Toast.makeText(this, "Game over!", Toast.LENGTH_SHORT).show(); } private void checkWin() { int numRevealed = 0; for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS; col++) { if (revealed[row][col]) { numRevealed++; } } } if (numRevealed == NUM_ROWS * NUM_COLS - NUM_MINES) { Toast.makeText(this, "You win!", Toast.LENGTH_SHORT).show(); } } } ``` 这个示例代码使用一个二维数组来表示扫雷游戏的方格,其中-1表示地雷,其他数字表示周围地雷的数量。它还使用另外两个二维数组来跟踪哪些方格已经被揭示和哪些方格被标记。在点击和长按方格时,它根据游戏规则揭示或标记方格,并在必要时检查游戏是否结束。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值