C语言学习—扫雷游戏(尝试)

目录

一、描述

二、思路

三、实现

1  游戏的开始与退出

1)打印菜单

2)选择

2  初始化棋盘

1)定义棋盘框架

2)定义初始函数

3)初始化棋盘

3  打印棋盘

4  随机生成地雷

5  判断

6  game()

四、总代码

1  game.h:声明函数

2  game.cpp:存放自定义函数

3   扫雷.cpp:实现游戏


一、描述

扫雷游戏网页版 - Minesweeper

尝试用C语言实现扫雷游戏

二、思路

将游戏分为几个模块,分别实实现:

1  游戏开始与退出的选择

2  初始化棋盘

3  打印棋盘

4  在随机坐标生成n个地雷并埋在棋盘上

5  判断输入的坐标有无地雷,有则游戏结束,无则统计该坐标附近的地雷个数并输出

6  联系以上模块实现游戏函数game()

三、实现

1  游戏的开始与退出

1)打印菜单

定义一个函数,专门用来打印菜单

//打印菜单
void Dycd()
{
	printf("==============================\n");
	printf("---------1.开始游戏-----------\n");
	printf("---------0.退出游戏-----------\n");
	printf("==============================\n");
}

2)选择

对输入的数字进行判断,,如果是数字 1 就开始游戏,数字 就退出游戏,如果两个数字都不是,即重新选择 ,由于程序至少运行一次,这里使用do while循环

	int n = 0;
	do
	{
		Dycd();
		printf("请选择:");
		scanf("%d", &n);
		switch (n)
		{
		case 0:
			printf("退出游戏!!!\n");
			break;
		case 1:
			printf("游戏开始!!!\n");
			game();
			break;
		default:
			printf("输入错误,请重新选择!!!\n");
			break;
		}

	} while (n);

2  初始化棋盘

1)定义棋盘框架

假设游戏的棋盘框架是n*n的,但由于在后面统计输入的坐标附近的地雷个数时,是统计以该坐标为中心形成的九宫格的地雷个数,而位于边界的坐标不方便统计,所以这里设置内置棋盘是框架(n+2)*(n+2),而真正游戏中操作并输出的棋盘框架为n*n

所以这里定义棋盘的内置行、内置列、输出行和输出列,棋盘设置为9*9

#define Hang 9//输出行
#define Lie 9//输出列
#define Nhang Hang+2//内置行
#define Nlie Lie+2//内置列

2)定义初始函数

专门用来初始化棋盘,将想要的字符布置在棋盘里

//初始化棋盘
void Csh(char Sz[Nhang][Nlie],int nhang,int nlie, char zf)
{
	for (int x = 0; x < nhang; x++)
	{
		for (int y = 0; y < nlie; y++)
		{
			Sz[x][y] = zf;
		}
	}
}

3)初始化棋盘

创建两个字符类型的二维数组,一个作为内置棋盘来存放无地雷信息的"0"和有地雷信息的"1",另一个则作为输出棋盘用“X”将地雷信息隐藏,且可以在输入的坐标输出坐标附近的地雷个数

	//内置棋盘
	char Nqp[Nhang][Nlie] = { 0 };
	//存放内置棋盘信息并输出的棋盘
	char Sqp[Nhang][Nlie] = { 0 };
	//初始化棋盘
	Csh(Nqp, Nhang, Nlie, '0');
	Csh(Sqp, Nhang, Nlie, ' X');

3  打印棋盘

定义一个函数,可以在需要的时候调用打印输出棋盘,同时可以在棋盘的打印相应的X轴Y轴,便于游戏时辨认坐标

//打印棋盘
void print(char Sz[Nhang][Nlie])
{
	printf("========扫雷========\n");
	for (int i = 0; i <= Hang; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int x = 1; x <= Hang; x++)
	{
		printf("%d ", x);
		for (int y = 1; y <= Lie;y++)
		{
			printf("%c ", Sz[x][y]);
		}
		printf("\n");
	}
}

4  随机生成地雷

