设计总体思路
实现游戏可以一直玩,先打印棋盘,玩家和电脑下棋,最后分出胜负。
如果编写较大的程序,我们可以分不同模块
例如这个扫雷,我们可以创建三个文件
分别为:
- game.h 函数的声明
- game.c 函数的实现
- test.c 测试游戏逻辑
一、打印游戏菜单界面
首先要有开始界面并且有选项选择,开始你的游戏,代码以及效果图如下:
void menu()
{printf("*********************************************\n");printf("************* 1. play *********\n");printf("************* 0. exit *********\n");printf("*********************************************\n");
}int main()
{srand((unsigned int)time(NULL)); //随机数 无符号整型 时间戳 //头文件:stdlib.h time.hint input = 0;do {menu(); //先打印菜单printf("请选择>:"); //选项选择scanf("%d", &input);switch(input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}
二、初始化棋盘
test.c
void game()
{//mine数组是专门存放布置好的雷的信息char mine[ROWS][COLS] = {0};//show数组是专门存放排查出的雷的信息char show[ROWS][COLS] = {0};//初始化棋盘InitBoard(mine, ROWS, COLS, '0');//'0'InitBoard(show, ROWS, COLS, '*');//'*'
}
game.c
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set; #因为两次调用,数组填充不同,set("0","*")}}
}
三、打印棋盘
test.c
//打印棋盘
DisplayBoard(show, ROW, COL); //打印show数组
game.c
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("******* 扫雷 *******\n");for (j = 0; j <= col; j++){printf("%d ", j);}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}
}
四、布置雷
test.c
//布置雷
SetMine(mine,ROW,COL);
game.c
void SetMine(char mine[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count){//rand()随机生成范围0-32767int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}
五、排查雷
test.c
//排查雷
FindMine(mine,show,ROW,COL);
game.c
int GetMineCount(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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;while (win<row*col-EASY_COUNT){printf("请输入要排查的坐标>:");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (show[x][y] == '*'){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);win++;}}else{printf("该位置已经被排查\n");}}else{printf("排查的坐标非法,请重新输入\n");}}if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}
}
六、最后整理代码(完整代码)
game.h
#include<stdio.h>
#include<stdlib.h>
#include<time.h>//初始化棋盘
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 mine[ROWS][COLS], int row, int col);//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = set;}}
}void DisplayBoard(char board[ROWS][COLS], int row, int col)
{int i = 0;int j = 0;printf("******* 扫雷 *******\n");for (j = 0; j <= col; j++){printf("%d ", j);}printf("\n");for (i = 1; i <= row; i++){printf("%d ", i);for (j = 1; j <= col; j++){printf("%c ", board[i][j]);}printf("\n");}
}void SetMine(char mine[ROWS][COLS], int row, int col)
{int count = EASY_COUNT;while (count){//rand()随机生成范围0-32767int x = rand() % row + 1;int y = rand() % col + 1;if (mine[x][y] == '0'){mine[x][y] = '1';count--;}}
}int GetMineCount(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 FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{int x = 0;int y = 0;int win = 0;while (win<row*col-EASY_COUNT){printf("请输入要排查的坐标>:");scanf("%d %d", &x, &y);if (x >= 1 && x <= row && y >= 1 && y <= col){if (show[x][y] == '*'){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);win++;}}else{printf("该位置已经被排查\n");}}else{printf("排查的坐标非法,请重新输入\n");}}if (win == row * col - EASY_COUNT){printf("恭喜你,排雷成功\n");DisplayBoard(mine, ROW, COL);}
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"void menu()
{printf("*********************************************\n");printf("************* 1. play *********\n");printf("************* 0. exit *********\n");printf("*********************************************\n");
}void game()
{//mine数组是专门存放布置好的雷的信息char mine[ROWS][COLS] = {0};//show数组是专门存放排查出的雷的信息char show[ROWS][COLS] = {0};//初始化棋盘InitBoard(mine, ROWS, COLS, '0');//'0'InitBoard(show, ROWS, COLS, '*');//'*'//打印棋盘DisplayBoard(show, ROW, COL);//布置雷SetMine(mine,ROW,COL);//DisplayBoard(mine, ROW, COL);//排查雷FindMine(mine,show,ROW,COL);}int main()
{srand((unsigned int)time(NULL)); //随机数 无符号整型 时间戳 //头文件:stdlib.h time.hint input = 0;do{menu(); //先打印菜单printf("请选择>:"); //选项选择scanf("%d", &input);switch (input){case 1:game();break;case 0:printf("退出游戏\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}
七、游戏展示
个人建议第一个坐标填1 1(这样比较好排)
扩展:
展开一片
标记是否是雷
计时器
记录剩余雷数量
展开一片满足下列条件:
- 该坐标不是雷
- 该坐标周围没有雷
- 该坐标没有被排查过
满足就再遍历该坐标周围的八个坐标
本文是简单版的扫雷,之后我会出一个进阶版的扫雷
希望会对你有所帮助