前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >扫雷游戏(有讲解)

扫雷游戏(有讲解)

作者头像
用户11039529
发布2024-03-25 15:16:43
750
发布2024-03-25 15:16:43
举报
文章被收录于专栏:算法学习日常算法学习日常

引言:

1.数组

2.随机数的生成,我在这篇文章里面详细讲述过:猜数字游戏(C语言实现)-CSDN博客

3.知道棋盘的设置:假如棋盘中1表示雷,0表示没有雷,如果扫雷时扫到的地方没有雷,则在显示的棋盘上对应的位置显示周围的八个位置中有多少雷,那么,这里就出现了问题:有1的时候是有雷呢,还是附近有一个雷?所以,在这里,我们要设置两个棋盘,一个是mine棋盘存放雷的信息),另一个是show棋盘展示给玩家的部分

思路:

1.菜单供玩家选择

2.实现主题函数部分:

(1)初始化棋盘
(2)布置雷
(3)玩家扫雷

实现:

首先,我们要将函数分为三个部分:

1.game.h(函数的声明部分)

2.game.c(函数的重要实现部分

3.test.c(函数的测试部分

1.菜单

猜数字一样,在开头,要生成菜单和供玩家选择的部分,具体实现就参考猜数字文章了啦

代码语言:javascript
复制
void caidan()
{
	printf("************************\n");
	printf("*****  1.开始游戏  *****\n");
	printf("*****  0.退出游戏  *****\n");
	printf("************************\n");
}


int main()
{
	int input;
	srand((unsigned int)time(NULL));

	do
	{	
		caidan();
		printf("请输入>:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				printf("开始游戏\n");
				sao_lei();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("选择错误\n");
				break;
		}
		
	} while (input);

	return 0;
}

2.初始化棋盘

(1)mine棋盘:

没雷设置为0,有雷设置为1,由于一开始还没有布置雷,所以全设置为0

(2)show棋盘:

若该位置被排查过且不是雷,则显示周围雷的个数,但是一开始没有开始排查,所以全设置为*

由于*为字符,为了简化代码和模板化,需要将初始化部分写为一个函数,所以将mine数组设置为char类型的数组方便操作

test.c:
代码语言:javascript
复制
void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');
}
game.c:
代码语言:javascript
复制
void InitBorad(char borad[ROWS][COLS], int rows, int cols, char tuan)
{
	int i = 0, j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			borad[i][j] = tuan;
		}
	}
}

若不明白COL,ROW,COLS,ROWS的意义,请根据目录转到:总代码----game.h部分

效果:

3.布置雷:

test.c:
代码语言:javascript
复制
void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);
}
game.c:
代码语言:javascript
复制
void SetBorad(char borad[ROWS][COLS], int row, int col)
{
	int x;
	int y;
	int count = COUNT;

	while(count)
	{
		x = rand() % row + 1;//设置生成雷的部分在坐标为1~行数-1的范围内
		y = rand() % row + 1;

		if (borad[x][y] == '0')//如果这个地方没有设置雷,则布置mine棋盘这里是雷
		{
			borad[x][y] = '1';
			count--;
		}
	}

}

若不明白COUNT的意义,请根据目录转到:总代码----game.h部分

效果:

上面为mine棋盘,下面为show棋盘

4.打印棋盘:

test.c:
代码语言:javascript
复制
void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);

	//打印棋盘
	print_qi_pan(mine, ROW, COL);
	print_qi_pan(show, ROW, COL);
}
game.c:
代码语言:javascript
复制
void print_qi_pan(char borad[ROWS][COLS],int row,int col)
{
	int i = 0, j = 0;
	printf("--------扫雷游戏--------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	/**/

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ",borad[i][j]);
		}
		printf("\n");
	}
	printf("--------扫雷游戏--------\n");

}

5.找雷:

要获取玩家排查坐标,所以要玩家输入坐标x,y,因为需要在展示的棋盘内排查,所以若输入坐标超出棋盘,则需要重新输入,这需要循环来完成,所以有以下代码:

代码语言:javascript
复制
void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

如果是雷,则显示:“很遗憾,你被炸死了”,并将mine棋盘打印给玩家,跳出循环:

代码语言:javascript
复制
void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

如果排查的地方不是雷,则在show棋盘上显示周围雷的个数(要运用排查雷的函数: Get_My_Borad):

代码语言:javascript
复制
void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//棋盘中不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);//检查周围坐标并算出雷的个数
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';//周围雷的个数
				count--;//没有排查的坐标减一
				print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}
Get_My_Borad:
代码语言:javascript
复制
int Get_My_Borad(char mine[ROWS][COLS], int x, int y)
{
	return (
		(mine[x - 1][y - 1] - '0') +
		(mine[x-1][y] - '0') +
		(mine[x- 1][y + 1] - '0') +
		(mine[x][y-1] - '0') +
		(mine[x][y+1] - '0') +
		(mine[x + 1][y - 1] - '0') +
		(mine[x + 1][y] - '0') +
		(mine[x + 1][y + 1] - '0')
		);
}

