【C语言-56】用C语言实现简单"扫雷小游戏",代码讲解喵喵乐~~~~~

功能实现:

  • 地图创建,玩家地地图和地雷布局图
  • 输入位置坐标合法性判定和胜负判定
  •  

解题分析:

  • 创建两个二维数组表示两个地图:
  1. a)玩家看到的地图show_map,已翻开(数字表示)和未翻开(*表示)两种状态;
  2. b)地雷布局图mine_map,每个位置是否有地雷(0表示是地雷1表示不是地雷);
    1. 行列

      数标

      0 1 2 3 4 5 6 7 8
      0 0 0 0 0 0 0 0 0 0
      1 0 0 1 0 0 0 0 0 1
      2 0 0 0 0 0 0 0 0 0
      3 1 1 0 0 0 1 0 0 0
      4 0 0 1 0 0 0 0 0 0
      5 0 0 0 0 0 0 0 0 0
      6 0 0 0 0 0 0 0 0 0
      7 1 0 0 0 0 0 0 0 1
      8 0 0 0 1 1 0 0 0 0
  • 进行地图初始化
  1. show_map初始化,每个元素设为 *
  2. mine_map初始化,随机生成若干个个地雷
  • 打印地图
  • 提示用户输入一个坐标,表示要翻开某个位置(进行必要合法性判定)                                                                                                          
  • 坐标判定:
  1. 判定该位置是否是地雷,如果是地雷,游戏结束
  2. 如果不是地雷,判定是否游戏胜利(把所有不是地雷的格子翻开则胜利)
  3. 如果没有胜利,给当前位置的格子生成一个数字表示周围有几个雷
  • 计算点击位置周围雷的数目
  1. 遍历目标单位上下左右共八个格子就可以了,
  2. row-1

    col-1

    row-1

    col

    row-1

    col+1

    row

    col-1

    row

    col

    row

    col+1

    row+1

    col-1

    row+1

    col

    row+1

    col+1

代码解析:

头文件和宏的定义:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define MAX_ROW 9
#define MAX_COL  9
#define MINE_COUNT 10

主函数:

  1.  主函数内获取菜单函数返回值,
  2. 进入选择程序,判断是否进行游戏;
  3. 代码示例:
  4. int main() {
    	while (1) {
    
    		int choice = Menu();
    
    		if (choice == 1) {
    
    			Game();
    		}
    		else if (choice == 0) {
    
    			printf("退出游戏,再见!");
    
    			break;
    		}
    
    		else {
    
    			printf("您的输入有误!");
    		}
    	}
    	system("pause");
    
    	return 0;
    }

    菜单函数Menu():

  5.  提示用户进行选择,返回值为用户选择,在主函数内得到判断;
  6.  
  7. 代码示例:
  8. int Menu() {
    	printf("==================================\n");
    	printf("          1.开始游戏\n");
    	printf("          0.退出游戏\n");
    	printf("==================================\n");
    	printf("请输入您的选项:");
    
    	int choice = 0;
    	scanf("%d", &choice);
    	return choice;
    
    }

    运行示例:

