您现在的位置是:首页 >其他 >扫雷游戏(C语言)网站首页其他
扫雷游戏(C语言)
目录
一、扫雷游戏介绍
《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。
二、扫雷游戏如何实现
首先我们在浏览器上试玩一下扫雷游戏, 观察扫雷都有哪些元素来组成
1.大致了解一下扫雷游戏
我们可以看到,扫雷是由9*9的棋盘构成的,所有我们就确定了要使用数组来实现扫雷游戏。
扫雷顾名思义,肯定要布置地雷,我们可以用字符0表示该位置没有地雷,用字符1表示该位置有地雷,当然地雷的布置是我们看不到的,我们只能看到在该位置3*3的范围内有没有地雷,所有我们就需要两个数组,一个用于存放地雷的布置,一个用来展示给玩家观看。
2 、进一步的深入扫雷游戏
1)关于数组的大小
我们看到的是一个9*9的棋盘,但我们实际需要的是11*11的棋盘,因为在判断一颗棋子附件有多少地雷的时候,在边边角角的棋子在检查的时候就会越界,为了避免这种情况,我们需要在周围再加上一圈。
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
我们用ROW和COL表示我们看到的行和列,用ROWS和COLS表示实际的行和列
2)用流程图大致演示流程
三、分模板用C语言进行实现
1.初始化数组
函数的定义
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = ch;
}
}
}
函数的使用
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
将定义的数组传过去,并分别将雷数组置为字符0,展示数组置为*
如图所示
2.打印棋盘
函数的定义
//打印棋盘
void printBorad(char board[ROWS][COLS], int row, int col)
{
int i = 0;
for (i = 0; i <= col; i++)
printf(" %d ", i);
printf("
");
for (i = 1; i <= row; i++)
{
printf(" %d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf(" %c ", board[i][j]);
}
printf("
");
}
printf("
");
}
函数的使用
printBorad(mine, ROW, COL);
printBorad(show, ROW, COL);
用于将两个棋盘都打印出来
3.布置雷
函数的定义
setmine(char board[ROWS][COLS], int row, int col)
{
int num = minenum;
while (num)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
num--;
}
}
}
函数的使用
setmine(mine, ROW, COL);
minenum为雷的数量
#define minenum 10
我们用随机数来布置雷的位置,当布置成功时num--,布置成功所需雷的数量时函数结束
布置的雷(‘1’)
4.开始排雷
函数定义
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//给出坐标
int x = 0;
int y = 0;
int wins = 0;
while (wins!= minenum)
{
printf("请输入排查的坐标:");
scanf("%d %d", &x, &y);
//判断坐标是否正确
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("游戏结束,你被炸死了
");
printBorad(mine, row, col);
return 0;
}
else
{
//判断周围有几个雷
int num = getminenum(mine, x, y);
if (num == 0)
{
getspace(mine, show, x, y);
}
//将show上的0换成num
else
{
show[x][y] = num + '0';
}
printBorad(show, row, col);
}
}
else
{
printf("输入坐标错误,请重新输入
");
}
wins = win(show, row, col);
}
if (wins== minenum)
{
printf("游戏胜利,恭喜你排雷成功!
");
printBorad(mine, row, col);
return 1;
}
}
函数使用
FindMine(mine, show, ROW, COL);
1.排雷的流程图
依次输入坐标,并判断该坐标是否为炸弹,若为炸弹则游戏结束,若不是炸弹则检测该位置范围有无炸弹,并扩展开来,直到游戏结束
1.判断周围有多少个雷的代码
//判断周围有几颗雷
int getminenum(char mine[ROWS][COLS], 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');
}
将周围八个的编码值加起来减去8*‘0’的编码值既为所求
2.扩展代码
void getspace(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
show[x][y] = ' ';
//左上
if (show[x-1][y-1] != ' ' && getminenum(mine, x - 1, y - 1) == 0)
{
getspace(mine, show, x-1, y-1);
}
else if(show[x-1][y-1] != ' ' && getminenum(mine, x - 1, y - 1) != 0)
{
show[x - 1][y - 1] = getminenum(mine, x - 1, y - 1) + '0';
}
//上
if (show[x-1][y] != ' ' && getminenum(mine, x - 1, y) == 0)
{
getspace(mine, show, x - 1, y);
}
else if (show[x-1][y] != ' ' && getminenum(mine, x - 1, y) != 0)
{
show[x - 1][y] = getminenum(mine, x - 1, y) + '0';
}
//右上
if (show[x - 1][y+1] != ' ' && getminenum(mine, x - 1, y+1) == 0)
{
getspace(mine, show, x - 1, y + 1);
}
else if (show[x - 1][y + 1] != ' ' && getminenum(mine, x - 1, y + 1) != 0)
{
show[x - 1][y + 1] = getminenum(mine, x - 1, y + 1) + '0';
}
//左
if (show[x][y - 1] != ' ' && getminenum(mine, x , y - 1) == 0)
{
getspace(mine, show, x, y - 1);
}
else if (show[x][y + 1] != ' ' && getminenum(mine, x , y - 1) != 0)
{
show[x][y - 1] = getminenum(mine, x , y - 1) + '0';
}
//右
if (show[x][y + 1] != ' ' && getminenum(mine, x, y + 1) == 0)
{
getspace(mine, show, x, y + 1);
}
else if (show[x ][y + 1] != ' ' && getminenum(mine, x, y + 1) != 0)
{
show[x][y + 1] = getminenum(mine, x , y + 1) + '0';
}
//左下
if (show[x+1][y - 1] != ' ' && getminenum(mine, x+1, y - 1) == 0)
{
getspace(mine, show, x+1, y - 1);
}
else if (show[x+1][y + 1] != ' ' && getminenum(mine, x+1, y - 1) != 0)
{
show[x+1][y - 1] = getminenum(mine, x+1, y - 1) + '0';
}
//下
if (show[x + 1][y] != ' ' && getminenum(mine, x + 1, y) == 0)
{
getspace(mine, show, x+1, y );
}
else if (show[x + 1][y] != ' ' && getminenum(mine, x + 1, y) != 0)
{
show[x + 1][y] = getminenum(mine, x + 1, y) + '0';
}
//右下
if (show[x + 1][y+1] != ' ' && getminenum(mine, x + 1, y+1) == 0)
{
getspace(mine, show, x + 1, y+1);
}
else if (show[x + 1][y+1] != ' ' && getminenum(mine, x + 1, y+1) != 0)
{
show[x + 1][y+1] = getminenum(mine, x + 1, y+1) + '0';
}
}
当周围没有雷才可以使用该函数,判断该位置周围的八个位置也是否没有雷,若周围没有雷则用递归的方法继续下去,若有则将展示的数组换成周围的雷数。
3.判断胜利的条件
int win(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int wins=0;
for(i=1;i<=row;i++)
{
int j = 0;
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
wins++;
}
}
return wins;
}
判断展示数组还剩几个*,若和布置的雷数一样则游戏结束
四、代码总览
将上述代码进行整理编排既可实现扫雷游戏
1.test.c
#include"game.h"
//游戏菜单
void menu()
{
printf("*************************
");
printf("******* 1.play *******
");
printf("******* 0.exit *******
");
printf("*************************
");
}
//游戏实现
void game()
{
//定义数组
char mine[ROWS][COLS]; //布置雷的棋盘
char show[ROWS][COLS]; //排雷的棋盘
//初始化数组
//mine 全为0 show全为*
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
//打印棋盘
printBorad(mine, ROW, COL);
printBorad(show, ROW, COL);
//布置雷
setmine(mine, ROW, COL);
printBorad(mine, ROW, COL);
//排雷
FindMine(mine, show, ROW, COL);
}
int main()
{
int flag = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入:");
scanf("%d", &flag);
switch (flag)
{
case 1:
game();
break;
case 0:
printf("退出游戏
");
break;
default :
printf("输入错误请重新输入:
");
break;
}
} while (flag);
return 0;
}
2.game.c
#include "game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch)
{
int i = 0;
for (i = 0; i < rows; i++)
{
int j = 0;
for (j = 0; j < cols; j++)
{
board[i][j] = ch;
}
}
}
//打印棋盘
void printBorad(char board[ROWS][COLS], int row, int col)
{
int i = 0;
for (i = 0; i <= col; i++)
printf(" %d ", i);
printf("
");
for (i = 1; i <= row; i++)
{
printf(" %d ", i);
int j = 0;
for (j = 1; j <= col; j++)
{
printf(" %c ", board[i][j]);
}
printf("
");
}
printf("
");
}
//布置雷
setmine(char board[ROWS][COLS], int row, int col)
{
int num = minenum;
while (num)
{
int x = rand() % row + 1;
int y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
num--;
}
}
}
//判断周围有几颗雷
int getminenum(char mine[ROWS][COLS], 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 getspace(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
show[x][y] = ' ';
//左上
if (show[x-1][y-1] != ' ' && getminenum(mine, x - 1, y - 1) == 0)
{
getspace(mine, show, x-1, y-1);
}
else if(show[x-1][y-1] != ' ' && getminenum(mine, x - 1, y - 1) != 0)
{
show[x - 1][y - 1] = getminenum(mine, x - 1, y - 1) + '0';
}
//上
if (show[x-1][y] != ' ' && getminenum(mine, x - 1, y) == 0)
{
getspace(mine, show, x - 1, y);
}
else if (show[x-1][y] != ' ' && getminenum(mine, x - 1, y) != 0)
{
show[x - 1][y] = getminenum(mine, x - 1, y) + '0';
}
//右上
if (show[x - 1][y+1] != ' ' && getminenum(mine, x - 1, y+1) == 0)
{
getspace(mine, show, x - 1, y + 1);
}
else if (show[x - 1][y + 1] != ' ' && getminenum(mine, x - 1, y + 1) != 0)
{
show[x - 1][y + 1] = getminenum(mine, x - 1, y + 1) + '0';
}
//左
if (show[x][y - 1] != ' ' && getminenum(mine, x , y - 1) == 0)
{
getspace(mine, show, x, y - 1);
}
else if (show[x][y + 1] != ' ' && getminenum(mine, x , y - 1) != 0)
{
show[x][y - 1] = getminenum(mine, x , y - 1) + '0';
}
//右
if (show[x][y + 1] != ' ' && getminenum(mine, x, y + 1) == 0)
{
getspace(mine, show, x, y + 1);
}
else if (show[x ][y + 1] != ' ' && getminenum(mine, x, y + 1) != 0)
{
show[x][y + 1] = getminenum(mine, x , y + 1) + '0';
}
//左下
if (show[x+1][y - 1] != ' ' && getminenum(mine, x+1, y - 1) == 0)
{
getspace(mine, show, x+1, y - 1);
}
else if (show[x+1][y + 1] != ' ' && getminenum(mine, x+1, y - 1) != 0)
{
show[x+1][y - 1] = getminenum(mine, x+1, y - 1) + '0';
}
//下
if (show[x + 1][y] != ' ' && getminenum(mine, x + 1, y) == 0)
{
getspace(mine, show, x+1, y );
}
else if (show[x + 1][y] != ' ' && getminenum(mine, x + 1, y) != 0)
{
show[x + 1][y] = getminenum(mine, x + 1, y) + '0';
}
//右下
if (show[x + 1][y+1] != ' ' && getminenum(mine, x + 1, y+1) == 0)
{
getspace(mine, show, x + 1, y+1);
}
else if (show[x + 1][y+1] != ' ' && getminenum(mine, x + 1, y+1) != 0)
{
show[x + 1][y+1] = getminenum(mine, x + 1, y+1) + '0';
}
}
int win(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int wins=0;
for(i=1;i<=row;i++)
{
int j = 0;
for (j = 1; j <= col; j++)
{
if (show[i][j] == '*')
wins++;
}
}
return wins;
}
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
//给出坐标
int x = 0;
int y = 0;
int wins = 0;
while (wins!= minenum)
{
printf("请输入排查的坐标:");
scanf("%d %d", &x, &y);
//判断坐标是否正确
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (mine[x][y] == '1')
{
printf("游戏结束,你被炸死了
");
printBorad(mine, row, col);
return 0;
}
else
{
//判断周围有几个雷
int num = getminenum(mine, x, y);
if (num == 0)
{
getspace(mine, show, x, y);
}
//将show上的0换成num
else
{
show[x][y] = num + '0';
}
printBorad(show, row, col);
}
}
else
{
printf("输入坐标错误,请重新输入
");
}
wins = win(show, row, col);
}
if (wins== minenum)
{
printf("游戏胜利,恭喜你排雷成功!
");
printBorad(mine, row, col);
return 1;
}
}
3.game.h
#pragma once
#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 minenum 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char ch);
//打印棋盘
void printBorad(char board[ROWS][COLS], int row, int col);
//布置雷
setmine(char board[ROWS][COLS], int row, int col);
//排雷
FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
五、结束语
本章用C语言实现了扫雷,感谢大家的阅读,如有出错,欢迎纠错。