问题描述:相信大多数人都很熟悉扫雷游戏,在n*n的雷盘上随机埋上一些雷,玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。
游戏设计:
在test.c里,完成了游戏的框架实现
首先,我们写一个test()函数测试我们写出的小游戏
void test() { int input = 0; do { menu(); srand((unsigned)time(NULL)); printf("请输入选项:"); scanf("%d",&input); switch(input) { case 1: game(); break; case 0: printf("退出游戏"); break; default: printf("输入错误,请重新输入: "); break; } }while(input); }
接着就是菜单函数,辅助玩家选择
void menu() { printf("********************** "); printf("**** 1.play ******** "); printf("**** 0.exit ******** "); printf("********************** "); }
最后就是我们的游戏实现部分啦
void game() { int ret = 0; char mine[ROWS][COLS] = {0}; char show[ROWS][COLS] = {0}; InitBoard(mine,ROWS,COLS,'0'); InitBoard(show,ROWS,COLS,'*'); DisplayBoard(show,ROWS,COLS); printf(" "); //DisplayBoard(mine,ROWS,COLS); Setmine(mine,ROW,COL); DisplayBoard(mine,ROWS,COLS); while (1) { int ret=FineMine(mine,show,ROW,COL); if(ret==0) break; else if(ret==1) { printf("被雷炸死 "); DisplayBoard(show,ROWS,COLS); printf(" "); DisplayBoard(mine,ROWS,COLS); printf(" "); break; } DisplayBoard(show,ROWS,COLS); printf(" "); } }
接着我们就得实现游戏函数的主要细节实现:
1、函数声明部分
game.h
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define ROWS 10 #define COLS 10 #define ROW 8 #define COL 8 #define COUNT 5 void InitBoard(char board[ROWS][COLS],int rows,int cols, char c); void DisplayBoard(char board[ROWS][COLS],int row,int col); void Setmine(char board[ROWS][COLS],int row,int col); int FineMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col); int count_show(char board[ROWS][COLS],int row ,int col);
2、函数的细节实现
game.c
首先利用memset函数初始化棋盘
void InitBoard(char board[ROWS][COLS],int rows,int cols, char c) { memset(board,c,rows*cols*sizeof(char)); }
打印棋盘实现
void DisplayBoard(char board[ROWS][COLS],int rows,int cols) { int i = 0; int j = 0; for (i = 0; i <rows - 1; i++) { printf("%d ", i); } printf(" "); for (i = 1; i <rows - 2; i++) { printf("%d ", i); for (j = 1; j < cols - 1; j++) { printf("%c ", board[i][j]); } printf(" "); } printf("%d ",rows-2); for (i = 1; i < rows - 1; i++) { printf("%c ", board[rows-2][i]); } printf(" "); }
利用rand()函数随机埋雷
void Setmine(char board[ROWS][COLS],int row,int col) { int x = 0; int y = 0; int count = COUNT; while (count) { int x = rand() % row + 1; int y = rand() % row + 1; if (board[x][y] == '0') { board[x][y] = '1'; count--; } } }
扫雷过程(判断输赢):
int FineMine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col) { int x = 0; int y = 0; int count = 0; printf("输入坐标扫雷 "); scanf("%d %d", &x, &y); if ((x >= 1 && x <= row) && (y >= 1 && y <= row)) { if (mine[x][y] == '0') { char ch = count_mine(mine,x,y); show[x][y] = ch+'0'; open_mine(mine,show,x, y); if (count_show(show,row,col) == COUNT) { DisplayBoard(show,ROWS,COLS); printf("玩家赢! "); DisplayBoard(mine,ROWS,COLS); printf(" "); return 0; } } else if (mine[x][y]=='1') { return 1; } } else { printf("输入错误重新输入 "); } }
在扫雷函数中我们需要一些功能函数地辅助。
判断周围雷的个数
static char count_mine(char board[ROWS][COLS],int x, int y) { int count = 0; if (board[x - 1][y - 1] == '1') count++; if (board[x - 1][y] == '1') count++; if (board[x - 1][y + 1] == '1') count++; if (board[x][y - 1] == '1') count++; if (board[x][y + 1] == '1') count++; if (board[x + 1][y - 1] == '1') count++; if (board[x + 1][y] == '1') count++; if (board[x + 1][y + 1] == '1') count++; return count; }
展开扫雷
static void open_mine(char mine[ROWS][COLS],char show[ROWS][COLS],int x, int y) { if (mine[x - 1][y - 1]== '0') { show[x - 1][y - 1] = count_mine(mine,x - 1, y - 1) + '0'; } if (mine[x - 1][y] == '0') { show[x - 1][y] = count_mine(mine,x - 1, y) + '0'; } if (mine[x - 1][y + 1] == '0') { show[x - 1][y + 1] = count_mine(mine,x - 1, y + 1) + '0'; } if (mine[x][y - 1] == '0') { show[x][y - 1] = count_mine(mine,x, y - 1) + '0'; } if (mine[x][y + 1] == '0') { show[x][y + 1] = count_mine(mine,x, y + 1) + '0'; } if (mine[x + 1][y - 1] == '0') { show[x + 1][y - 1] = count_mine(mine,x + 1, y - 1) + '0'; } if (mine[x + 1][y] == '0') { show[x + 1][y] = count_mine(mine,x + 1, y) + '0'; } if (mine[x + 1][y + 1] == '0') { show[x + 1][y + 1] = count_mine(mine,x + 1, y + 1) + '0'; } }
最后统计是否扫除雷外所有非雷格
int count_show(char board[ROWS][COLS],int row ,int col) { int count = 0; int i = 0; int j = 0; for (i = 1; i <= row; i++) { for (j = 1; j <= col; j++) { if (board[i][j] == '*') { count++; } } } return count; }
以上就是我关于扫雷写的一个简单的小程序,还很稚嫩,会持续更新改进的。