关于扫雷游戏,你必须知道的一些小事

文章目录

  • 前言
    • 一、游戏分析与设计
    • 1.游戏的过程
    • 2.游戏需要的知识点
      • 2.1随机数函数
      • 2.2头文件的自定义
      • 2.3 宏定义的使用
  • 二.代码的实现与步骤
    • 1.main函数(test.c)
    • 2.game.h(头文件)
    • 3.game函数(game.c)
      • 3.1 InitBoard(初始化函数)``
      • 3.2 DisplayBoard(打印棋盘函数)
      • 3.3 SetMine(布置雷函数)
      • 3.4 FindMine(排查雷函数 )
  • 三.原代码
    • 1.game.h
    • 2.test.c
    • 3.game.c
  • 四.总结


前言

通过,前面的学习,我们学习了,数组与函数(没有写的话,就是本人懒得写了👻),然后我们就可以编写一个的程序,关于扫雷游戏的编程。

一、游戏分析与设计

这里提供了在线玩扫雷的网址,大家可以先玩玩,观察一下
扫雷游戏网页版 - Minesweeper

1.游戏的过程

  1. 首先,本游戏是通过控制台进行的排雷游戏。
  2. 其次,可以通过菜单来控制是否进行游戏。
  3. 难度为9*9的棋盘,有十个雷.
  4. 可以排查雷以及标记雷
    如果该位置是雷,则游戏失败;
    如果该位置不是雷,则可以展开一片直到附近有雷。
  5. 将所有雷都排查出来游戏胜利。

具体流程:
初始化的界面:
请添加图片描述
游戏开始界面:
请添加图片描述
游戏结束页面:
请添加图片描述

2.游戏需要的知识点

2.1随机数函数

我们在这简单的讲述一下:

我们会用到:

rand()>>产出随机数
srand()>>避免rand(),生成假的随机数
time()>>使每次的数都不一样。

#include<stdio.h>
#include<stdlib.h>//srand()的头文件
#include<time.h>//time()的头文件
int main()
{
srand((unsigned int)time(NELL));
//srand要返回正整数型
//time的值不知道,所以用NELL(空)来表示
int i = rand();
printf("%d\n",i);
return 0;
}

这就是随机数的函数的大概写法。

2.2头文件的自定义

我们需要在头文件中创造一个.h的文件,用来存储我们的相关的头文件,函数,宏定义等等,可以使我们的主文件,更简洁,更明了。
请添加图片描述
但主文件中要用 #include" game.h"来引入头文件,是代码可以正常运行。

2.3 宏定义的使用

正如上图所示,宏定义是用 #define 来修饰的 。如:

#define ROW 9
//注意要有空格。

这样,只要头文件中包含,就可以使ROW的值固定为9;且只要在头文件中修改,就可以使全局的值可以修改。

二.代码的实现与步骤

为了程序更加简明,我们需要设立三个文件,分别为:

test.c的源文件 ,用于游戏的逻辑测试。
game.c的源文件,用于游戏各个函数的代码实现。
game.h的头文件,用于函数声明以及各种数据类型的包含。

1.main函数(test.c)

首先为了整个游戏做到可以多次玩,它可以是放在循环里的,这个时候我们可以用一个do while语句来作为主体,玩家是需要选择的,所以我们可以用到switch语句来进行下一步的操作。代码初步如下:

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void mune()
{
	printf("****************\n");
	printf("****1.PLAY******\n");
	printf("****0.EXIT******\n");

}
void test()
{
	
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
	mune();
	printf("请输入你的选项:");
	scanf("%d",&input);
	switch (input)
	{
	case 1:
		game();
		break;
	case 0:
	    printf("GAME OVER\n");
	    break;
	default:
	    printf("输入错误,请重新输入。\n");
	    break;

	}
	} while (input);
}
int main()
{
	test();
	return 0;
}

2.game.h(头文件)

设置 test.c需要的相关的头文件,并且运用宏定义设置棋盘的行与列和雷的个数。

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

#define ROW 9//设置棋盘的行
#define COL 9//设置棋盘的列
#define ROWS ROW+2
#define COLS COL+2

#define EASY_COUNT 10//定好雷的个数为10;

3.game函数(game.c)

3.1 InitBoard(初始化函数)``

因为,在计算机里,对“0”和“1”这两个数非常敏感。而且两个数代表了真与假,所以我们可以用两个数字来代表是否有雷。所以我们可以将数组里全放上“0”,然后再随机生成10个“1”,这可以大概描述游戏的运行布骤。
所以我们先初始化棋盘:

//制作二个二维数组,一个可见,一个不可见;
char mine[ROWS][COLS] = { 0 };//存放雷的信息
char show[ROWS][COLS] = { 0 };//存放排放出的雷的信息

InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;//使棋盘初始化为0;
		}
	}
}

这样,你就可以打印棋盘,使棋盘在控制台中显示出来。

3.2 DisplayBoard(打印棋盘函数)

打印棋盘,但仅仅打印show函数,而不是mine函数,这样我们就可以隐藏埋雷的地图,也可以放后面,中雷后显示出来。

