文章目录
欢迎讨论:如有错误或不足,欢迎指正和建议,本人主打“听劝”。当然,如有疑问,也期待你在评论区留言互动。
点赞+关注:如果这篇文章对你有帮助,那就支持一下小编吧~~
前言
扫雷游戏是一款经典的单人益智游戏,玩家的目标是在一个由许多格子组成的方格中寻找隐藏的地雷。通过标记地雷位置并避免点击地雷,玩家可以逐步揭示无雷区域,最终完成游戏。本文将介绍如何使用C语言实现一个简单的扫雷游戏。
游戏规则
在扫雷游戏中,玩家面临一个由大小可调的网格构成的区域。每个网格可能包含地雷,或者周围有若干地雷。玩家需要通过推测和逻辑判断来标记地雷位置,并揭开没有地雷的格子。每当玩家点击一个没有地雷的格子时,格子将显示周围邻近地雷的数量。
理清思路
我们先来看张图片:
不难发现,这是一个9*9的矩阵
。
首先我们第一个想到的就是二维数组
了。
我们可以先将棋盘初始化为0
然后用1
来表示雷
问题1:当我扫雷时周围只有1个雷时,也需要用到1,那这样岂不是重复了?
不妨可以用两个数组:
- 一个数组mine[][]用来“埋雷”,不打印。
- 一个数组show[][]用来“排雷”,打印。
show[][]我们初始化为*
。
问题2:那么,数组定义为什么类型呢?
show[][]很简单,要存放*
,定义为char类型
为了保持一致性,mine[][]最好也定义为char类型,这样可以避免一些不必要的麻烦。
需要注意的是:数字一定要用字符,1——>’1‘
问题3:当排雷边界数组时,遍历会出界,会出现数组越界的情况。
我们不妨可以给数组的行增加2行,列增加了2列。打印时打印中间我门需要的部分就是了。
布置雷时需要随机生成雷的坐标,随机数生成
又可以派上用场了。
srand((unsighed int)time(NULL));
int x=rand()%9+1;
int y=rand()%9+1;
在初探C语言|手把手带你手撕猜数字游戏中有详细介绍。
不要忘了头文件哦
代码实现
主函数代码
int main()
{
test();
return 0;
}
test()
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menue();
printf("请选择:");
scanf("%d", &input);
switch(input)
{
case 1: {
game();
break;
}
case 0: {
printf("退出游戏");
break;
}
default: {
printf("数据错误,重新输入!");
break;
}
}
} while (input);
}
menue()
void menue()
{
printf("*****************************\n");
printf("******** 1.Play ********\n");
printf("******** 0.Exit ********\n");
printf("*****************************\n");
}
game()
void game()
{
printf("扫雷游戏\n");
char mine[ROWS][COLS] = { 0 };//存储雷的位置
char show[ROWS][COLS] = { 0 };//存储雷的信息
//初始化棋盘
init_board(mine,ROWS,COLS,'0');
init_board(show,ROWS,COLS,'*');
//打印棋盘
//display_board(mine,ROW,COL);
display_board(show,ROW,COL);
//布置雷
set_mine(mine, ROWS, COLS);
//display_board(mine, ROW, COL);
//排查雷
find_mine(mine, show, ROWS,COLS);
}
游戏代码
初始化棋盘
void init_board(char board[ROWS][COLS], int row, int col, char set)
{
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
for (j = 0; j < col; j++) {
board[i][j] = set;
}
}
}
打印棋盘
void display_board(char board[ROWS][COLS], int row, int col)
{
printf("--------扫雷--------\n");
int i = 0;
for (i = 0; i <= row; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i <= row; i++) {
int j = 0;
printf("%d ", i);
for (j = 1; j <= col; j++) {
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("--------扫雷--------\n");
}
布置雷
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = MINE_NUMBER;
int x = 0;
int y = 0;
while (count) {
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if (mine[x][y] == '1')
continue;
else {
mine[x][y] = '1';
count--;
}
}
}
排查雷+判断输赢
//计算周围雷的数量
int number_mine(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 find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int count = ROW * COL - MINE_NUMBER;
while (count)
{
int x = 0;
int y = 0;
printf("输入坐标>");
scanf("%d%d", &x, &y);
if (x > 0 && x < row && y>0 && y < col&&mine[x][y]!='1') {
if (show[x][y] == '*') {
show[x][y] = '0' + number_mine(mine, x, y);
count--;
display_board(show, ROW, COL);
}
else {
printf("坐标出错,重新输入!\n");
continue;
}
}
else if (mine[x][y] == '1') {
printf("很遗憾,你被炸死了!\n");
display_board(mine, ROW, COL);
break;
}
else {
printf("坐标出错,重新输入!\n");
}
}
if (count == 0) {
printf("恭喜你,扫雷成功!\n");
display_board(mine, ROW, COL);
}
}
完整代码
测试test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menue()
{
printf("*****************************\n");
printf("******** 1.Play ********\n");
printf("******** 0.Exit ********\n");
printf("*****************************\n");
}
void game()
{
printf("扫雷游戏\n");
char mine[ROWS][COLS] = { 0 };//存储雷的位置
char show[ROWS][COLS] = { 0 };//存储雷的信息
//初始化棋盘
init_board(mine,ROWS,COLS,'0');
init_board(show,ROWS,COLS,'*');
//打印棋盘
//display_board(mine,ROW,COL);
display_board(show,ROW,COL);
//布置雷
set_mine(mine, ROWS, COLS);
//display_board(mine, ROW, COL);
//排查雷
find_mine(mine, show, ROWS,COLS);
}
void test()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menue();
printf("请选择:");
scanf("%d", &input);
switch(input)
{
case 1: {
game();
break;
}
case 0: {
printf("退出游戏");
break;
}
default: {
printf("数据错误,重新输入!");
break;
}
}
} while (input);
}
int main()
{
test();
return 0;
}
封装头文件game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define MINE_NUMBER 10
//初始化棋盘
void init_board(char board[ROWS][COLS],int row,int col,char set);
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col);
//布置雷
void set_mine(char mine[ROWS][COLS], int row, int col);
//排查雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
封装函数game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void init_board(char board[ROWS][COLS], int row, int col, char set)
{
int i = 0;
for (i = 0; i < row; i++) {
int j = 0;
for (j = 0; j < col; j++) {
board[i][j] = set;
}
}
}
void display_board(char board[ROWS][COLS], int row, int col)
{
printf("--------扫雷--------\n");
int i = 0;
for (i = 0; i <= row; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i <= row; i++) {
int j = 0;
printf("%d ", i);
for (j = 1; j <= col; j++) {
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("--------扫雷--------\n");
}
void set_mine(char mine[ROWS][COLS], int row, int col)
{
int count = MINE_NUMBER;
int x = 0;
int y = 0;
while (count) {
x = rand() % 9 + 1;
y = rand() % 9 + 1;
if (mine[x][y] == '1')
continue;
else {
mine[x][y] = '1';
count--;
}
}
}
//计算周围雷的数量
int number_mine(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 find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int count = ROW * COL - MINE_NUMBER;
while (count)
{
int x = 0;
int y = 0;
printf("输入坐标>");
scanf("%d%d", &x, &y);
if (x > 0 && x < row && y>0 && y < col&&mine[x][y]!='1') {
if (show[x][y] == '*') {
show[x][y] = '0' + number_mine(mine, x, y);
count--;
display_board(show, ROW, COL);
}
else {
printf("坐标出错,重新输入!\n");
continue;
}
}
else if (mine[x][y] == '1') {
printf("很遗憾,你被炸死了!\n");
display_board(mine, ROW, COL);
break;
}
else {
printf("坐标出错,重新输入!\n");
}
}
if (count == 0) {
printf("恭喜你,扫雷成功!\n");
display_board(mine, ROW, COL);
}
}
拓展实现:
- 能够展开一片的操作
- 标记和取消雷
- 显示剩余雷的个数
- 时间显示