C语言详细讲解通过递归实现扫雷的展开

Nancy ·
更新时间:2024-11-10
· 1847 次阅读

目录

用户选择菜单

棋盘初始化

布置雷(随机布置)

打印棋盘

玩家下棋

棋盘展开

展开部分思维导图

展开函数最后一个else return 作用

周围雷个数判断

用户选择菜单 void menu() { printf("****************************\n"); printf("******** 1.play **********\n"); printf("******** 0.exit **********\n"); printf("****************************\n"); }

用户按1进入游戏

棋盘初始化 void Itnboard(char board[ROWS][COLS], int rows, int cols,char c) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j <cols; j++) { board[i][j] = c; } } }

创建数组,并对其进行初始化

布置雷(随机布置) void Setboard(char board[ROWS][COLS], int row, int col) { int count = Easy_count; while (count) { int x = rand() % row+1; int y = rand() % col+1; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } }

用time函数产生随机值

打印棋盘 void Displayboard(char board[ROWS][COLS], int row, int col) { int i, j; for (i = 0; i <= col; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } }

打印棋盘

玩家下棋 void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x, y; int count = 0; while (1) { printf("请排雷:\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= 9 && y >= 1 && y <= 9) { if (board[x][y] == '0') { Openboard(show, board, x, y); Displayboard(show, ROW, COL); } else if (board[x][y] == '1') { printf("你死了\n"); break; } } else { printf("请重新输入"); } int i, j; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (show[i][j] == '*') { count++; } } } if (count == Easy_count) { printf("成功\n"); //这里的判断条件是遍历整个数组,统计雷的个数,如果雷的个数等于所剩余未排的*,说明排雷成功 break; } } }

用户输入值,并进行判断,如果该位置没有雷,我们进入展开函数

棋盘展开 void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col) { if (row >= 1 && row <= ROW && col >= 1 && col <= COL) { int count=sum(board, row, col); if (count != 0) { show[row][col] = count + '0'; } else if (show[row][col] != '_') { show[row][col] = '_'; int i = 0, j = 0; for (i = row - 1; i <= row + 1; i++) { for (j = col - 1; j <= col + 1; j++) { Openboard(show, board, i,j); } } } else { return; } } }

如果用户输入的这个位置没有雷,我们对其周围8个位置进行判断是否有雷,若有雷,我们把雷的个数显示在该位置上,若其周围8个位置没有雷并且不是下划线,我们把这个位置赋值为下划线,然后并对其8个位置进行同样的判断,如果周围没雷,而且周围的棋子也不是下划线,我们对其进行返回。

展开部分思维导图

展开函数最后一个else return 作用

这里我们show棋盘有三种情况,

1.该位置是*

2.该位置是下划线

3.该位置是雷的个数

else

return;

这里是作用:如果是下划线,我们就返回上一层函数。因为如果这里不是下划线,我们会在else return 之前的语句中进行判断,并对其周围8个位置进行操作,然后再对这8个棋子各个周围8个位置进行判断并操作,如果这里是下划线,就说明由这个位置为中心的周围8个棋子已经判断过了,并且以这8个位置为中心,已经递归过了,我们不需要再进行判断,所以直接返回就行

周围雷个数判断 int sum(char board[ROWS][COLS], int x, int y) { return (board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] - 8 * '0'); }

test.c

#include"game.h" void menu() { printf("****************************\n"); printf("******** 1.play **********\n"); printf("******** 0.exit **********\n"); printf("****************************\n"); } void game() { char board[ROWS][COLS] = { 0 }; char show[ROWS][COLS] = { 0 }; Itnboard(board, ROWS, COLS,'0'); //初始化棋盘 Itnboard(show, ROWS, COLS, '*'); Setboard(board, ROW, COL); Displayboard(board, ROW, COL); Player(board, show, ROW, COL); //玩家输入 } int main() { int input=1; srand((unsigned int)time(NULL)); do{ menu(); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: break; default: printf("输入错误请重新输入:\n "); } } while (input); }

game.c

#include"game.h" void Itnboard(char board[ROWS][COLS], int rows, int cols,char c) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j <cols; j++) { board[i][j] = c; } } } void Displayboard(char board[ROWS][COLS], int row, int col) { int i, j; for (i = 0; i <= col; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <= row; i++) { printf("%d ", i); for (j = 1; j <= col; j++) { printf("%c ", board[i][j]); } printf("\n"); } } void Setboard(char board[ROWS][COLS], int row, int col) { int count = Easy_count; while (count) { int x = rand() % row+1; int y = rand() % col+1; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } } int sum(char board[ROWS][COLS], int x, int y) { return (board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x][y - 1] + board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] - 8 * '0'); } void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x, y; int count = 0; while (1) { printf("请排雷:\n"); scanf("%d %d", &x, &y); if (x >= 1 && x <= 9 && y >= 1 && y <= 9) { if (board[x][y] == '0') { Openboard(show, board, x, y); Displayboard(show, ROW, COL); } else if (board[x][y] == '1') { printf("你死了\n"); break; } } else { printf("请重新输入"); } int i, j; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (show[i][j] == '*') { count++; } } } if (count == Easy_count) { printf("成功\n"); break; } } } void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col) { if (row >= 1 && row <= ROW && col >= 1 && col <= COL) { int count=sum(board, row, col); if (count != 0) { show[row][col] = count + '0'; } else if (show[row][col] != '_') { show[row][col] = '_'; int i = 0, j = 0; for (i = row - 1; i <= row + 1; i++) { for (j = col - 1; j <= col + 1; j++) { Openboard(show, board, i,j); } } } else { return; } } }

game.h

#include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 #define Easy_count 10 void Itnboard(char board[ROWS][COLS], int rows, int cols,char c); void Displayboard(char board[ROWS][COLS], int row, int col); void Setboard(char board[ROWS][COLS], int row, int col); void Player(char board[ROWS][COLS], char show[ROWS][COLS], int row, int col); void Openboard(char show[ROWS][COLS], char board[ROWS][COLS], int row, int col);

到此这篇关于C语言详细讲解通过递归实现扫雷的展开的文章就介绍到这了,更多相关C语言扫雷内容请搜索软件开发网以前的文章或继续浏览下面的相关文章希望大家以后多多支持软件开发网!



C语言 递归

需要 登录 后方可回复, 如果你还没有账号请 注册新账号