DisplayBoard(show, ROW, COL);

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	printf("******扫雷*****\n");
	int i = 0;
	for(i = 0;i <= col; i++)
	{ 
		printf("%d ", i);
	}
	printf("\n");
	
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}

}

3.3 SetMine(布置雷函数)

布置雷函数,我们需要使用随机数生成函数,并且要保证雷不能在同一位置,从而使雷的个数减少。并且运用count的个数的减少,来判断雷的个数。

SetMine(mine, ROW, COL);

void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		//不能在同一位置
		if (mine[x][y] != '1')
		{
			mine[x][y] = '1';
			count--;
		}
	}

}

3.4 FindMine(排查雷函数 )

这里我们运用了两个函数,其一是,判断周围雷的个数,在我们选的位置上下左右八个位置中,使用while来循环减’0’,因为字符1减字符0,正好等于49-48=1,所以可以计算,周围雷的个数。

FindMine(mine, show, ROW, COL);

int GetMineCount(char mine[ROWS][COLS], int x, int y)
//判断周围雷的个数
{
	int i = 0;
	int count = 0;
	for (i = -1; i <= 1; i++)
	{
		int j = 0;
		for (j = -1; j <= 1; j++)
		{
			count += (mine[x + i][y + j] - '0');//八个位置的和减去'0'>>'1'-'0'=49-48=1>>字符型转整型
		}
	}
	return count;
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;

	while (win < col * row - EASY_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d",&x,&y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')//注意 :==
			{
				printf("很遗憾,你踩雷了,游戏结束\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int count = GetMineCount(mine, x, y);
				show[x][y] = count + '0';
				DisplayBoard(show, ROW, COL);
				win++;
		    }	
		}
		else
		{
			printf("输入的坐标有误x(1~9),y(1~9),重新输入");

	     }	
	}
	if (win == row * col - EASY_COUNT)
		{
			printf("恭喜你,排雷成功\n");
			DisplayBoard(mine, ROW, COL);
		}
	
}

这样,进行编写,你就可以得到排雷游戏的大概编写思路,如何有了清晰的了解,你也可以进行尝试,并对照下方的原代码。

三.原代码

1.game.h

#pragma once

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

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

#define EASY_COUNT 10

//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);

//布置雷
void SetMine(char mine[ROWS][COLS], int row, int col);

//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);



2.test.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void mune()
{
	printf("****************\n");
	printf("****1.PLAY******\n");
	printf("****0.EXIT******\n");

}
void game()
{
	//制作二个二维数组,一个可见,一个不可见;
	char mine[ROWS][COLS] = { 0 };//存放雷的信息
	char show[ROWS][COLS] = { 0 };//存放排放出的雷的信息

	//初始化棋盘
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');


	//打印棋盘
	DisplayBoard(show, ROW, COL);


	//布置雷
	SetMine(mine, ROW, COL);

	//开始排雷
	FindMine(mine, show, ROW, COL);

}
void test()
{
	
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
	mune();
	printf("请输入你的选项:");
	scanf("%d",&input);
	switch (input)
	{
	case 1:
		game();
		break;
	case 0:
	    printf("GAME OVER\n");
	    break;
	default:
	    printf("输入错误,请重新输入。\n");
	    break;

	}
	} while (input);
}
int main()
{
	test();
	return 0;
}

3.game.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}
 
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	printf("******扫雷*****\n");
	int i = 0;
	for(i = 0;i <= col; i++)
	{ 
		printf("%d ", i);
	}
	printf("\n");
	
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}

}


//布置雷>>棋盘随机10各个坐标
void SetMine(char mine[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	int x = 0;
	int y = 0;
	while (count)
	{
		x = rand() % row + 1;
		y = rand() % col + 1;
		//不能在同一位置
		if (mine[x][y] != '1')
		{
			mine[x][y] = '1';
			count--;
		}
	}

}

//排查雷
int GetMineCount(char mine[ROWS][COLS], int x, int y)
//判断周围雷的个数
{
	int i = 0;
	int count = 0;
	for (i = -1; i <= 1; i++)
	{
		int j = 0;
		for (j = -1; j <= 1; j++)
		{
			count += (mine[x + i][y + j] - '0');//八个位置的和减去'0'>>'1'-'0'=49-48=1>>字符型转整型
		}
	}
	return count;
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;

	while (win < col * row - EASY_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d",&x,&y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')//注意 :==
			{
				printf("很遗憾,你踩雷了,游戏结束\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int count = GetMineCount(mine, x, y);
				show[x][y] = count + '0';
				DisplayBoard(show, ROW, COL);
				win++;
		    }	
		}
		else
		{
			printf("输入的坐标有误x(1~9),y(1~9),重新输入");

	     }	
	}
	if (win == row * col - EASY_COUNT)
		{
			printf("恭喜你,排雷成功\n");
			DisplayBoard(mine, ROW, COL);
		}
	
}


四.总结

对于这个排雷游戏,还有很多功能等待开发与维护,以后也会不定期更新优化这个小游戏的,如有其他有趣的想法也会在第一时间与大家分享!

  • 31
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值