大纲:
本文章主要分为两个部分:
一. 扫雷游戏分析和设计
二. 扫雷游戏的代码实现
一. 扫雷游戏分析和设计
1)创建文件首先,我们将本项目创建2个源文件和一个头文件分别存储代码
如:test.c game.c game.h
在game.c 中,我们将敲出扫雷程序的主体代码。
在test.c 中,我们将敲出扫雷程序中所用的函数。
在game.h 中, 我们将列出本项目中所用函数的声明,及头文件。
通过这三个文件,便于以后我们对项扫雷游戏的更改,同时便于别人更容易理解项目(扫雷游戏)。
2)打印菜单
说起游戏,那么我们首先需要为游戏创建一个开始游戏的界面,我们可以通过连续使用C语言中“printf”函数的的方式来打印一个简易的界面
void menu()
{
printf("**************************\n");
printf("**********1.play**********\n");
printf("**********0.exit**********\n");
printf("**************************\n");
}
3)输入反馈
我们将运用switch函数,分三种情况对用户的输入做出反馈
void test()
{
int input = 0;
do
{
menu();
printf("Your choice:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("start!!!\n");
game();
break;
case 0:
printf("exit game!\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
注:不要忘记break!!!
4)游戏开始后的代码
我们将开始编写开始游戏的代码:
注:为方便后期更改,我们可以通过定义两个变量来确定棋盘的大小
即:
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10 //可改变数字来改变雷的数量
注:为防止数组越界和打印行数与列数,所以创建11*11的数组
与此同时,本项目通过创建11*11的数组也可以方便后期对坐标附近雷个数的计算
1创建并初始化数组
首先,我们可以创建两个11*11的二维数组,一个用来放置雷,一个用来呈现给玩家。
char mine[ROWS][COLS];//存放布置好的雷
char show[ROWS][COLS];//存放排查出的雷的信息
然后创建 InitBoard 函数将其初始化.
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
函数的具体代码
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
2放置雷
然后我们创建 SetMine 函数在 mine 数组中随机放置10个雷:
SetMine(mine, ROW, COL);
SetMine函数源码:
void SetMine(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--;
}
}
}
3打印棋盘
之后便创建 DisplayBoard函数 打印棋牌展示给玩家进行游玩:
DisplayBoard(show, ROW, COL);
DisplayBoard函数 源码:
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("--------扫雷游戏-------\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
4排查雷并结束游戏
然后便是排查雷,通过玩家输入的坐标,将Mine数组与Show数组对比来确定
如果为雷(1)那么游戏结束,
如果不是则继续进行游戏。
为了游戏不会无穷无尽的运行下去,我们还须完成游戏结束的代码。
即:设置一个变量(win)等于0,没有雷的格子的个数,如果没扫到雷,则该变量加一,当变量为没有雷的格子的个数时,则游戏成功!
我们可以创建一个FindMine函数来实现!
FindMine(mine, show, ROW, COL);
FineMine源码:
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 (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");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
上述代码中,我们还创建了一个GetMineCount函数 来告诉玩家,如果没点到雷,那么该格子附近有几个雷。
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
mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}
注:由于雷是1,所以如果扫到的不是雷,我们只需返回该坐标四周值相加的值,值是几便有几个雷。
二. 扫雷游戏的代码实现
test.c
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
int i = 0;
printf("--------扫雷游戏-------\n");
for (i = 0; i <= col; i++)
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
void SetMine(char board[ROWS][COLS], int row, int col)
{
//布置10个雷
//⽣成随机的坐标,布置雷
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 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
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 (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");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,排雷成功\n");
DisplayBoard(mine, ROW, COL);
}
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void menu()
{
printf("**************************\n");
printf("**********1.play**********\n");
printf("**********0.exit**********\n");
printf("**************************\n");
}
void game()
{
char mine[ROWS][COLS];//存放布置好的雷
char show[ROWS][COLS];//存放排查出的雷的信息
//初始化棋盘
//1. mine数组最开始是全'0'
//2. show数组最开始是全'*'
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
//DisplayBoard(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
//1. 布置雷
SetMine(mine, ROW, COL);
//DisplayBoard(mine, ROW, COL);
//2. 排查雷
FindMine(mine, show, ROW, COL);
}
void test()
{
int input = 0;
do
{
menu();
printf("Your choice:");
scanf("%d", &input);
switch (input)
{
case 1:
printf("start!!!\n");
game();
break;
case 0:
printf("exit game!\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define EASY_COUNT 10
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
//初始化棋盘
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 board[ROWS][COLS], int row, int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);