IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> C语言实现小游戏 ---扫雷 -> 正文阅读

[游戏开发]C语言实现小游戏 ---扫雷

目录

一.游戏介绍

二.游戏思路

三.游戏实现步骤

1.游戏菜单

2.创建和初始化游戏棋盘

3.如何打印棋盘

4.布置雷的信息

5.排查雷

6.获胜机制

四.效果展示

五.代码总结

1.test.c内容:

2.game.c内容

3.game.h内容


一.游戏介绍


二.游戏思路

? ? ? ? 1.为了方便协作,可以将工程分成三个文件。其中game.c :游戏函数的实现

?game.h:游戏函数的声明? test.c :游戏测试

? ? ? ? 2.我们可以创建两个相同大小的二维数组,一个用来存放雷的信息- mine数组,一个供玩家排雷的show数组。

当玩家输入坐标时,在存放雷信息的二维数组中计算其周围含雷的个数,放到供玩家排雷数组的对于坐标处。若我们玩9*9的排雷游戏,建议创建11*11的二维数组。

?

这样的话,方便显示行标和列标,以及防止输入边缘坐标时,计算旁边雷的个数时 数组越界。

? ? ? ? 所以我们要定义4个变量 行标,列标为11。以及行标,列标为9。? 因为初始化时要初始化11*11的数组,而打印时只打印9*9的数组。


三.游戏实现步骤

1.游戏菜单

void menu()
{
	printf("********************************\n");
	printf("*********   1. play     ********\n");
	printf("*********   0. exit     ********\n");
	printf("********************************\n");
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	} while (input);

2.创建和初始化游戏棋盘

为了方便后续有什么改动之类的,可以用#define宏定义行和列

? ? 雷我们可以用‘1’表示,非0用‘0’表示。 为了保持神秘感,最初展示给用户的棋盘最好是*号棋盘,所以我们最初初始化就要注意要把设置的字符也传过去。

? ? ? ? 要把11*11的数组都初始化了,且存放雷的信息的数组初始化为0(0为非雷),防止后续计算9*9数组边界的雷的个数时越界/雷数出错。

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;
		}
	}
}

3.如何打印棋盘

? ? ? ? 注意:打印时只需要把9*9的数组打印出来即可。还可以把行标和列标也打印出来。

注意:对于11*11内部的9*9数组,下标是从1到9的元素。(可看上面的图)

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("------------------------\n");
	for (i = 0; i <= 9; i++)        //打印行标
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)       //打印列标
	{
		int j = 0;
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("------------------------\n");
}

4.布置雷的信息

? ? ? ? ?1.布置雷的位置要随机,所以我们使用rand()函数,rand()%row ->范围是0-row-1,rand()%col -> 范围是0-col-1;? ?刚好符合二维数组的下标范围。 使用rand()函数还需要使用srand和time()函数设置随机数的生成起点,具体的大家可以在cplusplus网站或者MSDN网站上搜rand()函数的注意事项,具体我就不展开了。

? ? ? ? 2.设置雷的个数。同样,为了方便后续提高/降低难度,我们可以宏定义雷的个数

? ? ? ? 每次安放一个雷,count-1;直到count为0.

3.注意雷是否重复安放? (雷用‘1’表示)

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;

	while (count)
	{
		//1. 生成随机下标
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

5.排查雷

? ? 1.当用户输入坐标时,我们首先要检查坐标的合法性,防止越界。

? ? 2.在存放雷信息的数组中计算雷的个数,把对于的整形数字放到用户输入的坐标下。

? ? 3.当排查时遇到雷时,游戏结束。把棋盘打印出来给用户查看。

int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][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] - 8 * '0');
}

void FindMine(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 >= 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);
			}
		}
		else
		{
			printf("坐标非法,重新输入\n");
		}
	}

注意:如何得到周围有几个雷?

-> 这就是为什么最开始以1为雷 0为不是雷,这样方便,字符1的个数有几个,就有几个雷!但字符要转化为整数,坐标旁边的8个坐标-字符0得到的值就是雷的个数(整数) 所以可以先全部加起来再减8个字符0。

?????????????????‘3’? - ‘0’ = 3


6.获胜机制

? ? ? ? 上面循环用的是while(1),除非踩到雷了,否则会一直死循环,所以怎么样游戏才结束呢?

->我们注意到,我们现在定义雷的个数是10,而9*9的棋盘有81个坐标,所以只要我们定义一个变量win,每当排查掉一个坐标,win++,当win=71时,排雷成功,并把棋盘打印给用户观看。

所以我们只需要对上面代码做稍微的修改:

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 < row * col - 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("坐标非法,重新输入\n");
		}
	}

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


四.效果展示

? 为了方便展示,我把雷的坐标定义为80个,并把存放雷的信息的棋盘打印出来,观察逻辑有无问题

?


五.代码总结

1.test.c内容:


#include "game.h"

void menu()
{
	printf("********************************\n");
	printf("*********   1. play     ********\n");
	printf("*********   0. exit     ********\n");
	printf("********************************\n");
}

void game()
{
	char mine[ROWS][COLS] = { 0 };//存放雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
	//初始化一下棋盘
	InitBoard(mine, ROWS, COLS, '0');//'0'
	InitBoard(show, ROWS, COLS, '*');//'*'

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

	//排查雷
	FindMine(mine, show, ROW, COL);
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,重新选择!\n");
			break;
		}
	} while (input);

	return 0;
}

? ? ? ?

2.game.c内容



#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)
{
	int i = 0;
	printf("------------------------\n");
	for (i = 0; i <= 9; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		int j = 0;
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
	printf("------------------------\n");
}


void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;

	while (count)
	{
		//1. 生成随机下标
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][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] - 8 * '0');
}

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 < row * col - 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("坐标非法,重新输入\n");
		}
	}

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

3.game.h内容


#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 board[ROWS][COLS], int row, int col);

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

总结:本篇扫雷小游戏到此就结束了,希望本文章对大家有所帮助!如果感觉文章对你有帮助的,请多多评论,点赞支持一下!谢谢大家!

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-01 14:48:33  更:2021-08-01 14:48:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 4:33:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码