游戏函数:

  1.  创建两个二维数组,用来表示地图;
  2. 定义一个函数  Init() ,对地图进行初始化;
  3. 定义一个函数 PrintMap(),进行地图打印;
  4.  提示用户输入坐标,并对坐标进行合法性检验;
  5. 坐标合法后在检测输入位置是否有雷;
  6.  判定游戏是否胜利;
  7. 定义一个函数,统计当前位置地雷个数;
  8.  
  9. 代码示例:
  10. void Game() {
    	//1.创建地图,并且初始化..
    	char show_map[MAX_ROW][MAX_COL];
    	char mine_map[MAX_ROW][MAX_COL];
    	//创建一个变量,表示已经翻开非地雷个数
    	int blank_count_already_show = 0;
    	Init(show_map, mine_map);
    	while (1) {
    
    		//2.打印地图
    		PrintMap(show_map);
    		//3.让用户输入坐标,并进行合法性检验
    		printf("请输入一组坐标(row col):");
    		int row = 0;
    		int col = 0;
    		scanf("%d %d", &row, &col);
    		//在这里进行清屏,
    		system("cls");
    		//3.合法性检测
    		if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
    			printf("您的输入非法!请重新输入!\n");
    			continue;
    		}
    		if (show_map[row][col] != '*') {
    			printf("您输入的位置已经翻开了");
    			continue;
    		}
    		//4.判定是否是地雷
    		if (mine_map[row][col] == '1') {
    			printf("游戏结束!\n");
    			PrintMap(mine_map);
    			break;
    		}
    		//5.判定游戏是否胜利,
    		//判定所有非地雷位置是否全部翻开
    		++blank_count_already_show;
    		if (blank_count_already_show == MAX_COL * MAX_ROW - MINE_COUNT) {
    			printf("游戏胜利!\n");
    			PrintMap(mine_map);
    			break;
    		}
    		//6.统计当前位置周围雷的个数
    		UpdateShowMap(row,col,show_map,mine_map);
    
    	}
    }

    地图初始化函数:

  11.  地图初始化,遍历地图每一个位置坐标,并设置为*;
  12. 对于mine_map,随机生成若干个地雷,这里设置地雷生成10个
  13. 使用0表示不是地雷,使用1表示是地雷
  14. 生成一组随机坐标,判断坐标合法性,并判断坐标处是否已经埋雷;
  15. 代码示例:
  16.  
void Init(char show_map[MAX_ROW][MAX_COL],
	char mine_map[MAX_ROW][MAX_COL]) {

	//1.初始化,show_map都设为*

	for (int row = 0; row < MAX_ROW; ++row) {

		for (int col = 0; col < MAX_COL; ++col) {

			show_map[row][col] = '*';
		}
	}
	//2.对于mine_map,随机生成若干个地雷

	//使用0表示不是地雷,使用1表示是地雷

	for (int row = 0; row < MAX_ROW; ++row) {

		for (int col = 0; col < MAX_COL; ++col) {

			mine_map[row][col] = '0';//此处可以用数字0
		}
	}


	int n = MINE_COUNT;
	while (n > 0) {

		//生成一组随机坐标
		int row = rand() % MAX_ROW;
		int  col = rand() % MAX_COL;
		//判断随机坐标合法性

		if (mine_map[row][col] == '1') {

			//该位置已经是地雷,需要重新生成
			continue;

		}
		mine_map[row][col] = '1';

		--n;
	}
}

