虫子 扫雷 众神起步,万语之基,软硬桥梁,帝国大厦

网友投稿 519 2022-05-28

扫雷

test.c

main

Meun菜单函数

game游戏函数

game.c文件

InitBoard初始化棋盘函数

DisplayBoard打印棋盘参数

SetMine放置雷函数

GetMineCount得到雷数函数

PutOneMine放单雷函数

ShowSpread显示展开函数

FindBoard排查雷函数

game.h

函数声明

测试图

次数限制

炸死

第一步开始连续踩雷,泉水无敌效应坐标2 3是有雷的

递归展开

赢了

扫雷

还是那个熟悉的味道,优化的扫雷,无限接近真正的扫雷。

test.c

还是从main入手,本人不太喜欢直接上代码,感觉那样的话博友会看不懂,我喜欢分开来讲解。废话不多说,直接上代码(哈哈开个玩笑)。

main

int main() { int input = 0; int num = 3;//不可连续选错的次数 int flag = 1;//这个我不想说了,三子棋里面有,就是次数标记 srand((unsigned)time(NULL));//随机数起点,与rand()搭配使用 /*别的不说,这游戏不管你玩不玩,总之你得玩一把,先和你说一声30个雷*/ do { Meun(); printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: if (flag == 0) { flag = 1; //标记取反 num = 3; //次数充满 } game(); //玩游戏 break; case 0: printf("退出游戏\n"); break; default: if (flag == 1) { flag = 0; //标记警告 } num--; if (num == 0) //到这里你就没机会了 { printf("你已经没有机会了。\n"); break; } printf("选错了,你还有%d次机会\n", num); break; } } while (input&&num); //输入0或次数没了就退出游戏 return 0; }

Meun菜单函数

void Meun() { printf("****************************\n"); printf("****1.play 0.exit*****\n"); printf("****************************\n"); }

game游戏函数

void game() { char mine[ROWS][COLS];//地雷数组 char show[ROWS][COLS];//排查雷数组 InitBoard(mine, ROWS, COLS,'0');//初始化放雷棋盘 InitBoard(show,ROWS,COLS,'*'); //初始化排查雷棋盘 //DisplayBoard(mine, ROW, COL);//打印放雷棋盘 DisplayBoard(show, ROW, COL);//打印排雷棋盘 SetMine(mine, ROW, COL); //布置雷 //DisplayBoard(mine, ROW, COL);//打印放雷棋盘 FindBoard(mine,show, ROW, COL); //排查雷 }

game.c文件

InitBoard初始化棋盘函数

棋盘初始化,这里到底初始化是么样的字符呢?写死’0’,show数组不行。写死’*’,mine数组也不行,那怎么办呢?所以我这里全都不要,我用一个参数set来承接,你要初始化什么样,你传给我的参数,然后再操作。

void InitBoard(char board[ROWS][COLS], int rows, int cols,char set) { int i = 0; for (i = 0; i < rows; i++) { int j = 0; for (j = 0; j < cols; j++) { board[i][j] = set;//set参数,你来啥我接啥 } } }

DisplayBoard打印棋盘参数

打印棋盘,这里打印就是我们所见的棋盘,那个为了防止数组溢出的外面一圈就不需要了。虽然我们这里虽然操作的是99的数组,但是我们传数组的时候还是1111的数组,所以用board这个11*11的数组来接收

void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0; printf("---------------------------------------\n"); /*这个循环是在打印列之前把序号打印出来*/ for (i = 0; i <= col; i++) { printf("%2d ", i);//为了看的方便,格式对齐所以用%2d } printf("\n"); for (i = 0; i <= col; i++) { if (0 == i) printf(" "); else printf("---"); } printf("\n"); for (i = 1; i <= row; i++) { int j = 0; printf("%2d|",i);//打印行之前把序号打印出来 for (j = 1; j <= col; j++) { printf(" %c ",board[i][j]); } printf("|");//行结束后打印个|分割线 printf("\n"); } for (i = 0; i <= col; i++)//列结束后打印分割线--- { if (0 == i) printf(" ");//0下面不需要分割线 else printf("---"); } printf("\n"); printf("---------------------------------------\n"); }

SetMine放置雷函数

布置雷,把雷放到mine数组里面

void SetMine(char board[ROWS][COLS], int row, int col) { int count = EASY_COUNT; while (count) { //布置雷生成随机下标(1-9) int x = rand() % row + 1; int y = rand() % col + 1; //如果board[x][y]不是雷才能把雷放进去,不然会少雷 if (board[x][y] != '*') { board[x][y] = '*'; count--; } } }

GetMineCount得到雷数函数

得到雷个数函数,因为我们放雷数组初始化是’0’,雷是’’,但我们从排查雷及其周围是定死33的数组,所以我们用循环把9个字符加起来再减9个’0’就能得到总共’*’-'0’的整数了,再除以它就可以得到count

int GetMineCount(char board[ROWS][COLS], int x, int y) { int i = 0; int sum = 0; int count = 0; for (i = x - 1; i <= x + 1; i++) { int j = 0; for (j = y - 1; j <= y + 1; j++) { sum = sum + (board[i][j] - '0'); } } return count = sum / ('*' - '0');//我们要灵活运用字符型和整型之间的切换 }

PutOneMine放单雷函数

放一个雷,防止第一步及之后连续踩雷就被炸死,这个代码就是保护那些脸黑的,怕他们没有游戏体验

void PutOneMine(char board[ROWS][COLS]) { while (1) { int x = rand() % ROW + 1; int y = rand() % COL + 1; if (board[x][y] != '*') { board[x][y] = '*';//把雷放进去就跳出 break; } } }

ShowSpread显示展开函数

显示展开函数,也就是递归展开排雷,这个函数大大增加了游戏的可玩性,我欲八面来风层层递归

void ShowSpread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { int count = 0;//计算雷个数 count = GetMineCount(mine, x, y); if (count == 0) { /*这里非常重要不然会死递归,很像对冲击波那样*/ show[x][y] = ' '; if ((x - 1) > 0 && (y - 1) > 0 && show[x - 1][y - 1] == '*') ShowSpread(mine, show, x - 1, y - 1); if((y-1)>0&&show[x][y-1] == '*') ShowSpread(mine, show, x , y - 1); if ((x + 1) <= ROW && (y - 1) > 0 && show[x - 1][y - 1] == '*') ShowSpread(mine, show, x + 1, y - 1); if ((x - 1) > 0&& show[x - 1][y] == '*') ShowSpread(mine, show, x - 1, y); if ((x + 1) <= ROW&& show[x + 1][y] == '*') ShowSpread(mine, show, x + 1, y); if ((x - 1) > 0 && (y + 1) <= COL && show[x - 1][y + 1] == '*') ShowSpread(mine, show, x - 1, y + 1); if ((y + 1) <= COL && show[x][y + 1] == '*') ShowSpread(mine, show, x, y + 1); if ((x + 1) <= ROW && (y + 1) <= COL && show[x + 1][y + 1] == '*') ShowSpread(mine, show, x + 1, y + 1); } else { show[x][y] = count + '0'; } }

FindBoard排查雷函数

虫子 扫雷 众神起步,万语之基,软硬桥梁,帝国大厦

排查雷,我们是通过排查mine数组,然后把信息传到show数组里面,我们还是操作99数组,但mine show一直都是1111的数组,为了防止查雷是溢出

void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int num = 3; int flag = 1; int mine_flag = 1; int win = 0; while (num&&(win"); scanf("%d%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (flag == 0) { flag = 1; num = 3; } if (mine[x][y] == '*') { if (mine_flag == 1) { mine[x][y] = '0'; PutOneMine(mine); //DisplayBoard(mine, ROW, COL); /*这步是更新周围雷数的*/ int count = GetMineCount(mine, x, y); show[x][y] = count + '0';//把得到的数给show数组,但count是整型,所以转成字符型(字符型-'0'=整型) DisplayBoard(show, ROW, COL); } else { printf("很遗憾,你被炸死了\n"); DisplayBoard(mine, ROW, COL); break; } } else {/*如果不是雷,我们就搜索该位置周围8个位置的雷的情况*/ win++; mine_flag = 0;//到了这里雷标记就没有了 if (mine[x][y] == '0' && show[x][y] == '*') { ShowSpread(mine, show, x, y);//显示展开 DisplayBoard(show, ROW, COL); } //int count = GetMineCount(mine,x,y); //show[x][y] = count + '0';//把得到的数给show数组,但count是整型,所以转成字符型(字符型-'0'=整型) //DisplayBoard(show, ROW, COL); } } else { if (flag == 1) { flag = 0; } num--; if (num == 0) { printf("你已经没有机会了"); break; } printf("输入坐标错误,你还有%d的输入机会", num); } } if (win == row * col - EASY_COUNT) printf("恭喜你排雷成功。\n"); }

game.h

上面的讲解是简易棋盘9乘9的,这里我就直接来个中等难度的15乘15的

#define ROW 15 #define COL 15 #define ROWS ROW+2 #define COLS COL+2 #define EASY_COUNT 30 //简单版本的地雷数

函数声明

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set); void DisplayBoard(char board[ROWS][COLS], int row, int col); void SetMine(char board[ROWS][COLS], int row, int col); void FindBoard(char mine[ROWS][COLS], char show[ROWS][COLS],int row, int col); int GetMineCount(char board[ROWS][COLS], int x, int y); void PutOneMine(char board[ROWS][COLS]); void ShowSpread(char mine[ROWS][COLS],char show[ROWS][COLS], int x, int y);

测试图

次数限制

炸死

第一步开始连续踩雷,泉水无敌效应坐标2 3是有雷的

但为了防止刚开始就死,看两幅图2 3雷被移走了,之后只要不是连续踩雷就不会出现这个情况

递归展开

赢了

9 2是唯一一个没有雷的

5G游戏 数据结构

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Redis持久化--RDB
下一篇:如何安装PyCharm【图文详解】
相关文章