**扫雷**
扫雷的功能可以分为以下几部分
一、功能菜单
二、选择功能(开始游戏、退出游戏)
三、棋盘初始化:一张棋盘用于显示玩家扫雷情况。一张棋盘用于记录雷的分布情况
四、扫雷过程:
扫雷游戏有扫雷和插旗两步:本程序输入数字1为扫雷,数字2为插旗,并显示剩余旗帜数的剩余(默认旗帜FLAG大小为雷的数量)
1、扫雷:输入想要扫雷的位置坐标,判断该位置是否插旗,是否已经扫过,是否有雷,如果上述都是否定情况,则该位置显示周围雷的数量。
2、插旗:输入想要插旗的位置坐标,判断该位置是否插旗,是否已经扫过,如果上述都是否定情况,则该位置会显示感叹号表示插旗。
3、如果扫雷过程中雷全部扫出来(统计不是雷的位置的个数),则会提示获胜,否则游戏失败
main.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
printf("****************\n");
printf("**1 . Play **\n");
printf("**2 . Exit **\n");
printf("****************\n");
}
game()
{
char board[ROWS][COLS] = { '0' }; //玩家棋盘
char mine[ROWS][COLS] = { '0' }; //雷的设置
int x = 0, y = 0,cnt = 0,FlagCnt = 0;
int flag = 0; //1为扫雷,2为插旗
InitBoard(board, ROWS,COLS,'*'); //初始化玩家棋盘
InitBoard(mine, ROWS, COLS,'0'); //初始化设置雷棋盘
SetMine(mine, ROW, COL,Level); //布置雷
PrintBoard(board, ROW, COL); //打印玩家棋盘
PrintMine_Board(mine, ROW, COL); //打印设置雷棋盘
while (1)
{
printf("请选择扫雷(1)/插旗(2)/拔旗(3):\n");
scanf("%d", &flag);
if (flag == 1) //扫雷
{
//如果扫到雷
if (FindMine(board, mine, ROWS, COLS) == 0)
{
break;
}
else //未扫到雷
{
printf("FLAG:%d\n", FLAG - FlagCnt);
printf("\n");
}
}
if (flag == 2) //插旗
{
if (FlagCnt != FLAG)
{
SetFlag(board, mine, ROW, COL,1);
FlagCnt++;
printf("FLAG:%d\n", FLAG - FlagCnt);
printf("\n");
}
else
printf("旗帜已用完,无法插旗!\n");
}
if (flag == 3) //拔旗
{
if (FlagCnt > 0)
{
SetFlag(board, mine, ROW, COL, 0);
FlagCnt--;
printf("FLAG:%d\n", FLAG - FlagCnt);
printf("\n");
}
else
printf("未插旗,不用拔旗\n");
}
if (IsWin(board,RO,COL)==1)
{
PrintMine_Board(mine, ROW, COL); //打印设置雷棋盘
printf("%d个雷已经全部找到,恭喜你获胜\n", Level);
break;
}
}
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n"); break;
default:
printf("选择错误,重新选择\n");
}
} while (input);
return 0;
}
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void Spread(char board[ROWS][ROWS], char mine[ROWS][COLS], int x, int y,int col,int row)
{
int Spr_x = 0;
int Spr_y = 0;
int count = 0;
//坐标合法
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//遍历周围坐标
for (Spr_x = -1; Spr_x <= 1; Spr_x++)
{
for (Spr_y = -1; Spr_y <= 1; Spr_y++)
{
//如果这个坐标不是雷
if (mine[x + Spr_x][y + Spr_y] == '0')
{
//统计周围雷的个数
count = CntMine(mine, x + Spr_x, y + Spr_y);
if (count == 0)
{
if (board[x + Spr_x][y + Spr_y] == '*')
{
board[x + Spr_x][y + Spr_y] = '0';
Spread(board,mine ,x + Spr_x, y + Spr_y,col,row);
}
}
else
{
board[x + Spr_x][y + Spr_y] = count + '0';
}
}
}
}
}
}
//统计周围雷数
int CntMine(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 SetFlag(char board[ROWS][ROWS], char mine[ROWS][COLS], int row, int col,int s)
{
int x = 0, y = 0;
if (s == 1)//插旗
{
while (1)
{
printf("请输入插旗位置:\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= ROW && y >= 1 && x <= COL)
{
if (board[x][y] == '0')
{
printf("该位置已经排除,不需要插旗。请重新选择位置:\n");
}
else if (board[x][y] == '*')
{
board[x][y] = '!';
break;
}
else if (board[x][y] == '!')
{
printf("该位置已经插旗,请重新选择位置:\n");
}
}
}
}
if (s == 0)//拔旗
{
while (1)
{
printf("请输入拔旗位置:\n");
scanf("%d %d", &x, &y);
if (x >= 1 && x <= ROW && y >= 1 && x <= COL)
{
if (board[x][y] == '*')
{
printf("该位置未插旗,请重新选择位置:\n");
}
if (board[x][y] == '!')
{
board[x][y] = '*';
break;
}
}
}
}
PrintBoard(board, ROW, COL);//打印玩家棋盘
}
//扫雷
int FindMine(char board[ROWS][ROWS],char mine[ROWS][COLS], int row, int col)
{
int x = 0, y = 0;
while (1)
{
printf("请输入扫雷位置:\n");
scanf("%d %d", &x, &y);
if (board[x][y] == '!')//如果扫雷位置有旗,则不能扫雷
{
printf("该位置已插旗,无法扫雷,请重新选择:\n");
}
else
{
if (mine[x][y] == '1')
{
printf("你被炸死了,游戏结束\n");
PrintMine_Board(mine, ROW, COL);//打印设置雷棋盘
return 0;
}
else
{
if (board[x][y] = '*')
{
int count = CntMine(mine, x, y);
board[x][y] = count + '0';
if (count == 0 )//如果周围没有雷则展开
{
board[x][y] = count+'0';
Spread(board, mine, x, y, row, col);
}
PrintBoard(board, ROW, COL);//打印玩家棋盘
return 1;
}
else
{
printf("该位置已扫过,请重新选择:\n");
}
}
}
}
}
//布置雷
void SetMine(char board[ROWS][ROWS], int row, int col,int level)
{
int x = 0, y = 0;
while (level)
{
x = rand() % row + 1;
y = rand() % col + 1;
if (board[x][y] == '0')
{
board[x][y] = '1';
level--;
}
}
}
//初始化棋盘
void InitBoard(char board[ROWS][ROWS], int rows, int cols,char c)
{
int i = 0,j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
board[i][j] = c;
}
}
}
//打印玩家棋盘
void PrintBoard(char board[ROWS][ROWS], int rows, int cols)
{
int i = 0, j = 0;
printf("———扫雷————\n");
printf(" ");
for (i = 0; i <= rows; i++)
printf(" %d", i);
printf("\n");
printf(" ———————\n");
for (i = 1; i <= rows; i++)
{
printf(" %d|", i);
for (j = 1; j <= cols; j++)
{
printf(" %c", board[i][j]);
}
printf("\n");
}
printf("———扫雷————\n");
}
//打印雷的分布
void PrintMine_Board(char board[ROWS][ROWS], int row, int col)
{
int i = 0, j = 0;
printf("————雷————\n");
printf(" ");
for (i = 0; i <= row; i++)
printf(" %d", i);
printf("\n");
printf(" ———————\n");
for (i = 1; i <= row; i++)
{
printf(" %d|", i);
for (j = 1; j <= col; j++)
{
printf(" %c", board[i][j]);
}
printf("\n");
}
printf("————雷————\n");
}
int IsWin(char board[ROWS][ROWS], int row, int col)
{
int cnt = 0,i = 0,j = 0;
for (i = 1; i <= row; i++ )
{
for (j = 1; j <= col; j++ )
{
if (board[i][j] == '*' || board[i][j] == '!')
cnt++;
}
}
if (cnt == Level)
return 1;
else
return 0;
}
game.h
#pragma
#include
#include
#include
#define ROW 6
#define COL 6
#define ROWS ROW+2
#define COLS COL+2
#define Level 6 //游戏难度
#define FLAG Level //旗子数
void InitBoard(char board[ROWS][ROWS], int rows, int cols,char c);//初始化棋盘
void PrintBoard(char board[ROWS][ROWS], int rows, int cols);//打印棋盘
void PrintMine_Board(char board[ROWS][ROWS], int rows, int cols);//打印雷棋盘
void SetMine(char board[ROWS][ROWS], int row, int col,int level);//布置雷
int FindMine(char board[ROWS][ROWS], int row, int col);
void SetFlag(char board[ROWS][ROWS], char mine[ROWS][COLS], int row, int col,int s);
int CntMine( char mine[ROWS][COLS], int x, int y);//统计雷的数量
int IsWin(char board[ROWS][ROWS], int row, int col);//判断是否排雷成功
void Spread(char board[ROWS][ROWS], char mine[ROWS][COLS], int x, int y, int row, int col);//扩散
玩家操作棋盘和雷的分布图
游戏操作,FLAG为可插旗数
当该位置周围没有雷时,会扩散出来
插旗操作,显示感叹号(3,3),FLAG大小减一
拔旗操作,FLAG+1,该位置感叹号消失(3 , 3)
踩到雷,游戏结束,并显示雷的分布图
获胜