C语言实现扫雷游戏

今天我们来用C语言实现另一个众所周知的小游戏——扫雷;

首先,与五子棋不同的是,为了不让雷被玩家直接看到,我们需要创建两个棋盘。一个用于储存雷,我们将其命名为mine盘,一个能直观的展现给玩家,我们将其命名为show盘;

其次,为了算清玩家选择的坐标周围有多少雷,我们无可避免的要访问mine盘对应坐标周围一圈的类容。此时就出现问题了,最外围一圈的雷周围的类容是随机值,会影响判断雷数,所以创建时我们必须创建大一圈的mine盘,对应show盘也要大一圈,即创建的二维数组两个下标均加一;

为了提升游戏体验,在原游戏的基础上新增两个函数:
1:当玩家选中的坐标周围没有雷时,自动向周围八个坐标拓展;
2:首轮排雷保护,即在首轮踩到雷就将雷移走,确保首轮不被炸死;

代码实现:
依旧将游戏外围的框架做好,使得玩家能重复玩扫雷

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"//调用自己定义的game库

void menu()
{
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃     欢迎来到扫雷       ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃       1.开始游戏       ┃\n");
	printf("┣━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
	printf("┃       0.退出游戏       ┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
}

//主函数
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();//打印菜单
		printf("请选择:");
		scanf("%d",&input);
		switch(input)
		{
		case 1:
			system("cls");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}

	}
	while(input);
	return 0;
}

然后整理扫雷游戏的具体流程:

void game()
{
	char w = ' ';
	char mine[ROWS][COLS] = {0};
	char show[ROWS][COLS] = {0};
	int time1 = (int)time(NULL);
	int time2 = 0;
	Init_arr(mine,ROWS,COLS,' ');
	Init_arr(show,ROWS,COLS,' ');
	Set_mine(mine,ROW,COL,EASY_MODE);
	Print_arr(show,ROW,COL);
	First_round(mine,show,ROW,COL);
	while(1)
	{
		Print_arr(show,ROW,COL);
		Sweep_mine(mine,show,ROW,COL);
		w = Is_win(show,ROW,COL);
		if('w' == w)
		{
			printf("\n          恭 喜\n          扫 雷\n          成 功\n          ! !\n          ! !\n\n");
			break;
		}
		else if('l' == w)
		{
			printf("很可惜,您被炸死了~~!!!!\n");
			Print_arr(mine,ROW,COL);
			break;
		}
	}
	time2 = (int)time(NULL);
	printf("用时为%ds\n",time2-time1);
}

将游戏中所有需要的函数整理到自定义的game库中;

#ifndef  __GAME_H__
#define  __GAME_H__

#define  ROWS ROW+2
#define  COLS COL+2 
#define  ROW 9
#define  COL 9
#define  EASY_MODE 10

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>


void game();

//初始化棋盘
void Init_arr(char arr[ROWS][COLS],int row,int col,char n);
//打印棋盘
void Print_arr(char arr[ROWS][COLS],int row,int col);
//设置雷
void Set_mine(char arr[ROWS][COLS],int row,int col,int n);
//玩家扫雷
void Sweep_mine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);
//计算坐标周围雷的数量
int Num_mine(char arr[ROWS][COLS],int x,int y);
//坐标雷数为0时拓展周围
void Expand(char show[ROWS][COLS],char mine[ROWS][COLS],int row,int col, int x,int y);
//电脑进行扫雷操作
void Com_Sweep(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y);
//判断胜负
char Is_win(char show[ROWS][COLS],int row,int col);
//返回主菜单
void re_menu();
//首轮保护
void First_round(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);


#endif  //__GAME_H__

最后,定义以上函数

void Init_arr(char arr[ROWS][COLS],int row,int col,char n)
{
	memset(arr,n,row*col*sizeof(arr[0][0]));
}

