ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

扫雷小游戏

2021-07-29 18:31:31  阅读:162  来源: 互联网

标签:ROWS show int LINES char 小游戏 扫雷 board


一、游戏设计要求

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():展开周围没有雷的位置,递归

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

标签:ROWS,show,int,LINES,char,小游戏,扫雷,board
来源: https://blog.csdn.net/m0_58342797/article/details/119215812

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有