扫雷游戏 c语言实现

代码思路:

  • 打印菜单,用户选择是否玩游戏(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;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值