void Print_arr(char arr[ROWS][COLS],int row,int col)
{
	int i = 0 ;
	int j = 0 ;
	for(i=0; i<=col;i++)
	{
		printf(" %d  ",i);
	}
	printf("\n");
	for(i=0; i<row; i++)
	{
		printf(" %d ",i+1);
		for(j=0; j<col; j++)
		{
			printf(" %c ",arr[i+1][j+1]);
			if(j<col-1)
				printf("┃");
		}
		printf("\n");
		if(i<row-1)
		{
			printf("   ");
			for(j=0; j<col-1; j++)
			{
				printf("━━━╋");
			}
			printf("━━━");
		}
		printf("\n");
	}
}

void Set_mine(char arr[ROWS][COLS],int row,int col,int n)
{
	while(n>0)
	{
		int x = rand()%row + 1;
	    int y = rand()%col + 1;
		if(' ' == arr[x][y])
		{
			arr[x][y] = '*';
			n--;
		}
	}
}

int Num_mine(char arr[ROWS][COLS],int x,int y)
{
	int i = 0;
	int j = 0;
	int n = 0;
	for(i=x-1; i<=x+1; i++)
	{
		for(j=y-1; j<=y+1; j++)
		{
			if('*' == arr[i][j])
				n++;
		}
	}
	return n;
}

void Expand(char show[ROWS][COLS],char mine[ROWS][COLS],int row,int col, int x,int y)
{
	int i = 0;
	int j = 0;
	for(i=x-1; i<=x+1; i++)
	{
		for(j=y-1; j<=y+1; j++)
		{
			if((' ' == show[i][j])&&(x>0 && x<=row && y>0 && y<=col))//防止跨界拓展
				Com_Sweep(mine,show,i,j);
		}
	}
}

void Com_Sweep(char mine[ROWS][COLS],char show[ROWS][COLS],int x,int y)
{
	show[x][y] ='0'+ Num_mine(mine,x,y);
	if(0 == Num_mine(mine,x,y))
	{
		mine[x][y] = '0';
		Expand(show,mine,ROW,COL,x,y);
	}
}

void Sweep_mine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
	int x = 0;
	int y = 0;
	while(1)
	{
		printf("输入一个坐标:>");
	    scanf("%d%d",&x,&y);
		if(x>0 && x<=row && y>0 && y<=col)
		{
			if(' ' == show[x][y])
			{
				if('*' == mine[x][y])
				{
					show[x][y] = '*';
					break;
				}
				else
				{
					Com_Sweep(mine,show,x,y);
				    break;
				}	
			}
			else
				printf("输入的坐标已经扫描过,请重新输入!\n");
		}
		else
			printf("输入的坐标有误,请重新输入!\n");
	}
}

char Is_win(char show[ROWS][COLS],int row,int col)
{
	int x = 0;
	int y = 0;
	int num_void = 0;
	for(x=1; x<=row; x++)
	{
		for(y=1; y<=col; y++)
		{
			if('*' == show[x][y])
				return 'l';
			else if(' ' == show[x][y])
				num_void++;
		}
	}
	if(EASY_MODE == num_void)
		return 'w';
	else
		return ' ';
}

void re_menu()
{
	int i = 'b';
	printf("按回车可返回主菜单\n");
	scanf("%d",&i);
	system("cls");
}

void First_round(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{	
	int x = 0;
	int y = 0;
	while(1)
	{
		printf("输入一个坐标:>");
	    scanf("%d%d",&x,&y);
		if(x>0 && x<=row && y>0 && y<=col)
		{
				if('*' == mine[x][y])
				{
					while(1)
					{
						int i = rand()%row + 1;
						int j = rand()%col + 1;
						if(' ' == mine[i][j])
						{
							mine[i][j] = '*';
							break;
						}
					}
					mine[x][y] = ' ';
				}
				Com_Sweep(mine,show,x,y);
			    break;	
		}
		else
			printf("输入的坐标有误,请重新输入!\n");
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值