用C语言写扫雷
首先,我们要清楚扫雷的逻辑。扫雷游戏就是点一个方块,如果是雷,那么你直接被炸死;如果不是雷 ,那么这个方块则会显示周围8个方块雷的个数。大概的逻辑就是这样。
现在,我们开始写这个代码。
先创建一个头文件,用来放我们的定义的常量以及库函数。
#ifndef __GAME_H_
#define __GAME_H_
#include<stdio.h>
#include<time.h>
#include<string.h>
#include<windows.h>
#define ROW 12 //数组的长
#define COL 12 //数组的宽
#define NUMS 20 //雷的个数
void Menu();
void Game();
#endif
下面我们需要写一个游戏的主程序。既然要扫雷那么就得有个游戏界面,这里我们用#来表示这个菜单。
void Menu()
{
printf("###########################\n");
printf("## 1.PLAY 2.EXIT ####\n");
printf("###########################\n");
printf("请输入你的选择:");
}
当你输入1,则会进入游戏主体,输入2,就退出这个游戏。
int main()
{
int quit = 0;
int n;
while (!quit) {
Menu();
scanf_s("%d", &n);//输入选择
switch (n) {
case 1:
Game(); //游戏函数
printf("要不要再来一局?\n");
break;
case 2:
quit = 1;
printf("再见!");
break;
default:
break;
}
}
return 0;
}
现在 这个游戏的主逻辑就完成了,那么接下来就是我们怎么写这个游戏的函数了。 玩过扫雷的都知道,扫雷是一个二维平面的游戏,那么C语言中,我们可以用二维数组来表现这个游戏界面。但是,一个二维数组我们用来输出给玩家看,但是如果只有一个数组,我们的雷就没地方放了,所以这里我们需要创建两个二维数组,一个用来给玩家看,另一个用来给我们放置雷。这里我们用一个10*10的界面
char show_broad[ROW][COL];//玩家界面
char mine_broad[ROW][COL];//雷的放置界面
创建好了数组,我们就需要对数组初始化,这里我们用“*”代表玩家看的界面,用字符'0'来表示雷区的界面。
memset(show_broad, '*', sizeof(show_broad));
memset(mine_broad, '0', sizeof(mine_broad));
初始化好后,玩家要进入游戏需要开始扫了,那么我们需要提前放置好雷。这里我们需要随机放置若干个雷,所以就要用到随机数。
srand((unsigned long)time(NULL));
然后将这些随机数放置在雷区。这里需要注意下,我们用的是10*10界面,所以在放置雷的时候不能放置在外面;其次,不能放置在已经放置的地方。所以我们写个函数。
void SetMines(char mine_broad[][COL], int row, int col)
{
int count = NUMS;
while (count) {
int x = rand() % 10 + 1;
int y = rand() % 10 + 1;//放置随机雷
if (mine_broad[x][y] == '0') {
mine_broad[x][y] = '1';//判断是否重复放雷
count--;
}
}
}
雷放置好后,玩家就要开始输入坐标。输入的坐标会有三种情况:1.输入的坐标不在定义的区域内;2.输入的坐标之前输入过了;3.输入正确的坐标。所以我们需要判断一下。
int x = 0;
int y = 0;
printf("请输入位置# ");
scanf_s("%d %d", &x, &y);
if (x < 1 || x > 10 || y < 1 || y >10) {
printf("输入越界,请重新输入!\n");
continue;
}
if (show_broad[x][y] != '*') {
printf("该位置已经被排除,请重新输入!\n");
continue;
}
接下来我们需要判断玩家输入的位置是否有雷。如果有,那么直接游戏结束,如果没有,那么我们需要显示附近方块所有雷的个数。
if (mine_broad[x][y] == '1') {
break;
}
int GetMines(char mine[][COL], int row, int col, int x, int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + \
mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + \
mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
}
做到这里我们的代码就写的差不多了,再加上界面控制以及其他的细节,我们这个扫雷游戏就写完了。
完整代码
头文件
#ifndef __GAME_H_
#define __GAME_H_
#include<stdio.h>
#include<time.h>
#include<string.h>
#include<windows.h>
#define ROW 12
#define COL 12
#define NUMS 99
void Menu();
void Game();
#endif
主逻辑
#include"game.h"
int main()
{
int quit = 0;
int n;
while (!quit) {
Menu();
scanf_s("%d", &n);
switch (n) {
case 1:
Game();
printf("要不要再来一局?\n");
break;
case 2:
quit = 1;
printf("再见!");
break;
default:
break;
}
}
return 0;
}
游戏函数
#include"game.h"
void Menu()
{
printf("###########################\n");
printf("## 1.PLAY 2.EXIT ####\n");
printf("###########################\n");
printf("请输入你的选择:");
}
void SetMines(char mine_broad[][COL], int row, int col)
{
int count = NUMS;
while (count) {
int x = rand() % 10 + 1;
int y = rand() % 10 + 1;
if (mine_broad[x][y] == '0') {
mine_broad[x][y] = '1';
count--;
}
}
}
int GetMines(char mine[][COL], int row, int col, int x, int y)
{
return mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] + \
mine[x][y - 1] + mine[x][y + 1] + mine[x + 1][y - 1] + \
mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
}
void ShowLine(int nums)
{
printf("---");
for (int i = 0; i < nums; i++) {
printf("-");
}
printf("\n");
}
void Show_broad(char show_broad[][COL], int row, int col)
{
printf(" ");
for (int i = 1; i < row - 1; i++) {
printf(" %d ", i);
}
printf("\n");
ShowLine(2 * col + col + 4);
for (int i = 1; i < row - 1; i++) {
printf("%2d|", i);
for (int j = 1; j < col - 1; j++) {
printf(" %c |", show_broad[i][j]);
}
printf("\n");
ShowLine(2 * col + col + 4);
}
}
void Game()
{
char show_broad[ROW][COL];
char mine_broad[ROW][COL];
memset(show_broad, '*', sizeof(show_broad));
memset(mine_broad, '0', sizeof(mine_broad));
srand((unsigned long)time(NULL));
SetMines(mine_broad, ROW, COL);
int count = (ROW - 2) * (COL - 2) - NUMS;
int x = 0;
int y = 0;
do {
Show_broad(show_broad, ROW, COL);
printf("请输入位置# ");
scanf_s("%d %d", &x, &y);
if (x < 1 || x > 10 || y < 1 || y >10) {
printf("输入越界,请重新输入!\n");
continue;
}
if (show_broad[x][y] != '*') {
printf("该位置已经被排除,请重新输入!\n");
continue;
}
if (mine_broad[x][y] == '1') {
break;
}
int num = GetMines(mine_broad, ROW, COL, x, y);
show_broad[x][y] = num + '0';
count--;
system("cls");
} while (count > 0);
if (count > 0) {
printf("你被炸死了!");
}
else {
printf("你赢了!\n");
}
printf("下面是雷区的排布\n");
Show_broad(mine_broad, ROW, COL);
}