这里定义生成地雷的地雷个数为10

#define DL 10//存放地雷的个数

这里利用rand()函数随机生成坐标,但由于rang()生成的坐标并不完全随机,所以还要利用srand()time()函数初始化rand()函数(由于初始化只需要一次所以放置在game()函数里

//随机存放地雷
void Cfdl(char Sz[Nhang][Nlie])
{
	int n = DL;
	while (n)
	{
		//生成地雷的随机坐标
		int x = rand() % Hang + 1;
		int y = rand() % Lie + 1;
		//将地雷存放在内置棋盘里,并判断生成的随机坐标是否重合
		if (Sz[x][y] != '1')
		{
			Sz[x][y] = '1';
			n--;
		}
	}
}

5  判断

判断输入的坐标有无地雷,有则游戏结束,无则统计以该坐标为中心形成的九宫格的地雷个数并输出,这里通过数字 1 和数字 0asll码值相加相减来统计地雷个数

/*判断输入的坐标有没有地雷,
无地雷就在输入的坐标输出该坐标附近有多少个地雷,
有地雷就结束游戏*/
int Pd(char Nsz[Nhang][Nlie],char Sz[Nhang][Nlie], int x, int y)
{
	int n = 0;//存放该坐标附近地雷个数
	if (Nsz[x][y] == '1')
	{
		return 0;//返回0结束游戏
	}
	else
	{
		//计算该坐标附近地雷个数
		for (int i = -1; i < 2; i++)
		{
			for (int j = -1; j < 2; j++)
			{
				n += (Nsz[x + i][y + j] - '0');
			}
		}
		//将地雷数量存放在输出棋盘里
		Sz[x][y] = n + '0';
		return 1;//返回1则继续游戏
	}
}

6  game()

联系以上模块实现游戏函数game()

//扫雷游戏
void game()
{
	//初始化随机数生成器
	srand((unsigned int)time(NULL));
	//内置棋盘
	char Nqp[Nhang][Nlie] = { 0 };
	//存放内置棋盘信息并输出的棋盘
	char Sqp[Nhang][Nlie] = { 0 };
	//初始化棋盘
	Csh(Nqp, Nhang, Nlie, '0');
	Csh(Sqp, Nhang, Nlie, ' X');
	//打印初始化棋盘
	//print(Nqp);
	print(Sqp);
	//存放地雷
	Cfdl(Nqp);
	//print(Nqp);
	//输入坐标、判断并输出
	int x = 0, y = 0, n = Hang*Lie-DL;
	while (n)
	{
		printf("请输入坐标(x,y):");
		scanf("%d %d", &x, &y);
		if (((x > 0 && x <= Hang) && (y > 0 && y <= Lie)) && (Pd(Nqp, Sqp, x, y)))
		{
			print(Sqp);
			n--;
		}
		else if(((x > 0 && x <= Hang) && (y > 0 && y <= Lie)) && (Pd(Nqp, Sqp, x, y)) == 0)
		{
			printf("你死了。。。。。。\n游戏结束!!!\n");
			return;
		}
		else
		{
			printf("输入错误,请重新输入!!!\n");
		}
	}
	printf("排雷成功!!!\n游戏结束\n");
}

四、总代码

这里分别创建三个文件来实现游戏

1  game.h:声明函数

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#define Hang 9//输出行
#define Lie 9//输出列
#define Nhang Hang+2//内置行
#define Nlie Lie+2//内置列

#define DL 10//存放地雷的个数

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

//打印菜单
void Dycd(void);

//初始化数组
void Csh(char Nsz[Nhang][Nlie], int nhang, int nlie, char zf);

//打印棋盘
void print(char Sz[Nhang][Nlie]);

//随机存放地雷
void Cfdl(char Sz[Nhang][Nlie]);

/*判断输入的坐标有没有地雷,
无地雷就在输入的坐标输出该坐标附近有多少个地雷,
有地雷就结束游戏*/
int Pd(char Nsz[Nhang][Nlie], char Sz[Nhang][Nlie], int x, int y);

2  game.cpp:存放自定义函数

#include"game.h"

//打印菜单
void Dycd()
{
	printf("==============================\n");
	printf("---------1.开始游戏-----------\n");
	printf("---------0.退出游戏-----------\n");
	printf("==============================\n");
}

//初始化棋盘
void Csh(char Sz[Nhang][Nlie],int nhang,int nlie, char zf)
{
	for (int x = 0; x < nhang; x++)
	{
		for (int y = 0; y < nlie; y++)
		{
			Sz[x][y] = zf;
		}
	}
}

//打印棋盘
void print(char Sz[Nhang][Nlie])
{
	printf("========扫雷========\n");
	for (int i = 0; i <= Hang; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int x = 1; x <= Hang; x++)
	{
		printf("%d ", x);
		for (int y = 1; y <= Lie;y++)
		{
			printf("%c ", Sz[x][y]);
		}
		printf("\n");
	}
	printf("——————————\n");
}

//随机存放地雷
void Cfdl(char Sz[Nhang][Nlie])
{
	int n = DL;
	while (n)
	{
		//生成地雷的随机坐标
		int x = rand() % Hang + 1;
		int y = rand() % Lie + 1;
		//将地雷存放在内置棋盘里,并判断生成的随机坐标是否重合
		if (Sz[x][y] != '1')
		{
			Sz[x][y] = '1';
			n--;
		}
	}
}

/*判断输入的坐标有没有地雷,
无地雷就在输入的坐标输出该坐标附近有多少个地雷,
有地雷就结束游戏*/
int Pd(char Nsz[Nhang][Nlie],char Sz[Nhang][Nlie], int x, int y)
{
	int n = 0;//存放该坐标附近地雷个数
	if (Nsz[x][y] == '1')
	{
		return 0;
	}
	else
	{
		//计算该坐标附近地雷个数
		for (int i = -1; i < 2; i++)
		{
			for (int j = -1; j < 2; j++)
			{
				n += (Nsz[x + i][y + j] - '0');
			}
		}
		//将地雷数量存放在输出棋盘里
		Sz[x][y] = n + '0';
		return 1;
	}
}



3   扫雷.cpp:实现游戏

#include"game.h"

//扫雷游戏
void game()
{
	//初始化随机数生成器
	srand((unsigned int)time(NULL));
	//内置棋盘
	char Nqp[Nhang][Nlie] = { 0 };
	//存放内置棋盘信息并输出的棋盘
	char Sqp[Nhang][Nlie] = { 0 };
	//初始化棋盘
	Csh(Nqp, Nhang, Nlie, '0');
	Csh(Sqp, Nhang, Nlie, ' X');
	//打印初始化棋盘
	//print(Nqp);
	print(Sqp);
	//存放地雷
	Cfdl(Nqp);
	//print(Nqp);
	//输入坐标、判断并输出
	int x = 0, y = 0, n = Hang*Lie-DL;
	while (n)
	{
		printf("请输入坐标(x,y):");
		scanf("%d %d", &x, &y);
		if (((x > 0 && x <= Hang) && (y > 0 && y <= Lie)) && (Pd(Nqp, Sqp, x, y)))
		{
			print(Sqp);
			n--;
		}
		else if(((x > 0 && x <= Hang) && (y > 0 && y <= Lie)) && (Pd(Nqp, Sqp, x, y)) == 0)
		{
			printf("你死了。。。。。。\n游戏结束!!!\n");
			return;
		}
		else
		{
			printf("输入错误,请重新输入!!!\n");
		}
	}
	printf("排雷成功!!!\n游戏结束\n");
}

int main()
{
	int n = 0;
	do
	{
		Dycd();
		printf("请选择:");
		scanf("%d", &n);
		switch (n)
		{
		case 0:
			printf("退出游戏!!!\n");
			break;
		case 1:
			printf("游戏开始!!!\n");
			game();
			break;
		default:
			printf("输入错误,请重新选择!!!\n");
			break;
		}

	} while (n);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值