C语言实现扫雷小游戏(设定游戏简易程度,实现空白,实现跳过第一次选中雷)

首先,演示一下:


要写出扫雷,首先要对扫雷有一个基本的认识。

分析一下:

(1):初始化棋盘

初始化棋盘分为两步:第一步,我们给一个全为“*”的棋盘;第二步,我们考虑到在计算雷周围数目的数目的时候,位于边界的位置不好求,所以我们在棋盘的每一边都增加1行或者1列。


(2)布雷:

布雷我们主要是在随机产生的位置上布雷,所以我们就要用到rand()。

(3):打印棋盘

打印棋盘也分为两步:第一步,我们要计算点开一个格子以后周围雷的数目;

第二步,如果我们点开的格子是0,就用递归调用显示他周围的一片空白区域。


(4):判断

如果踩中雷,我们就说结束了;如果排完雷,我们就说排雷成功了。

这四步呢,一定要捋清楚!

在这里呢,我用到了两个菜单,其实原理很简单,只是把雷的个数改变了



程序代码:

game.h

#ifndef __GAME_H__  
#define __GAME_H__  

#define COLS 11  
#define ROWS 11  

#define COL (COLS-2)  
#define ROW (ROWS-2)  
 

#include <stdio.h>  
#include <stdlib.h>  
#include <time.h>  
#include <string.h>
#pragma warning (disable:4996)


void init_board(char mine[ROWS][COLS], char set, int row, int col);//初始化棋盘 
void set_mine(char mine[ROWS][COLS],int max, int x, int y);//布雷
void display(char mine[ROWS][COLS], int row, int col);//打印棋盘
void get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);//统计周围雷的数目以及为0时的处理

#endif//__GAME_H__  


game.c

#include"game.h"  

void init_board(char mine[ROWS][COLS], char set, int row, int col)
{
	memset(mine, set, row*col*sizeof(mine[0][0]));//初始化棋盘,set表示对棋盘布置0还是*
}

void set_mine(char mine[ROWS][COLS], int max,int x, int y)//布雷定义雷的个数,随机产生一个位置布雷,依次递减
{
	int count = max;
	while (count>0)
	{
		int X = rand() % 9 + 1;
		int Y = rand() % 9 + 1;
		if ((X != x) && (Y != y) && mine[X][Y] == '0')//避免新的雷步到了原来的位置上
		{
			mine[X][Y] = '1';
			count--;
		}
	}
}

void display(char mine[ROWS][COLS], int row, int col)//打印棋盘,为了美观在这里要注意空格
{
	int x = 0;
	int y = 0;
	printf("  ");
	for (x = 1; x <= 9; x++)
	{
		printf("%d ", x);
	}
	printf("\n");
	for (x = 1; x <= 9; x++)
	{
		printf("%d ", x);
		for (y = 1; y <= 9; y++)
		{
			printf("%c ", mine[x][y]);
		}
		printf("\n");
	}
}

void get_mine_count(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)  
{
	//玩家选择了一个位置以后,如果该位置为'0',就把空格赋给它,表示空白。然后通过递归显示周围的一片
	if ((mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x - 1][y] - 7 * '0') == '0')
	{
		show[x][y] = ' ';
		if (((x - 1>=1) && (x - 1<=ROW)) && ((y - 1>=1) && (y - 1<=COL)) && (show[x - 1][y - 1] == '*'))
			get_mine_count(mine, show, x - 1, y - 1);

		if (((x >= 1) && (x <= ROW)) && ((y - 1 >= 1) && (y - 1 <= COL)) && (show[x][y - 1] == '*'))
			get_mine_count(mine, show, x, y - 1);

		if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y - 1 >= 1) && (y - 1 <= COL)) && (show[x + 1][y - 1] == '*'))
			get_mine_count(mine, show, x + 1, y - 1);

		if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y >= 1) && (y <= COL)) && (show[x + 1][y] == '*'))
			get_mine_count(mine, show, x + 1, y);

		if (((x + 1 >= 1) && (x + 1 <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x + 1][y + 1] == '*'))
			get_mine_count(mine, show, x + 1, y + 1);

		if (((x >= 1) && (x <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x][y + 1] == '*'))
			get_mine_count(mine, show, x, y + 1);

		if (((x - 1 >= 1) && (x - 1 <= ROW)) && ((y + 1 >= 1) && (y + 1 <= COL)) && (show[x - 1][y + 1] == '*'))
			get_mine_count(mine, show, x - 1, y + 1);

		if (((x - 1 >= 1) && (x - 1 <= ROW)) && ((y >= 1) && (y <= COL)) && (show[x - 1][y] == '*'))
			get_mine_count(mine, show, x - 1, y);
	}
	else show[x][y] = (mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] + mine[x + 1][y]
		+ mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] + mine[x - 1][y] - 7 * '0');
}




test.c

#include"game.h"  
void menu()//菜单
{
	printf("**********************************\n");
	printf("********* 1.play  0.exit**********\n");
	printf("**********************************\n");
}
void second_menu()//二级菜单显示
{
	printf("**********************************\n");
	printf("             1.简单               \n");
	printf("             2.中等               \n");
	printf("             3.困难               \n");
	printf("**********************************\n");
}
void game(num)//游戏环节
{   
	int max = num;//在这里实现了改变雷的个数,也是选择困难度传参的地方
	int blank = COL*ROW - max;
	int x = 0;
	int y = 0;
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	init_board(mine, '0', ROWS, COLS);//初始化11*11棋盘为0,考虑到最角落统计周围8格的总数
	init_board(show, '*', ROWS, COLS);//初始化9*9的棋盘为*
	display(show, ROWS, COLS);//打印棋盘
	while (blank)//循环条件是你排除的只剩下雷了
	{
		int i = 1;
		printf("请输入一个坐标:");
		scanf("%d%d", &x, &y);
		set_mine(mine, max, x, y);//输入坐标以后在布雷,就免去了玩家第一次输入就踩雷
		if (((x >= 1) && (x <= ROW)) && ((y >= 1) && (y <= COL)))
		{
		
			 if (mine[x][y] == '1')
			{
				printf("你选中了雷!\n");
				
				break;
			}
			else
			{
				get_mine_count(mine, show, x, y);//统计周围雷的数目以及打开0时的处理
			}
			blank--;
			display(show, ROWS, COLS);
			//display(mine, ROWS, COLS);//测试雷数,也就是直接看结果
		}
		else
		{
			printf("你输入的坐标有误!\n");
		}
	}
	if (blank == 0)
	{
		printf("德玛西亚!\n");
	}
}
void test()//对菜单进行选择
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择开始还是退出:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
		{
				  int input = 0;
				  do{
					  second_menu();
					  int easy_mine_num = 10;
					  int medium_mine_num = 15;
					  int difficult_mine_num = 20;
					  printf("请选择困难度:");
					  scanf("%d", &input);
					  switch (input)
					  {
					  case 1:
						  game(easy_mine_num);
						  input = 0;
						  break;
					  case 2:
						  game(medium_mine_num);
						  input = 0;

						  break;
					  case 3:
						  game(difficult_mine_num);
						  input = 0;

						  break;
					  default:
						  printf("输入有误,重新开始:\n");
					  }
				  } while (input);
		}
				break;
		case 0:
				break;
		default:
			printf("您的选择有误,请重新选择1:\n");
		}
	} while (input);
}
int main()
{
	test();
	system("pause");
	return 0;
}




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值