文章目录
一、前言
大家应该都玩过扫雷游戏吧,大家可以先去玩一玩扫雷这个游戏,这样可以对自己写扫雷这个代码会有很大的帮助。
接下来我要给大家介绍扫雷游戏的实现步骤!!!
二、模块化编程
2.1 传统方式编程
所有的函数都放在 main.c 里面,这样会显得非常的乱,不利于组织管理并且影响你打代码时的思维。
2.2 模块化编程
把各个模块的代码放在不同的 .c 文件中,并且独立创建一个 .h文件写所有的头文件,然后用 #inculde “XXXXX.h” 去调用里面的头文件。
这样大大的提高了代码的可阅读性,可移植性,可维护性。。。。
三、编程思路
- 先用 do while 循环进入游戏程序打印菜单
- 定义存放雷的棋盘,展现给用户的棋盘
- 初始化雷的初始棋盘
- 打印
- 布置雷
- 扫雷(坐标是否合法)(是否被排查过)(是不是雷)
四、代码实现
4.1 菜单 menu()
菜单就是函数的一个界面
void menu()
{
printf("********************************\n");
printf("******* 1.play 0.exit *******\n");
printf("********************************\n");
}
4.2 主函数
int main()
{
//设计随机数
srand((unsigned int)time(NULL));
int input = 0;
do
{
//菜单
menu();
printf("请选择 : >");
scanf("%d", &input);
//判断输入
switch (input)
{
case 1:
printf("进入游戏!!!\n");
//进入游戏
game();
break;
case 0:
printf("退出游戏!!!\n");
break;
default:
printf("输入错误,请重新输入!!!\n");
break;
}
} while (input);
return 0;
}
4.2 实现扫雷行列可变化
//内行
#define ROW 9
//内列
#define COL 9
这样方便自己想修改棋盘大小
提升了效率,只需要改变宏定义
4.3 棋盘的初始化
使棋盘上的字符变成自己想要的字符
//初始化棋盘,set是实参传到形参的字符
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;
}
}
}
4.4 棋盘的打印
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");
}
printf("-------扫雷游戏-----\n");
}
效果图
4.5 布置雷的信息
void Set_T(char board[ROWS][COLS], int row, int col)
{
//设置雷数量
int count = EASY_COUNT;
//当雷数量为零停止循环
while (count)
{
//设置行和列的随机值
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
}
count--;
}
}
随机数
头文件 #include <time.h>
srand((unsigned int)time(NULL));
int a = rand() % 10 ; //0---9
int b = rand() % 100 ; //0---99
4.6 判断周围有多少雷
int get_mine_count(char board[ROWS][COLS], int x,int y)
{
return (board[x - 1][y] + board[x + 1][y] +
board[x - 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] +
board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y -1]-8*'0');
}
4.7 玩家扫雷
没有雷 ’ 0 ’
有雷 ’ 1 ’
坐标是否合法
是否被排查过
是不是雷
void Find_T(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 <= col && y >= 1 && y <= row)
{
//是否已经被排查过
if (show[x][y] != '*')
{
printf("你输入的坐标已经被排查过\n");
}
else
{
//是雷,被炸死
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else//如果不是雷
{
win++;
//统计mine数组中x,y坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';//转换成数字字符
DisplayBoard(show, ROW, COL);
}
}
}
else
{
printf("输入的坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
五、代码
game.h
#pragma once
#include <stdio.h>
//内行
#define ROW 9
//内列
#define COL 9
//外行
#define ROWS ROW+2
//外列
#define COLS COL+2
//雷的数量
#define EASY_COUNT 80
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);
//展示棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//放置雷
void Set_T(char board[ROWS][COLS], int row, int col);
//发现雷
void Find_T(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col);
test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
printf("********************************\n");
printf("******* 1.play 0.exit *******\n");
printf("********************************\n");
}
void game()
{
//存放地雷的棋盘
char mine[ROWS][COLS] = { 0 };
//展示给用户的棋盘
char show[ROWS][COLS] = { 0 };
//初始化棋盘
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印
DisplayBoard(show, ROW, COL);
//放置地雷
Set_T(mine, ROW, COL);
//开始扫雷
Find_T(mine,show, ROW, COL);
}
int main()
{
//设计随机数
srand((unsigned int)time(NULL));
int input = 0;
do
{
//菜单
menu();
printf("请选择 : >");
scanf("%d", &input);
//判断输入
switch (input)
{
case 1:
printf("进入游戏!!!\n");
//进入游戏
game();
break;
case 0:
printf("退出游戏!!!\n");
break;
default:
printf("输入错误,请重新输入!!!\n");
break;
}
} while (input);
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
int j = 0;
//遍历一遍使所有地方变成 ' 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");
}
printf("-------扫雷游戏-----\n");
}
//放置雷
void Set_T(char board[ROWS][COLS], int row, int col)
{
//设置雷数量
int count = EASY_COUNT;
//当雷数量为零停止循环
while (count)
{
//设置行和列的随机值
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
}
count--;
}
}
//得到中间数显示周围有多少雷
int get_mine_count(char board[ROWS][COLS], int x,int y)
{
return (board[x - 1][y] + board[x + 1][y] +
board[x - 1][y + 1] + board[x][y + 1] + board[x - 1][y + 1] +
board[x - 1][y - 1] + board[x][y - 1] + board[x + 1][y - 1]-8*'0');
}
//扫雷
void Find_T(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 <= col && y >= 1 && y <= row)
{
//是否已经被排查过
if (show[x][y] != '*')
{
printf("你输入的坐标已经被排查过\n");
}
else
{
//是雷,被炸死
if (mine[x][y] == '1')
{
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, ROW, COL);
break;
}
else//如果不是雷
{
win++;
//统计mine数组中x,y坐标周围有几个雷
int count = get_mine_count(mine, x, y);
show[x][y] = count + '0';//转换成数字字符
DisplayBoard(show, ROW, COL);
}
}
}
else
{
printf("输入的坐标非法,请重新输入\n");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
六、效果演示
还有炸金花式展开和插旗未完成以后更新,希望这个对大家有用!!!