一、简介
其中包括一个头文件function.h
两个源文件game.c和function.c
二、function.h代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE 10
void menu();
void initial_show_board(char show_board[ROW][COL]);
void lay_mine(int data_board[ROWS][COLS]);
void scan_mine(int data_board[ROWS][COLS], char show_board[ROW][COL]);
void printf_data_board(int data_board[ROWS][COLS]);
void printf_show_board(char show_board[ROW][COL]);
int sum_mine(int data_board[ROWS][COLS], int row, int col);
void scan_diffusion(int data_board[ROWS][COLS], char show_board[ROW][COL], int x, int y, int* win);
void printf_result(int data_board[ROWS][COLS], char show_board[ROW][COL]);
三、function.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"function.h"
void menu() {
printf("********************\n");
printf("****** 1.play ******\n");
printf("****** 2.exit ******\n");
printf("****** 3.rule ******\n");
printf("********************\n");
printf("\n请输入1或2或3进行选择:>");
}
void initial_show_board(char show_board[ROW][COL]) {
for (int row=0;row < ROW;row++) {
for (int col=0;col < COL;col++) {
show_board[row][col] = '*';
}
}
}
void lay_mine(int data_board[ROWS][COLS]) {
//埋雷下标范围为1--9即(1--(ROWS-2))
int mine = 0;
srand((unsigned)time(NULL));
while(mine < MINE) {
int rows= rand() % (ROWS-2) + 1;
int cols= rand() % (COLS-2) + 1;
if (data_board[rows][cols] == 0) { //此处用if判断的目的是防止在同一位置重复埋雷
data_board[rows][cols] = 1;
mine++;
}
else
;
}
}
void scan_mine(int data_board[ROWS][COLS], char show_board[ROW][COL]) {
int x = 0;
int y = 0;
int win = 0; //计数器,计算已经扫描的区域
while (win<(ROW*COL-MINE)) {
printf_show_board(show_board);
printf("\n");
printf("请输入扫雷坐标:>");
scanf("%d%d", &x, &y);
if ((x >= 1 && x <= COL) && (y >= 1 && y <= ROW)) { //x和y必须合法
//用户输入x=9,y=1代表
//在show棋盘中的第1行第9列,对应下标为[y-1][x-1]
//在data棋盘中的第2行第10列,对应下标为[y][x]
if (data_board[y][x] == 1) {
show_board[y-1][x-1] = 'X';
printf("game over\n\n");
printf_result(data_board, show_board);
Sleep(2000);
break;
}
else {
if(show_board[y - 1][x - 1] != '*')
printf("此坐标已扫描\n\n");
else
scan_diffusion(data_board, show_board, x, y,&win);
}
}
else
printf("非法输入\n\n");
}
if (win == (ROW * COL - MINE)){
printf("扫雷成功\n\n");
printf_result(data_board, show_board);
Sleep(2000);
}
}
void printf_result(int data_board[ROWS][COLS], char show_board[ROW][COL]) {
for (int row = 1;row < (ROWS-1);row++) {
for (int col = 1;col < (COLS-1);col++) {
if (data_board[row][col] == 1)
show_board[row - 1][col - 1] = 'X';
}
}
}
int sum_mine(int data_board[ROWS][COLS], int row, int col) {
//统计此坐标周围的8个坐标中值的总数
int sum = data_board[row][col + 1] + data_board[row][col - 1]
+ data_board[row + 1][col + 1] + data_board[row + 1][col] + data_board[row + 1][col - 1]
+ data_board[row - 1][col + 1] + data_board[row - 1][col] + data_board[row - 1][col - 1];
return sum;
}
void scan_diffusion(int data_board[ROWS][COLS], char show_board[ROW][COL], int x, int y, int* win) {
if (show_board[y - 1][x - 1] == '*') {
*win = *win + 1;
int numb_mine = sum_mine(data_board, y, x); //统计周围8格的雷数
if (numb_mine != 0) {
show_board[y - 1][x - 1] = 48 + numb_mine; //show_board是char型,对照ascll码表,数字0ascll码为48
}
else {
show_board[y - 1][x - 1] = ' ';
//用递归的思想传递扫描
int min_x = x - 1;
int max_x = x + 1;
int min_y = y - 1;
int max_y = y + 1;
int temp_x = x;
int temp_y = y;
if ((min_x >= 1 && min_x <= COL) && (y >= 1 && y <= ROW)) {
x = min_x;
scan_diffusion(data_board, show_board, x, y, win);
}
x =temp_x; //每一个if语句之间要相互独立,上一个if不能影响到下一个if的x和y值
y = temp_y;
if ((max_x >= 1 && max_x <= COL) && (y >= 1 && y <= ROW)) {
x = max_x;
scan_diffusion(data_board, show_board, x, y, win);
}
x = temp_x;
y = temp_y;
if ((min_x >= 1 && min_x <= COL) && (min_y >= 1 && min_y <= ROW)) {
x = min_x;
y = min_y;
scan_diffusion(data_board, show_board, x, y, win);
}
x = temp_x;
y = temp_y;
if ((x >= 1 && x <= COL) && (min_y >= 1 && min_y <= ROW)) {
y = min_y;
scan_diffusion(data_board, show_board, x, y, win);
}
x = temp_x;
y = temp_y;
if ((max_x >= 1 && max_x <= COL) && (min_y >= 1 && min_y <= ROW)) {
x = max_x;
y = min_y;
scan_diffusion(data_board, show_board, x, y, win);
}
x = temp_x;
y = temp_y;
if ((min_x >= 1 && min_x <= COL) && (max_y >= 1 && max_y <= ROW)) {
x = min_x;
y = max_y;
scan_diffusion(data_board, show_board, x, y, win);
}
x = temp_x;
y = temp_y;
if ((x >= 1 && x <= COL) && (max_y >= 1 && max_y <= ROW)) {
y = max_y;
scan_diffusion(data_board, show_board, x, y, win);
}
x = temp_x;
y = temp_y;
if ((max_x >= 1 && max_x <= COL) && (max_y >= 1 && max_y <= ROW)) {
x = max_x;
y = max_y;
scan_diffusion(data_board, show_board, x, y, win);
}
}
}
}
void printf_data_board(int data_board[ROWS][COLS]) {
for (int row=1;row < ROWS-1;row++) {
for (int col=1;col < COLS-1;col++) {
printf("%d ", data_board[row][col]);
}
printf("\n");
}
}
void printf_show_board(char show_board[ROW][COL]) {
int x = 0; //打印x和y的坐标
int y = 1;
for (x;x <= COL;x++)
printf("%d ", x);
printf("\n");
for (int row=0;row < ROW;row++) {
printf("%d ", y);
y++;
for (int col=0;col < COL;col++) {
printf("%c ", show_board[row][col]);
}
printf("\n");
}
}
四、game.c代码
#define _CRT_SECURE_NO_WARNINGS 1
#include"function.h"
void game() {
int data_board[ROWS][COLS] = { 0 }; //数据棋盘11x11
char show_board[ROW][COL] = { 0 }; //展示棋盘9x9
initial_show_board(show_board); //初始化棋盘
lay_mine(data_board); //布设地雷
//printf_data_board(data_board); //调试时查看data_board
//printf("\n");
scan_mine(data_board, show_board); //扫雷
printf_show_board(show_board);
printf("\n");
Sleep(5000);
}
int main() {
while (1) {
int input = 0;
menu();
scanf("%d", &input);
switch (input) {
case 1:
printf("\n扫雷\n\n");
game();
break;
case 2:
printf("\n退出游戏\n");
break;
case 3:
printf("\n输入坐标后,*下显示的数字为周围地雷总数(周围指上下左右和右上右下左上左下,共八个位置)\n\n");
break;
default:
printf("\n非法输入\n\n");
break;
}
if (input == 2)
break;
}
return 0;
}
五、写程序时犯的错误
1.在二维数组传参时报错:访问权限冲突。
收集资料后发现这种报错通常是由数组访问越界引起的,但检查逻辑之后并没有发现此类型错误,最后发现是二维数组传参时格式错误。
定义函数时应为function(arr[a][b]),但使用函数时直接function(arr),不要加下标!
2.传址调用在递归中的转变
在scan_diffusion函数里我们想控制函数之外的变量,所以用了传址调用,把int型win(定义的变量,用于计数)转为了指针,但在递归时scan_diffusion函数反复调用它本身,此时win已经是指针,不用再&win,应直接用win。
标签:语言,show,实现,int,扫雷,board,&&,printf,data From: https://blog.51cto.com/u_16102535/6346815