您现在的位置是:首页 >技术教程 >C语言(扫雷)网站首页技术教程
C语言(扫雷)
简介C语言(扫雷)
开发过程
- 准备工作
- 效果展示
准备工作:
game.h 一个头文件–>声明函数
test.c 为主文件
game.c 为功能函数实现文件
效果展示
开发思路
-
菜单界面
-
游戏界面打印(二维数组)
-
雷的随机产生
-
排雷(以及判断周围的雷数)
-
胜利条件
大致思路就是这样,接下来我们一步步去分析
菜单界面
void menu()
{
printf("*********************
");
printf("*** 1.play 0.exit ***
");
printf("*********************
");
}
这里我们要不断的去 接收用户的输入,当为1时,进入游戏,为0时,退出程序
直接就想到了 条件语句判断,这里我们用switch
不断的:用户完成游戏后,可以再次打印菜单供用户选择
这个操作当然是项目的核心部分了,放在 main()函数里
int main()
{
int input = 0;
//设置随机数 后面会讲
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入有误!!!");
break;
}
} while (input);
return 0;
}
游戏界面的打印
这里当然是用二维数组,但是我们要去考虑,如果就一个数组的话,能否起到不知情排雷的效果。
当然,一个数组是不可能的,所以我们要建立两个数组,
一个是真实的,一个是展示给用户看的
char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
char show[ROWS][COLS] = { 0 };//存放排查出雷的信息
在这里我们要先去考虑一下,该数组若是9×9,在边缘时去判断周围的雷数会越界
我们可以通过建立11×11的数组,其中最外围我们不用,只是设置为默认值
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
对地图的初始化
//mine 数组在没有布置雷的时候全为 0
InitBoard(mine, ROWS, COLS, '0');
//show 数组在没有排查雷的时候全为 *
InitBoard(show, ROWS, COLS, '*');
我们的InitBoard函数为:
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0, 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, j = 0;
printf("-----------扫雷游戏--------------
");
//打印上面0~9注释
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("
");
for (i = 1; i <= row; i++)
{
printf("%d ", i); //打印竖着1~9的注释
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("
");
}
printf("-----------扫雷游戏--------------
");
}
雷的随机产生
我们很容易想到,就是产生随机数,对其数组进行更改元素值。
这就用到了 srand()函数
//设置随机数的起始
srand((unsigned int)time(NULL));
随机产生的函数:
我们定义EASY_COUNT(雷的数量)在头文件中
void SetMine(char board[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
//横纵坐标1~9
while (count)
{
int d = rand() % row + 1;
int c = rand() % col + 1;
//随机生成十个雷,雷:1
if (board[d][c] == '0')
{
board[d][c] = '1';
count--;
}
}
}
扫雷以及判断胜利条件
扫雷
让用户输入一个坐标,对其值进行判断
- 若在 show数组内该坐标为*,则该坐标已经被排雷
- 若在mine数组内该坐标为1则被雷炸失败
- 否则对其周围进行判断在mine数组内有几颗雷并在show数组的该坐标上显示其数量
判断是否重复输入坐标
if (show[x][y] != '*')
{
printf("该坐标已经排查过了,请重新输入:>
");
}
失败的代码很简单,一个判断就行了
if (mine[x][y] == '1') //是雷
{
printf("被炸死咯
");
DisplayBoard(mine, ROW, COL);
break;
}
判断周围有几颗雷的函数为
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
return (board[x - 1][y] +
board[x - 1][y - 1] +
board[x - 1][y + 1] +
board[x][y + 1] +
board[x][y - 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1]- 8*'0');
}
整个操作的函数为
void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col)
{
int x = 0, y = 0;
int a = 0, b = 0;
int win = 0;
while (win<row*col-EASY_COUNT)//判断胜利条件,win小于整体-雷数
{
printf("请输入排查的坐标:>
");
scanf("%d %d", &a, &b);
x = a + 1;
y = b + 1;
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*')
{
printf("该坐标已经排查过了,请重新输入:>
");
}
else
{
if (mine[x][y] == '1') //是雷
{
printf("被炸死咯
");
DisplayBoard(mine, ROW, COL);
break;
}
else //不是雷 '0'-'0'=0 '1'-'0'=1 字符->整型
// ASCII码值分别为 '1':49 '0':48
{
int count = get_mine_count(mine, x, y);//统计该坐标周围有几颗雷
show[x][y] = count + '0';//转换成数字字符
//printf("%c
", count + '0');
DisplayBoard(show, ROW, COL);
win++;
}
}
}
else
{
printf("输入坐标错误,请重新输入:>
");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,扫雷成功!!!
");
DisplayBoard(mine, ROW, COL);
}
}
代码整合
test.c
#include "game.h"
void menu()
{
printf("*********************
");
printf("*** 1.play 0.exit ***
");
printf("*********************
");
}
void game()
{
char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
char show[ROWS][COLS] = { 0 };//存放排查出雷的信息
//初始化数组的内容为指定内容
//mine 数组在没有布置雷的时候全为 0
InitBoard(mine, ROWS, COLS, '0');
//show 数组在没有排查雷的时候全为 *
InitBoard(show, ROWS, COLS, '*');
//DisplayBoard(mine,ROW, COL);
//设置雷
SetMine(mine, ROW, COL);
//展示
DisplayBoard(show, ROW, COL);
//排雷
FindMine(mine,show,ROW,COL);
}
int main()
{
int input = 0;
//设置随机数
srand((unsigned int)time(NULL));
do
{
menu();
printf("请输入:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏");
break;
default:
printf("输入有误!!!");
break;
}
} while (input);
return 0;
}
game.c
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
int i = 0, 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, j = 0;
printf("-----------扫雷游戏--------------
");
for (j = 0; j <= col; j++)
{
printf("%d ", j);
}
printf("
");
for (i = 1; i <= row; i++)
{
printf("%d ", i);
for (j = 1; j <= col; j++)
{
printf("%c ", board[i][j]);
}
printf("
");
}
printf("-----------扫雷游戏--------------
");
}
void SetMine(char board[ROWS][COLS], int row, int col)
{
int count = EASY_COUNT;
//横纵坐标1~9
while (count)
{
int d = rand() % row + 1;
int c = rand() % col + 1;
//随机生成十个雷,雷:1
if (board[d][c] == '0')
{
board[d][c] = '1';
count--;
}
}
}
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
return (board[x - 1][y] +
board[x - 1][y - 1] +
board[x - 1][y + 1] +
board[x][y + 1] +
board[x][y - 1] +
board[x + 1][y - 1] +
board[x + 1][y] +
board[x + 1][y + 1]- 8*'0');
}
void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col)
{
int x = 0, y = 0;
int a = 0, b = 0;
int win = 0;
while (win<row*col-EASY_COUNT)//判断胜利条件,win小于整体-雷数
{
printf("请输入排查的坐标:>
");
scanf("%d %d", &a, &b);
x = a + 1;
y = b + 1;
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (show[x][y] != '*')
{
printf("该坐标已经排查过了,请重新输入:>
");
}
else
{
if (mine[x][y] == '1') //是雷
{
printf("被炸死咯
");
DisplayBoard(mine, ROW, COL);
break;
}
else //不是雷 '0'-'0'=0 '1'-'0'=1 字符->整型
// ASCII码值分别为 '1':49 '0':48
{
int count = get_mine_count(mine, x, y);//统计该坐标周围有几颗雷
show[x][y] = count + '0';//转换成数字字符
//printf("%c
", count + '0');
DisplayBoard(show, ROW, COL);
win++;
}
}
}
else
{
printf("输入坐标错误,请重新输入:>
");
}
}
if (win == row * col - EASY_COUNT)
{
printf("恭喜你,扫雷成功!!!
");
DisplayBoard(mine, ROW, COL);
}
}
game.h
#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10 //雷
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[ROW][COL],char show[ROW][COL], int row, int col);
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。