相信大家都玩过扫雷吧,以前机房上机,无聊的时候就开始玩扫雷和蜘蛛纸牌,有时候能玩好久好久。那今天,我们就来写一个简易的扫雷游戏吧!
和三子棋游戏一样,我们先把它需要的游戏功能列出来:
(1)void Menu();菜单
(2)void Game();游戏框架
(3)int GetRandIndex(int start, int end);随机生成雷的下标
(4)void SetMines(char mineboard[][COL], int row, int col);埋雷数组
(5)char ShowBoard(char mineboard[][COL], int row, int col);扫雷数组
(6)int GetMines(char mineboard[][COL], int row, int col);判断用户选择的坐标周围有几个雷
接下来,我们依次实现这些子程序
1.菜单
void Menu() { printf("#########################\n"); printf("##### 1.Play
#####\n"); printf("##### 2.Exit #####\n");
printf("#########################\n"); printf("Please select:"); }
2.随机生成雷的下标,并且埋雷。
在生成随机数时,我们采用了 rand() % (end - start + 1) + start;
start和end是我们需要的随机数的范围。
int GetRandIndex(int start, int end) //随机生成埋雷下标 { return rand() % (end - start
+ 1) + start; } void SetMines(char mineboard[][COL], int row, int col) //埋雷 {
srand((unsigned long)time(NULL)); //随机数种子 int count = 0; while (count <
Mine_Num){ int x = GetRandIndex(1, 10); int y = GetRandIndex(1, 10); if
(mineboard[x][y] == '0'){ mineboard[x][y] = '1'; count++; } } }
3.显示用户所选坐标周围有几个雷,我们在这里要注意,该函数的返回值为整型,但得到的mineboard为"1"的字符型,我们知道字符其实在ASCII码中也是一个阿拉伯数字。所以要得到阿拉伯数字就需要减去七个字符‘0’。
int GetMines(char mineboard[][COL], int row,int col) //显示周围雷的数目 { return
mineboard[row - 1][col - 1] + mineboard[row - 1][col] + mineboard[row - 1][col
+ 1] + mineboard[row][col - 1] + \ mineboard[row][col + 1] + mineboard[row +
1][col - 1] + mineboard[row + 1][col] + mineboard[row + 1][col + 1] - 7 * '0'; }
4.展示棋盘,我们要明白在这个程序中,我们用了俩个数组,一个用来埋雷,一个用来给用户展示。而这个展示棋盘就是用来给用户扫雷并展示的。
char ShowBoard(char showboard[][COL], int row, int col) { int i = 0; int j =
0; printf(" "); for (i = 1; i <= 10; i++){ printf("%d ", i); } printf("\n");
for (i = 0; i < col-1; i++){ printf("----"); } printf("\n"); for (i = 1; i <=
row - 2; i++) { printf("%-2d|", i); for (j = 1; j <= col - 2; j++) { printf("
%c |", showboard[i][j]); } printf("\n"); int k = 1; for (k = 1; k <= col - 1;
k++) { printf("----"); } printf("\n"); } }
5.整个游戏的框架。
oid Game() { char mineboard[ROW][COL]; char showboard[ROW][COL];
memset(mineboard, '0', sizeof(mineboard)); //将埋雷数组全都清0 memset(showboard, '*',
sizeof(showboard)); //将扫雷数组全都置* SetMines(mineboard, ROW, COL); //随机设置雷 int
count = TOTAL; int x = 0; int y = 0; while (1){ ShowBoard(showboard, ROW, COL);
printf("Please select<x,y>:"); scanf("%d %d", &x, &y); if (x >= 1 && x <= ROW -
2 && y >= 1 && y <= COL - 2){ if (mineboard[x][y] == '0'){ char num =
GetMines(mineboard, x, y); showboard[x][y] = num; //Showboard(mineboard, ROW,
COL); count--; if (count <= 20){ printf("恭喜你,完美避开所有的雷区!\n"); break; } } else{
printf("实在是太遗憾了,你被炸死了!\n"); break; } } else{ printf("输入有误,请重新选择!\n"); } } }
未了避免代码冗余,且可读性强,我们这里使用头文件进行函数声明等。
函数声明 mine.h
#ifndef _MINE_H_ #define _MINE_H_ #include<stdio.h> #include<windows.h>
#include<time.h> #pragma warning(disable:4996) #define ROW 12 #define COL 12
#define TOTAL 10*10 #define Mine_Num 20 void Menu(); void Game(); int
GetRandIndex(int start, int end); void SetMines(char mineboard[][COL], int row,
int col); char ShowBoard(char mineboard[][COL], int row, int col); int
GetMines(char mineboard[][COL], int row, int col); #endif
函数实现 mine.c
#include "mine.h" int GetRandIndex(int start, int end) //随机生成埋雷下标 { return
rand() % (end - start + 1) + start; } void SetMines(char mineboard[][COL], int
row, int col) { srand((unsigned long)time(NULL)); int count = 0; while (count <
Mine_Num){ int x = GetRandIndex(1, 10); int y = GetRandIndex(1, 10); if
(mineboard[x][y] == '0'){ mineboard[x][y] = '1'; count++; } } } int
GetMines(char mineboard[][COL], int row,int col) //显示周围雷的数目 { return
mineboard[row - 1][col - 1] + mineboard[row - 1][col] + mineboard[row - 1][col
+ 1] + mineboard[row][col - 1] + \ mineboard[row][col + 1] + mineboard[row +
1][col - 1] + mineboard[row + 1][col] + mineboard[row + 1][col + 1] - 7 * '0';
} char ShowBoard(char showboard[][COL], int row, int col) { int i = 0; int j =
0; printf(" "); for (i = 1; i <= 10; i++){ printf("%d ", i); } printf("\n");
for (i = 0; i < col-1; i++){ printf("----"); } printf("\n"); for (i = 1; i <=
row - 2; i++) { printf("%-2d|", i); for (j = 1; j <= col - 2; j++) { printf("
%c |", showboard[i][j]); } printf("\n"); int k = 1; for (k = 1; k <= col - 1;
k++) { printf("----"); } printf("\n"); } } void Game() { char
mineboard[ROW][COL]; char showboard[ROW][COL]; memset(mineboard, '0',
sizeof(mineboard)); //将埋雷数组全都清0 memset(showboard, '*', sizeof(showboard));
//将扫雷数组全都置* SetMines(mineboard, ROW, COL); int count = TOTAL; int x = 0; int y
= 0; while (1){ ShowBoard(showboard, ROW, COL); printf("Please select<x,y>:");
scanf("%d %d", &x, &y); if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= COL - 2){
if (mineboard[x][y] == '0'){ char num = GetMines(mineboard, x, y);
showboard[x][y] = num; //Showboard(mineboard, ROW, COL); count--; if (count <=
20){ printf("恭喜你,完美避开所有的雷区!\n"); break; } } else{ printf("实在是太遗憾了,你被炸死了!\n");
break; } } else{ printf("输入有误,请重新选择!\n"); } } }
主函数main.c
#include "mine.h" void Menu() { printf("#########################\n");
printf("##### 1.Play #####\n"); printf("##### 2.Exit #####\n");
printf("#########################\n"); printf("Please select:"); } int main() {
int select = 0; int quit = 0; while (quit!=1){ Menu(); scanf("%d", &select);
switch (select){ case 1: Game(); break; case 2: printf("Bye-bye!\n"); quit = 1;
break; default: printf("Select error!Please select again!\n"); break; } } }
运行结果: