功能实现:
- 地图创建,玩家地地图和地雷布局图
- 输入位置坐标合法性判定和胜负判定
解题分析:
- 创建两个二维数组表示两个地图:
- a)玩家看到的地图show_map,已翻开(数字表示)和未翻开(*表示)两种状态;
- b)地雷布局图mine_map,每个位置是否有地雷(0表示是地雷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
-
- 进行地图初始化
- show_map初始化,每个元素设为 *
- mine_map初始化,随机生成若干个个地雷
- 打印地图
- 提示用户输入一个坐标,表示要翻开某个位置(进行必要合法性判定)
- 坐标判定:
- 判定该位置是否是地雷,如果是地雷,游戏结束
- 如果不是地雷,判定是否游戏胜利(把所有不是地雷的格子翻开则胜利)
- 如果没有胜利,给当前位置的格子生成一个数字表示周围有几个雷
- 计算点击位置周围雷的数目
- 遍历目标单位上下左右共八个格子就可以了,
-
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
主函数:
- 主函数内获取菜单函数返回值,
- 进入选择程序,判断是否进行游戏;
- 代码示例:
-
int main() { while (1) { int choice = Menu(); if (choice == 1) { Game(); } else if (choice == 0) { printf("退出游戏,再见!"); break; } else { printf("您的输入有误!"); } } system("pause"); return 0; }
菜单函数Menu():
- 提示用户进行选择,返回值为用户选择,在主函数内得到判断;
- 代码示例:
-
int Menu() { printf("==================================\n"); printf(" 1.开始游戏\n"); printf(" 0.退出游戏\n"); printf("==================================\n"); printf("请输入您的选项:"); int choice = 0; scanf("%d", &choice); return choice; }
运行示例:
-
游戏函数:
- 创建两个二维数组,用来表示地图;
- 定义一个函数 Init() ,对地图进行初始化;
- 定义一个函数 PrintMap(),进行地图打印;
- 提示用户输入坐标,并对坐标进行合法性检验;
- 坐标合法后在检测输入位置是否有雷;
- 判定游戏是否胜利;
- 定义一个函数,统计当前位置地雷个数;
- 代码示例:
-
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); } }
地图初始化函数:
- 地图初始化,遍历地图每一个位置坐标,并设置为*;
- 对于mine_map,随机生成若干个地雷,这里设置地雷生成10个
- 使用0表示不是地雷,使用1表示是地雷
- 生成一组随机坐标,判断坐标合法性,并判断坐标处是否已经埋雷;
- 代码示例:
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; }
全部代码:
-
#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; }