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 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 扫雷小游戏 -> 正文阅读

[游戏开发]扫雷小游戏

一、游戏设计要求

1.输入坐标,显示周围雷的数目

2.附近没有雷的位置全部展开

3.玩家下第一步棋时,如果踩雷了,判定玩家不死,重新分布雷

二、代码功能

1.菜单界面

选择1开始游戏,0退出游戏

void menu()
{
	printf("***************************\n");
	printf("*********1.开始游戏********\n");
	printf("*********0.退出游戏********\n");
	printf("***************************\n");
}

2.创建2个数组? 一个数组用于设置雷,另外一个数组存放排雷过程中雷的数目

char board[LINES][ROWS] = { 0 };  // 存放雷
char show[LINES][ROWS] = { 0 };//存放之后雷的个数   为了方便排查最外围的雷 ,将方格扩大一圈

#define LINE 9
#define ROW 9
#define LINES 11
#define ROWS 11

?使用宏定义设定数组大小,方便更改

因为在排查雷的时候,需要计数周围一共8个坐标的雷的数目,在9*9的方格中,例如左上角坐标在访问时会出界,所以将9*9的数组扩大一圈,改为11*11数组,但是雷的信息仍储存于9*9格子之中。

3.两个数组的初始化?

board数组用于储存以后的雷,全部初始化为‘0’

show数组?用于储存排查出来的信息,初始化为‘*’

使用char set传入‘0‘ 和’*’

void Initboard(char board[LINES][ROWS], int lines, int rows, char set)
{
	int i = 0; int j = 0;
	for (i = 0; i < lines; i++)
	{
		for (j = 0; j < rows; j++)
		{
			board[i][j] = set;
		}
	}
}

4.打印数组

为了方便输入坐标,打印了行列?

