打印
考虑如何实现图表
什么时候该打印
什么时候不该打印
打印的间距
换行的考虑
打印布局的美观性
参考代码
//打印棋盘 void DisplayBoard(char board[ROWS][COLS], int row, int col) { int i = 0;//在外围打印标数以便于玩家定位坐标 printf("-----------------------------------------\n"); for (i = 0; i <= 9; i++)//0-9打印最上排数字 { printf("| %d ", i); } printf("|\n"); printf("-----------------------------------------\n"); for (i = 1; i <= row; i++) { int j = 0; printf("| %d |", i);//1-9打印最左排数字 for (j = 1; j <= col; j++) { printf(" %c |", board[i][j]); } printf("\n");//一定注意要换行 printf("-----------------------------------------\n");//每打印一排内容,再打印一排横线,形成表格,提升美观 }
效果图
玩家排雷
考虑问题
1.因为实际雷区是11x11的,也就是说显示雷区的下标是从1开始的,符合玩家思维
2.排雷范围
3.第一次免雷
4.显示周围雷数
免雷
//第一次免雷 void FirstSafe(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int x, int y) { int count = 0; if (mine[x][y] == '1') { mine[x][y] = '0';//替换 while (1) { int rx = rand() % row + 1; int ry = rand() % col + 1; if (mine[rx][ry] == '0' && (rx != x) && (ry != y)) { mine[rx][ry] = '1';//再次布雷 break; } } count = GetMineCount(mine, x, y); show[x][y] = count + '0'; ExtendNotMine(mine, show, x, y, '0', '*'); DisplayShow(show, row, col); } }
査雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) { int x = 0; int y = 0; int win = 0; while (1) { printf("请输入要排查的坐标:>"); scanf("%d %d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col)//排查范围 { if (mine[x][y] == '1') { printf("很遗憾,你被炸死了\n"); DisplayBoard(mine, ROW, COL); break; } else { int count = GetMineCount(mine, x, y); show[x][y] = count + '0';//替换成字符数,显示雷数 DisplayBoard(show, ROW, COL); } } else { printf("坐标非法,重新输入\n"); } }
周围雷数
int GetMineCount(char mine[ROWS][COLS], int x, int y)//获取周边一圈雷个数的信息 { int ret = 0; for (int i = x - 1; i <= x + 1; i++) { for (int j = y - 1; j <= y + 1; y++)//3X3范围 { ret += mine[i][j]; } } return ret - mine[x][y] - 8 * '0';//注:'1'-'0'=1(ASCII码值) }//返回值代表雷的个数
雷区展开
考虑用递归实现
//扩展排雷,展开周围非雷区 void ExtendNotMine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) { int n = 0; n = GetMineCount(mine, x, y); if (n == 0) { show[x][y] = ' ';//如果周围没有雷,将中心赋值为空格 int i = 0; int j = 0; for (i = x - 1; i <= x + 1; i++) { for (j = y - 1; j <= y + 1; j++) { if (mine[i][j] =='0'&& show[i][j]=='*')//周围坐标满足自身不是雷且还是初始化字符,进入递归再次扩展排雷 { { ExtendNotMine(mine, show, i, j, '0', '*');//递归排雷 } } } } else show[x][y] = n + '0';//如果附近有雷,展示雷的个数 }
胜利判断
遍历雷区剩余的初始值个数进行判断
//求展示扫雷棋盘上含有初始化字符的个数,用来判断游戏何时终止 int AroundInitCount(char board[ROWS][COLS], int row, int col) { int i = 0; int j = 0; int count = 0; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (board[i][j] == '0') count++; } } return count; }
if (count == EASY_COUNT) { printf("恭喜你!扫雷成功!\n"); DisplayShow(mine, ROW, COL); break; }
显示用时
void SpendTime(clock_t start) { clock_t end = clock(); clock_t total = end - start; printf("游戏所用时间为:%.1lf秒!\n", 1.0 * total / CLOCKS_PER_SEC); }