如果不是没有被排查且不是雷的位置个数=不是雷的位置总个数,则打印:”恭喜你,排雷成功“,并打印mine棋盘,再退出循环:

代码语言:javascript
复制
void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//棋盘中不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);//检查周围坐标并算出雷的个数
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';//周围雷的个数
				count--;//没有排查的坐标减一
				if(count==0)
				{
					printf("恭喜排雷成功\n");
					print_qi_pan(mine, col, row);
					break;
				}
				else
					print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}
test.c:
代码语言:javascript
复制
void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);

	//打印棋盘
	print_qi_pan(mine, ROW, COL);
	print_qi_pan(show, ROW, COL);

	//扫雷
	Findlei(mine,show, ROW, COL);

}
game.c:
代码语言:javascript
复制
int Get_My_Borad(char mine[ROWS][COLS], int x, int y)
{
	return (
		(mine[x - 1][y - 1] - '0') +
		(mine[x-1][y] - '0') +
		(mine[x- 1][y + 1] - '0') +
		(mine[x][y-1] - '0') +
		(mine[x][y+1] - '0') +
		(mine[x + 1][y - 1] - '0') +
		(mine[x + 1][y] - '0') +
		(mine[x + 1][y + 1] - '0')
		);
}

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';
				count--;
				if(count==0)
				{
					printf("恭喜排雷成功\n");
					print_qi_pan(mine, col, row);
					break;
				}
				else
					print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

总代码:

game.h:

代码语言:javascript
复制
#pragma once

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define ROW 9//展示给玩家部分的行
#define COL 9//展示给玩家部分的列

#define ROWS ROW+2//实现部分的行
#define COLS COL+2//实现部分的列

#define COUNT 10//雷的个数

//以下均为函数声明部分
void sao_lei();
void InitBorad(char borad[ROWS][COLS], int rows, int cols, char tuan);
void print_qi_pan(char borad[ROWS][COLS], int row, int col);
void SetBorad(char borad[ROWS][COLS], int row, int col);
void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int Get_My_Borad(char mine[ROWS][COLS], int x, int y);

game.c:

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include "sao_lei_you_xi.h"
//重要部分实现

void InitBorad(char borad[ROWS][COLS], int rows, int cols, char tuan)
{
	int i = 0, j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			borad[i][j] = tuan;
		}
	}
}

void print_qi_pan(char borad[ROWS][COLS],int row,int col)
{
	int i = 0, j = 0;
	printf("--------扫雷游戏--------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	/**/

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ",borad[i][j]);
		}
		printf("\n");
	}
	printf("--------扫雷游戏--------\n");

}




void SetBorad(char borad[ROWS][COLS], int row, int col)
{
	int x;
	int y;
	int count = COUNT;

	while(count)
	{
		x = rand() % row + 1;
		y = rand() % row + 1;

		if (borad[x][y] == '0')
		{
			borad[x][y] = '1';
			count--;
		}
	}

}

int Get_My_Borad(char mine[ROWS][COLS], int x, int y)
{
	return (
		(mine[x - 1][y - 1] - '0') +
		(mine[x-1][y] - '0') +
		(mine[x- 1][y + 1] - '0') +
		(mine[x][y-1] - '0') +
		(mine[x][y+1] - '0') +
		(mine[x + 1][y - 1] - '0') +
		(mine[x + 1][y] - '0') +
		(mine[x + 1][y + 1] - '0')
		);
}

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//棋盘中不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);//检查周围坐标并算出雷的个数
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';//周围雷的个数
				count--;//没有排查的坐标减一
				if(count==0)
				{
					printf("恭喜排雷成功\n");
					print_qi_pan(mine, col, row);
					break;
				}
				else
					print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

test.c:

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS 1
#include "sao_lei_you_xi.h"
//可展示函数

//显示菜单
void caidan()
{
	printf("************************\n");
	printf("*****  1.开始游戏  *****\n");
	printf("*****  0.退出游戏  *****\n");
	printf("************************\n");
}

void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);

	//打印棋盘
	print_qi_pan(mine, ROW, COL);
	print_qi_pan(show, ROW, COL);

	//扫雷
	Findlei(mine,show, ROW, COL);

}

int main()
{
	int input;
	srand((unsigned int)time(NULL));

	do
	{	
		caidan();
		printf("请输入>:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				printf("开始游戏\n");
				sao_lei();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("选择错误\n");
				break;
		}
		
	} while (input);

	return 0;
}

完结撒花,恭喜你今天又进步了呀~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-01-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言:
  • 思路:
    • 1.菜单供玩家选择
      • 2.实现主题函数部分:
        • (1)初始化棋盘
        • (2)布置雷
        • (3)玩家扫雷
    • 实现:
      • 1.菜单
        • 2.初始化棋盘
          • (1)mine棋盘:
          • (2)show棋盘:
          • test.c:
          • game.c:
          • 效果:
        • 3.布置雷:
          • test.c:
          • game.c:
          • 效果:
        • 4.打印棋盘:
          • test.c:
          • game.c:
        • 5.找雷:
          • Get_My_Borad:
          • test.c:
          • game.c:
      • 总代码:
        • game.h:
          • game.c:
            • test.c:
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档