void Displayboard(char board[LINES][ROWS], int line, int row)
{
	int i = 0; int j = 0;
	for (i = 1; i <= line; i++)
	{
		if (i == 1)
		{
			for (j = 0; j <= row; j++)
				printf("%d ", j);
			printf("\n");
		}
		printf("%d ", i);
		for (j = 1; j <= row; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

5.开始设置雷

?使用宏定义设置雷的数目

要求雷的坐标不能越界,不能重复

因为打印了行列,数组坐标从1开始

void Setboard(char board[LINES][ROWS], int line, int row)
{//9*9的格子 范围 1~9
	 srand((unsigned int)time(NULL));
	 int count = COUNT;
	while (count)
	{
		int x = rand() % line + 1;
		int y = rand() % row + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

6.排查雷:Findboard()实现总体控制

int Time = 1;
void Findboard(char board[LINES][ROWS], char show[LINES][ROWS], int line, int row)
{
	int x; int y; 
	int count = Countset(show, LINES, ROW);//show数组中没有展开的坐标总个数
	while (count>COUNT)//循环条件 :show数组中没有被展开的个数比雷的总数要多
	{
		printf("游戏共有%d个雷\n", COUNT);
		printf("请输入坐标,横坐标范围1~%d,纵坐标范围1~%d\n",line,row);
		scanf("%d%d", &x, &y);	
		if (x >= 1 && x <= line && y >= 1 && y <= row) //坐标不能越界
		{
			if (show[x][y] != '*')// 输入已经展开了的坐标,重新进入循环
			{
				printf("该位置已经排过了,请重新输入坐标!\n");
			}
			else if (board[x][y] == '1')//输入的坐标是雷
			{
				if (Time == 1)//第一步下棋中雷,重新分布雷
				{
					printf("刚开始游戏踩到雷,雷已经重新分布\n");
					Safe(board, LINES, ROWS, x, y);
					Findboard(board, show, line, row);
				}
				else //输入的坐标是雷,且不是第一步下棋,死亡
				{
					Sleep(100);
					system("cls");
					printf("踩雷了\n");
					printf("雷的分布情况如图:\n");
					Displayboard(board, LINE, ROW);
					break;// 中雷了跳出循环
				}
			}
			else //输入的坐标不是雷,那么这局游戏不符合重新分布雷的要求,Time值改为0
			{
				Time = 0;
				int   s = Countboard(board, LINES, ROWS, x, y);//记录一周雷的个数
				show[x][y] = s+'0';// 使用ASCII码值的特点,1+’0'='1',使得show数组可以存放雷的数目
				Openboard(board ,show, LINES, ROWS, x, y);//展开坐标周围没有雷的地方
				count = Countset(show, LINES, ROW);//记录剩余show数组没有展开的坐标个数,改变循环条件的比较值
				Sleep(100);
				system("cls");
				Displayboard(show, LINE, ROW);//打印show数组
			}
		}
		else//坐标越界,重新输入
			printf("坐标非法,请重新输入\n");
	}
	if (count == COUNT)//当show数组没有展开的坐标等于雷的总数时,游戏胜利
		printf("排雷成功\n");
}

?Setboard()函数在9*9的数组内部生成雷,要求个数足够且位置不重复

void Setboard(char board[LINES][ROWS], int line, int row)
{//9*9的格子 范围 1~9
	 srand((unsigned int)time(NULL));
	 int count = COUNT;
	while (count)
	{
		int x = rand() % line + 1;
		int y = rand() % row + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count--;
		}
	}
}

Safe()函数在第一次输入坐标就中雷的情况下,将此坐标的雷去除,重新生成另外位置的雷,要求 :雷的位置不能重复?

void Safe(char board[LINES][ROWS], int line, int row, int x, int y) //避免第一次就踩到了雷
{
	board[x][y] = '0';
	int b = 1;
	while (b)
	{
		int x = rand() % line + 1;
		int y = rand() % row + 1;
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			b = 0;
		}
	}

Countboard():统计坐标周围的雷的数目

字符-字符得到数字

int Countboard(char board[LINES][ROWS], int lines, int rows,int x,int y)
{
	return (board[x - 1][y - 1] + board[x - 1][y] +
		board[x - 1][y + 1] + board[x][y - 1] + board[x][y + 1] +
		board[x + 1][y + 1] + board[x + 1][y] +
		board[x + 1][y - 1] - 8 * '0');
}

?Openboard():展开周围没有雷的位置,递归
要求:1.坐标不是雷

? ? ? ? ? ? 2.坐标周围没有雷

? ? ? ? ? ? ?3.为了避免重复扫描一圈中的坐标,在没有被展开的坐标处查找

void Openboard(char board[LINES][ROWS], char show[LINES][ROWS], int lines, int rows, int x, int y)
{
	int ret = Countboard(board, LINES, ROWS, x, y);//ret存放周围雷的数目
	if (ret == 0)//如果周围没有雷,判断周围没有展开的坐标是否有雷  
	{
		show[x][y] = '0';//存放show
		if (x - 1 >= 1 && x - 1 <= LINE && y - 1 >= 1 && y - 1 <= ROW && show[x - 1][y - 1] == '*')//坐标范围
			Openboard(board, show, LINES, ROWS, x - 1, y - 1);
		if (x - 1 >= 1 && x - 1 <= LINE && y + 1 >= 1 && y + 1 <= ROW && show[x - 1][y + 1] == '*')
			Openboard(board, show, LINES, ROWS, x - 1, y + 1);
		if (x - 1 >= 1 && x - 1 <= LINE && y >= 1 && y <= ROW && show[x - 1][y] == '*')
			Openboard(board, show, LINES, ROWS, x - 1, y);
		if (x >= 1 && x <= LINE && y - 1 >= 1 && y - 1 <= ROW && show[x][y - 1] == '*')
			Openboard(board, show, LINES, ROWS, x, y - 1);
		if (x >= 1 && x <= LINE && y + 1 >= 1 && y + 1 <= ROW && show[x][y + 1] == '*')
			Openboard(board, show, LINES, ROWS, x, y + 1);
		if (x + 1 >= 1 && x + 1 <= LINE && y - 1 >= 1 && y - 1 <= ROW && show[x + 1][y - 1] == '*')
			Openboard(board, show, LINES, ROWS, x + 1, y - 1);
		if (x + 1 >= 1 && x + 1 <= LINE && y >= 1 && y <= ROW && show[x + 1][y] == '*')
			Openboard(board, show, LINES, ROWS, x + 1, y);
		if (x + 1 >= 1 && x + 1 <= LINE && y + 1 >= 1 && y + 1 <= ROW && show[x + 1][y + 1] == '*')
			Openboard(board, show, LINES, ROWS, x + 1, y + 1);
	}
	else//当坐标周围有雷时
		show[x][y] = ret + '0';
}

?Countset():统计所有没有展开位置的坐标数目

int Countset(char show[LINES][ROWS], int lines, int rows)
{
	int i, j;
	int count = 0;
	for (i = 1; i <= LINE; i++)
	{
		for (j = 1; j <= ROW; j++)
		{
			if (show[i][j] == '*')
				count++;
		}
	}
	return count;
}

三、代码

我们将以上函数的定义放在 game.c 文件中

game.h声明

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define LINE 9
#define ROW 9
#define LINES 11
#define ROWS 11
#define COUNT 10
void Initboard(char board[LINES][ROWS], int lines, int rows,char set);
void Displayboard(char board[LINES][ROWS], int line, int row);
void Setboard(char board[LINES][ROWS], int line, int row);
void Findboard(char board[LINES][ROWS], char show[LINES][ROWS], int line, int row);
int Countboard(char show[LINES][ROWS], int lines, int rows, int x, int y);
void Openboard(char board[LINES][ROWS], char show[LINES][ROWS], int lines, int rows, int x, int y);
void Safe(char board[LINES][ROWS], int lines, int rows,int x,int y);
int Countset(char show[LINES][ROWS], int lines, int rows);

将game.c,? game.h 放入test.c实现

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"

void game()
{
	char board[LINES][ROWS] = { 0 };  // 存放雷
	char show[LINES][ROWS] = { 0 };//存放之后雷的个数   为了方便排查最外围的雷 ,将方格扩大一圈
	Initboard(board, LINES, ROWS, '0');
	Initboard(show, LINES, ROWS, '*');
	printf("\n");
	Displayboard(show, LINE, ROW);
	Setboard(board, LINE, ROW);// 在中间的9*9格子之中生成雷
	Findboard(board,show ,LINE, ROW);//坐标附近雷的数目传入show数组
}

int main()
{
	int ch = 0;
	do
	{
		menu();
		scanf("%d", &ch);
		switch (ch)
		{
		case 1:printf("开始游戏\n"); system("cls"); game(); break;
		case 0:printf("退出游戏\n"); break;
		default:printf("输入错误,请重新输入\n"); break;
		}
	} while (ch);
	return 0;
}

  游戏开发 最新文章
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-07-31 16:57:47  更:2021-07-31 16:59:02 
 
开发: 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年11日历 -2024/11/18 21:48:34-

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