地图打印函数:

  1.  
  2.  代码示例:
  3. void PrintMap(char map[MAX_ROW][MAX_COL]) {
    
    	//打印地图的同时,还有对应坐标
    	//打印第一行
    	printf("  ");
    
    	for (int col = 0; col< MAX_COL; ++col) {
    
    		printf("%d ", col);
    	}
    	printf("\n");
    
    	//打印一个分割线
    	for (int col = 0; col < MAX_COL-2; ++col) {
    
    		printf("---");
    		
    	}
    	printf("\n");
    
    	//打印其他行
    	for (int row = 0; row < MAX_ROW; ++row) {
    
    		printf("%d|",row);
    		//打印本行每一列
    
    		for (int col = 0; col < MAX_COL; ++col) {
    
    			printf("%c ", map[row][col]);
    		}
    		printf("\n");
    	}
    
    
    }

    当前位置周围地雷个数统计:

  4.  
  5.  
  6.  
  7. 代码示例:
  8. void UpdateShowMap(int row,int col,
    	char show_map[MAX_ROW][MAX_COL], 
    	char mine_map[MAX_ROW][MAX_COL]) {
    	//根据当前位置判定这个位置周围8个格子有几个地雷
    	//将数字更新到show_map中
    	int count = 0;
    	if (row-1>=0&&col-1>=0
    		&&row-1<MAX_ROW&&col-1<MAX_COL
    		&&mine_map[row - 1][col - 1] == '1') {
    		++count;
    	}
    	if (row - 1 >= 0 && col  >= 0
    		&& row - 1 < MAX_ROW&&col < MAX_COL
    		&&mine_map[row - 1][col] == '1') {
    		++count;
    	}
    	if (row - 1 >= 0 && col +1 >= 0
    		&& row - 1 < MAX_ROW&&col+1 < MAX_COL
    		&&mine_map[row - 1][col+ 1] == '1') {
    		++count;
    	}
    	if (row  >= 0 && col -1 >= 0
    		&& row < MAX_ROW&&col -1 < MAX_COL
    		&&mine_map[row][col -1] == '1') {
    		++count;
    	}
    	if (row  >= 0 && col  >= 0
    		&& row < MAX_ROW&&col  < MAX_COL
    		&&mine_map[row ][col ] == '1') {
    		++count;
    	}
    	if (row >= 0 && col + 1 >= 0
    		&& row < MAX_ROW&&col + 1 < MAX_COL
    		&&mine_map[row][col + 1] == '1') {
    		++count;
    	}
    	if (row+1 >= 0 && col -1 >= 0
    		&& row+1 < MAX_ROW&&col < MAX_COL
    		&&mine_map[row+1][col] == '1') {
    		++count;
    	}
    	if (row +1>= 0 && col >= 0
    		&& row +1< MAX_ROW&&col< MAX_COL
    		&&mine_map[row+1][col] == '1') {
    		++count;
    	}
    	if (row+1 >= 0 && col + 1 >= 0
    		&& row+1 < MAX_ROW&&col + 1 < MAX_COL
    		&&mine_map[row+1][col + 1] == '1') {
    		++count;
    	}
    
    	//得到了周围8个格子地雷的个数
    	show_map[row][col] = '0' + count;
    
    }

    全部代码:

  9.  
  10. #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<stdlib.h>
    #define MAX_ROW 9
    #define MAX_COL  9
    #define MINE_COUNT 10
    
              //菜单打印提醒玩家进行游戏选择;
    int Menu() {
    	printf("==================================\n");
    	printf("          1.开始游戏\n");
    	printf("          0.退出游戏\n");
    	printf("==================================\n");
    	printf("请输入您的选项:");
    
    	int choice = 0;
    	scanf("%d", &choice);
    	return choice;
    
    }
    
    
    void Init(char show_map[MAX_ROW][MAX_COL],
    	char mine_map[MAX_ROW][MAX_COL]) {
    	//1.初始化,show_map都设为*
    	for (int row = 0; row < MAX_ROW; ++row) {
    		for (int col = 0; col < MAX_COL; ++col) {
    			show_map[row][col] = '*';
    		}
    	}
    	//2.对于mine_map,随机生成若干个地雷
    	//使用0表示不是地雷,使用1表示是地雷
    	for (int row = 0; row < MAX_ROW; ++row) {
    		for (int col = 0; col < MAX_COL; ++col) {
    			mine_map[row][col] = '0';//此处可以用数字0
    		}
    	}
    
    
    	int n = MINE_COUNT;
    	while (n > 0) {
    		//生成一组随机坐标
    		int row = rand() % MAX_ROW;
    		int  col = rand() % MAX_COL;
    		//判断随机坐标合法性
    		if (mine_map[row][col] == '1') {
    			//该位置已经是地雷,需要重新生成
    			continue;
    		}
    		mine_map[row][col] = '1';
    		--n;
    	}
    }
    
    
    void PrintMap(char map[MAX_ROW][MAX_COL]) {
    	//打印地图的同时,还有对应坐标
    	//打印第一行
    	printf("  ");
    	for (int col = 0; col< MAX_COL; ++col) {
    		printf("%d ", col);
    	}
    	printf("\n");
    	//打印一个分割线
    	for (int col = 0; col < MAX_COL-2; ++col) {
    		printf("---");
    		
    	}
    	printf("\n");
    	//打印其他行
    	for (int row = 0; row < MAX_ROW; ++row) {
    		printf("%d|",row);
    		//打印本行每一列
    		for (int col = 0; col < MAX_COL; ++col) {
    			printf("%c ", map[row][col]);
    		}
    		printf("\n");
    	}
    
    
    }
    
    
    void UpdateShowMap(int row,int col,
    	char show_map[MAX_ROW][MAX_COL], 
    	char mine_map[MAX_ROW][MAX_COL]) {
    	//根据当前位置判定这个位置周围8个格子有几个地雷
    	//将数字更新到show_map中
    	int count = 0;
    	if (row-1>=0&&col-1>=0
    		&&row-1<MAX_ROW&&col-1<MAX_COL
    		&&mine_map[row - 1][col - 1] == '1') {
    		++count;
    	}
    	if (row - 1 >= 0 && col  >= 0
    		&& row - 1 < MAX_ROW&&col < MAX_COL
    		&&mine_map[row - 1][col] == '1') {
    		++count;
    	}
    	if (row - 1 >= 0 && col +1 >= 0
    		&& row - 1 < MAX_ROW&&col+1 < MAX_COL
    		&&mine_map[row - 1][col+ 1] == '1') {
    		++count;
    	}
    	if (row  >= 0 && col -1 >= 0
    		&& row < MAX_ROW&&col -1 < MAX_COL
    		&&mine_map[row][col -1] == '1') {
    		++count;
    	}
    	if (row  >= 0 && col  >= 0
    		&& row < MAX_ROW&&col  < MAX_COL
    		&&mine_map[row ][col ] == '1') {
    		++count;
    	}
    	if (row >= 0 && col + 1 >= 0
    		&& row < MAX_ROW&&col + 1 < MAX_COL
    		&&mine_map[row][col + 1] == '1') {
    		++count;
    	}
    	if (row+1 >= 0 && col -1 >= 0
    		&& row+1 < MAX_ROW&&col < MAX_COL
    		&&mine_map[row+1][col] == '1') {
    		++count;
    	}
    	if (row +1>= 0 && col >= 0
    		&& row +1< MAX_ROW&&col< MAX_COL
    		&&mine_map[row+1][col] == '1') {
    		++count;
    	}
    	if (row+1 >= 0 && col + 1 >= 0
    		&& row+1 < MAX_ROW&&col + 1 < MAX_COL
    		&&mine_map[row+1][col + 1] == '1') {
    		++count;
    	}
    
    	//得到了周围8个格子地雷的个数
    	show_map[row][col] = '0' + count;
    
    }
    
    
    void Game() {
    	//1.创建地图,并且初始化..
    	char show_map[MAX_ROW][MAX_COL];
    	char mine_map[MAX_ROW][MAX_COL];
    	//创建一个变量,表示已经翻开非地雷个数
    	int blank_count_already_show = 0;
    	Init(show_map, mine_map);
    	while (1) {
    
    		//2.打印地图
    		PrintMap(show_map);
    		//3.让用户输入坐标,并进行合法性检验
    		printf("请输入一组坐标(row col):");
    		int row = 0;
    		int col = 0;
    		scanf("%d %d", &row, &col);
    		//在这里进行清屏,
    		system("cls");
    		//3.合法性检测
    		if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) {
    			printf("您的输入非法!请重新输入!\n");
    			continue;
    		}
    		if (show_map[row][col] != '*') {
    			printf("您输入的位置已经翻开了");
    			continue;
    		}
    		//4.判定是否是地雷
    		if (mine_map[row][col] == '1') {
    			printf("游戏结束!\n");
    			PrintMap(mine_map);
    			break;
    		}
    		//5.判定游戏是否胜利,
    		//判定所有非地雷位置是否全部翻开
    		++blank_count_already_show;
    		if (blank_count_already_show == MAX_COL * MAX_ROW - MINE_COUNT) {
    			printf("游戏胜利!\n");
    			PrintMap(mine_map);
    			break;
    		}
    		//6.统计当前位置周围雷的个数
    		UpdateShowMap(row,col,show_map,mine_map);
    
    	}
    }
    
    int main() {
    	while (1) {
    		int choice = Menu();
    		if (choice == 1) {
    			Game();
    		}
    		else if (choice == 0) {
    			printf("退出游戏,再见!");
    			break;
    		}
    		else {
    			printf("您的输入有误!");
    		}
    	}
    	system("pause");
    	return 0;
    }

     

猜你喜欢

转载自blog.csdn.net/weixin_44749767/article/details/89318271
今日推荐