扫雷游戏 c语言实现
程序员文章站
2022-04-07 21:54:53
...
代码思路:
- 打印菜单,用户选择是否玩游戏(1——表示玩游戏,0——表示退出游戏);
- 设置两个数组,数组mine用来布雷(srand()和rand()配合使用,雷用‘1’表示),数组show用于输出;
- 如果第一次是雷,则将雷移走,如果不是雷,则计算它周围有多少雷并输出;
- 如果之后又踩雷则炸死,执行row*col-Easy_Count次没有炸死即为成功;
- 坐标周围没雷,可以实现展开;
- 重新选择是否继续玩游戏;
game.h
#define _CRT_SECURE_NO_WARNINGS 1
#ifndef __GAME_H__
#define __GAME_H__
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define Easy_Count 10 //雷的数量
void InitBoard(char arr[ROWS][COLS],int rows,int cols,char sz); //初始化数组
void SetMine(char mine[ROWS][COLS], int row, int col); //布雷
void DisplayBoard(char arr[ROWS][COLS], int row, int col); //打印数组
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col); //扫雷
#endif //__GAME_H__
game.c
#include"game.h"
//初始化函数
void InitBoard(char arr[ROWS][COLS], int rows, int cols,char sz)
{
memset(arr, sz, rows*cols*sizeof(arr[0][0]));
}
//放雷
void SetMine(char mine[ROWS][COLS], int row, int col)
{
int i=0; //雷数
while (i < Easy_Count)
{
int x = rand() % row + 1; //rand()%row产生的是0~row-1之间的数
int y = rand() % col + 1;
if (mine[x][y] == '0') //防止重复放雷
{
mine[x][y] = '1';
i++;
}
}
}
//打印
void DisplayBoard(char arr[ROWS][COLS], int row, int col)
{
int i, j;
for (i = 0; i <= row; i++) //打印行标---------0~9,便于用户
{
printf("%d ", i);
}
printf("\n");
for (i = 1; i <= col; i++)
{
printf("%d ", i); //打印列标---------1~9
for (j = 1; j <= col; j++) //循环打印元素
{
printf("%c ", arr[i][j]);
}
printf("\n");
}
}
//计算雷的数量
static int CountMine(char mine[ROWS][COLS], int x, int y)
{
int count;//坐标周围7个地方 字符1-字符0=数字1;
count = (mine[x][y - 1] + mine[x][y + 1] + mine[x - 1][y] +
mine[x - 1][y - 1] + mine[x - 1][y + 1] + mine[x + 1][y] + mine[x+1][y - 1] + mine[x + 1][y + 1]) - 8 * '0';
return count;
}
//展开函数
static void open_board(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
int i, j;
if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL)) //坐标合法
{
if (CountMine(mine, x, y) == 0) //坐标周围没有雷
{
show[x][y] = '0';
for (i = x - 1; i <= x + 1; i++)
{
for (j = y - 1; j <= y + 1; j++)
{
if (show[i][j] == '*') //如果这个地方没有展开,则递归展开
open_board(mine, show, i, j);
}
}
}
else
show[x][y] = CountMine(mine, x, y) + '0';
}
}
//扫雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
int x = 0;
int y = 0;
int win = 0;
int i = 1;
int t;
int m;
while (1)
{
printf("请输入坐标:>");
scanf("%d%d", &x, &y);
if ((x >= 1 && x <= row) && (y >= 1 && y <= col)) //坐标合法
{
if (mine[x][y] == '1')
{
if (i > 0) //第一次是雷,挪走雷,不被炸死
{
int count = 0;
mine[x][y] = '0';
t = rand() % row + 1; //雷-------x坐标
m = rand() % col + 1; //雷-------y坐标
if (mine[t][m] == '0')
{
mine[t][m] = '1'; //重新给雷找位置
}
open_board(mine, show, x, y);//展开
DisplayBoard(show, ROW, COL);//展示
i--; //i变为0,以后要是遇到雷,不执行这一步,直接炸死
}
else
{
printf("很遗憾,你被炸死了!\n");
break;
}
}
else if (mine[x][y] == '0'&&show[x][y] == '*') //统计周围雷的个数,防止一个位置count++两次
{
win++;
open_board(mine, show, x, y);
DisplayBoard(show, ROW, COL);
if (win == row*col - Easy_Count)
{
printf("恭喜你,闯关成功!\n");
break;
}
i--;
}
else
printf("坐标重复输入,请重新输入:\n");
}
else
{
printf("输入的坐标无效,请重新输入!\n");
}
}
}
test.c
#include"game.h"
enum game
{
tuichu,
wanyouxi
};
void menu()
{
printf("*******************\n");
printf("*****1 玩游戏***\n");
printf("*****0 退出*****\n");
printf("*******************\n");
}
void play()
{
char mine[ROWS][COLS] = { 0 }; //用于放雷
char show[ROWS][COLS] = { 0 }; //用于展示
InitBoard(mine, ROWS, COLS,'0'); //初始化 雷阵mine初始化为字符‘0’,show初始化为字符‘*’;
InitBoard(show, ROWS, COLS,'*'); //show初始化为字符‘*’
SetMine(mine, ROW, COL); //放置雷
DisplayBoard(show, ROW, COL); //打印数组show
FindMine(mine, show, ROW, COL); //扫雷
printf("雷阵:\n"); //最后让玩者看一下雷阵
DisplayBoard(mine, ROW, COL);
}
void test()
{
int input; //选择是否玩游戏
srand((unsigned)time(NULL)); //生成随机数
do
{
menu();
printf("请做出选择:>");
scanf("%d", &input);
switch (input)
{
case wanyouxi:
play(); //玩游戏
break;
case tuichu: printf("退出游戏!\n"); break;
default:printf("输入错误,请重新输入!\n"); break;
}
} while (input);
}
int main()
{
test();
system("pause");
return 0;
}