前言
(本文章没有将扫雷的爆炸式展开实现,将放在下一篇文章中实现。)
依旧是跑路的我,今天搞了搞扫雷再次巩固一下基础知识,准备c语言进阶了。
扫雷嘛,大家基本都玩过所以就不过多介绍了先把这次代码的思路放在下面:
我们依旧分为三个源文件来进行程序设计分别是
test.c 负责程序的设计主函数的布置
game.c 负责函数的实现
game.h 负责函数的引用以及定义宏
一、代码及易错分析
test.c 内容
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void meun() { printf("++++++++++++++++++++++++++++++\n"); printf("++++++++++ 1.play ++++++++++++\n"); printf("++++++++++ 0.exit ++++++++++++\n"); printf("++++++++++++++++++++++++++++++\n"); } void game() { char mark1 = '0'; char mark2 = '*'; char show[ROWS][COLS] = { 0 };//布置的数组 char mine[ROWS][COLS] = { 0 };//储存雷的数组 //数组的初始化。 Initboard(show, ROWS, COLS, mark2);//初始化show Initboard(mine, ROWS, COLS, mark1);//初始化mine //布置雷 setmine(mine, ROW, COL); //数组的打印 display(show, ROW, COL); //display(mine, ROW, COL);//用来储存雷的信息 //排雷 playmove(show, mine, ROW, COL); } int main(void) { int i = 0; do { srand(time(NULL));//设置随机数 meun(); printf("请输入1/0>:"); scanf("%d", &i); switch (i) { case 1: printf("开始三子棋游戏\n"); game(); break; case 0: printf("退出成功\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (i); return 0; }
game.c
#define _CRT_SECURE_NO_WARNINGS 1 #include "game.h" void Initboard(char board[ROWS][COLS], int rows, int cols, char mark) { int n = 0; int i = 0; for (i = 0; i < cols; i++) { for (n = 0; n < rows; n++) { board[n][i] = mark; } } } //易错点在传参时依旧要将board[ROWS][COLS] //二维数组要一致 //行列按需要传输 void display(char board[ROWS][COLS],int row,int col) { int i = 0; int j = 0; printf("0"); for (i = 1; i <= row; i++) { printf(" %d", i); } printf("\n"); for (i = 1; i <= col; i++)//从1行1列开始打印 { printf("%d", i); for (j = 1; j <= row; j++)//从1行1列开始打印 { printf(" %c", board[i][j]);//易错点一定是先打印一行而后换行打印列 } printf("\n"); } } void setmine(char mine[ROWS][COLS], int row, int col)//布置雷 { int count = COUNT;//使用COUNT在头文件里定义可以方便未来改数据 while (count) { unsigned int x = rand() % row+1; unsigned int y = rand() % col+1; if (mine[x][y] == '0') { mine[x][y] = '1'; count--; } } } int count(char mine[ROWS][COLS], int x, int y)//计算游戏次数到达次数后胜利 { return mine[x - 1][y] +mine[x - 1][y - 1] +mine[x][y - 1] +mine[x + 1][y - 1] +mine[x+1][y] +mine[x+1][y+1] +mine[x][y+1] +mine[x-1][y+1]-8*'0'; } void playmove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col) { int x = 0; int y = 0; while (1) { printf("请输入坐标>:"); scanf("%d %d", &x, &y); int win = 0; if (x >= 1 && x <= row && y >= 1 && y <= col) { if (mine[x][y] == '1') { //碰到雷死亡. printf("你碰到雷了\n"); printf("游戏结束\n"); break; } else if (mine[x][y] == '0') { //正常进行 int z = count(mine, x, y); show[x][y] = z + '0';//因为要用字符数字所以加上'0' display(show, ROW, COL); win++; } } else { printf("输入错误,请重新输入。\n"); } if (win == row * col - COUNT) { printf("恭喜你,成功排完所有雷\n"); break; } } }
易错点在相应位置注释处
我在这里总结性强调一下
1.在接收二维数组时一定要与传递的二维数组保持一致列和行数。
2.在display函数打印时一定要注意从行开始打印不然后续程序都会出问题。
3.在打印函数display要从第一行第一列开始打印(为了防止越界访问我们要将二维数组空出一圈及11 11的数组我们只用 9 9 )
game.h
声明和定义宏
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROWS 11 #define COLS 11 #define COUNT 10//雷的数目 #define ROW ROWS-2 #define COL COLS-2 void Initboard(char board[ROWS][COLS], int rows, int cols, char mark); void display(char board[ROW][COL], int row, int col); void setmine(char mine[ROWS][COLS], int row, int col); void playmove(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col);
增加扫雷的展开
void unfold(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y) { int ret = count(mine, x, y); if (ret == 0) { show[x][y] = ' '; if (x - 1 > 0 && y > 0 && show[x - 1][y] == '*') { unfold(show, mine, x - 1, y); } if (x - 1 > 0 && y-1 > 0 && show[x - 1][y-1] == '*') { unfold(show, mine, x - 1, y-1); } if (x - 1 > 0 && y+1 > 0 && show[x - 1][y+1] == '*') { unfold(show, mine, x - 1, y+1); } if (x > 0 && y > 0 && show[x][y] == '*') { unfold(show, mine, x, y); } if (x > 0 && y-1 > 0 && show[x][y-1] == '*') { unfold(show, mine, x, y-1); } if (x > 0 && y+1 > 0 && show[x][y+1] == '*') { unfold(show, mine, x, y+1); } if (x + 1 > 0 && y > 0 && show[x + 1][y] == '*') { unfold(show, mine, x + 1, y); } if (x + 1 > 0 && y > 0 && show[x + 1][y-1] == '*') { unfold(show, mine, x + 1, y-1); } if (x + 1 > 0 && y > 0 && show[x + 1][y+1] == '*') { unfold(show, mine, x + 1, y+1); } } }
使用递归完成
总结
(又把game.c 哪搬过来了方便查看)
1.在接收二维数组时一定要与传递的二维数组保持一致列和行数。
2.在display函数打印时一定要注意从行开始打印不然后续程序都会出问题。
3.在打印函数display要从第一行第一列开始打印(为了防止越界访问我们要将二维数组空出一圈及11 11的数组我们只用 9 9 )
后续文章会讲扫雷的爆炸式展开
再见咯