扫雷游戏的代码与分析

本文详细介绍了如何创建一个简单的在线扫雷游戏,包括设计雷的位置、使用11*11数组初始化游戏页面、防止越界、输出游戏界面、随机放置雷、排雷逻辑以及用户交互。
摘要由CSDN通过智能技术生成

在线扫雷游戏:http://www.minesweeper.cn/,如果大家感兴趣的话可以先玩一会,感受下,咱们做个简单一点的

一:创造游戏页面

1.我们把雷设计位数字1,无雷变为0,方便我们后续计算周边雷的个数。但是这样可能会混淆1到底是雷还是它周围类的个数,所以我们可以创造两个游戏页面。2.为了防止我们在排查周围雷的个数时出现越界现象,所以我们选择11*11的数组。如下图为我们想要的游戏界面,游戏页面的初始化代码已经在下面了,我们接下来输出游戏页面

void Initboard(char chess[row][col], int ROWs, int COLs, char set)//函数的形式展现,在主函数调用即可,且row=col=11,ROWs=COLs=9
{
	for (int i = 1;i <= ROWs;i++)//设置9*9的棋盘,但为防止在查找周边雷的个数时越界,数组定义为11*11的
	{
		for (int j = 1;j <= COLs;j++)
			chess[i][j] = set;//set可以是'0','1','*',这样使棋盘的初始化变得简单
	}
}

二.输出游戏页面

1.我们还是采用在主函数调用函数的形式,注意我们打印出的形式一般是这样A图的,但是我们一般选择隐藏(就是不输出)埋雷的页面B图

代码如下

void printboard(char chess[row][col], int ROWs, int COLs)
{
	int i = 0;
	for (i = 0;i < row;i++)//打印0~10,方便玩家输入坐标
		printf("%d ", i);//%xd可控制列宽
	printf("\n");
	for (int k = 1;k < ROWs;k++)
	{
		printf("%d", k);//打印1~10,方便玩家输入坐标
		for (int j = 1;j <= COL;j++)
		{
			printf("%c ", chess[k][j]);//棋盘的打印
		}
		printf("\n");
	}
}//打印棋盘

三.布置雷

 1.雷是随便放的,需要用到rand函数,我们把雷设置为字符’1‘。代码如下

void setfire(char chess[row][col], int ROWs, int COLs)
{
	int count = fire;//fire为雷的个数,为方便后续操作可以方便的任意更改雷的个数,我们可以在程序的开始定义雷的个数#define fire 10
	while (count)
	{
		int x = rand() % ROWs + 1;//x,y只能是在1~9的任意一个数
		int y = rand() % COLs + 1;
		if (chess[x][y] == '0')
		{
			chess[x][y] = '1';
			count--;
		}
	}

}//放雷

三.排雷

1.用户输入坐标,程序检查该处是否是雷,如果不是雷在该处显示雷的个数。

思考的问题:(1)该处有无雷,有雷则被炸死,无雷周围有几个雷(2)游戏结束的条件

int countfire(char chess[row][col], int x, int y)
{
	int count=0;
	for ( int i = 0;i <= 2;i++)
	{
		for (int j = 0;j <= 2;j++)
		{
			if (show1[x + i - 1][y + j - 1] == '1')
				count++;//如果不是雷则反映该处雷的个数
		}
	}
	return count;
}
void findfire(char show1[row][col],char show2[row][col], int ROWs, int COLs)//char show2是玩家的游戏页面的函数,char show1 是埋雷的函数
{
	int x = 1, y = 1;
	int l = 0;
	while (l < ROWs * COLs - fire)//循环终止条件
	{
		printf("请输入要排查的坐标:");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= ROWs && y >= 1 && y <= COLs)
		{
			if (show1[x][y] == '1')
			{
				printf("what a pity,game over\n");
				printboard(show1,ROWs,COLs);//
				break;
			}
			else
			{
				l++;
				int y = countfire(show1, x, y);
				show2[x][y] = y + '0';//把在埋雷函数周边的雷,反馈给show2,呈现给用户
				printboard(show2, ROWs, COLs);
			}
		}
		else
			printf("请输入合法坐标: ");
	}
	if (l == ROWs * COLs - fire)
		printf("恭喜你,雷已经被全部找出\n");
}

写到这里差不多要结束了,还有点细节需要打磨。当然也可以以多个文件的形式书写,you can try try

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9
#define COL 9
#define row ROW+2
#define col COL+2
#define fire 10
//棋盘的外观1.初始化棋盘
/*void Initboard(char chess[row][col], int ROWs, int COLs, char set);
void printboard(char chess[row][col], int ROWs, int COLs);
void setfire(char chess[row][col], int ROWs, int COLs);
void findfire(char show1[row][col], char show2[row][col], int ROWs, int COLs);
int countfire(char show1[row][col], int x, int y);*/
//#include "game.h"
void Initboard(char chess[row][col], int ROWs, int COLs, char set)
{
	for (int i = 1;i <= ROWs;i++)
	{
		for (int j = 1;j <= COLs;j++)
			chess[i][j] = set;
	}
}//初始化棋盘
void printboard(char chess[row][col], int ROWs, int COLs)
{
	int i = 0;
	for (i = 0;i <= ROWs;i++)
		printf("%d ", i);//%2d可控制列宽
	printf("\n");
	for (int k = 1;k <= ROWs;k++)
	{
		printf("%d ", k);
		for (int j = 1;j <= COL;j++)
		{
			printf("%c ", chess[k][j]);
		}
		printf("\n");
	}
}//打印棋盘
void setfire(char show1[row][col], int ROWs, int COLs)
{
	int count = fire;
	while (count)
	{
		int x = rand() % ROWs + 1;
		int y = rand() % COLs + 1;
		if (show1[x][y] == '0')
		{
			show1[x][y] = '1';
			count--;
		}
	}

}//放雷
//排查周围的雷
int countfire(char show1[row][col], int x, int y)
{
	int count = 0;
	for (int i = 0;i <= 2;i++)
	{
		for (int j = 0;j <= 2;j++)
		{
			if (show1[x + i - 1][y + j - 1] == '1')
				count++;
		}
	}
	return count;
}
void findfire(char show1[row][col], char show2[row][col], int ROWs, int COLs)//排雷
{
	int x = 0;
	int y = 0;
	int l = 0;
	while (l < ROWs * COLs - fire)
	{
		printf("请输入要排查的坐标:");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= ROWs && y >= 1 && y <= COLs)
		{
			if (show1[x][y] == '1')
			{
				printf("what a pity,game over\n");
				printboard(show1, ROWs, COLs);
				break;
			}
			else
			{
				l++;
				int k = countfire(show1, x, y);
				show2[x][y] = k + '0';
				printboard(show2, ROWs, COLs);
			}
		}
		else
			printf("请输入合法坐标");
	}
	if (l == ROWs * COLs - fire)
		printf("successful find fires");
}
void menu()
{
	printf("******************\n");
	printf("***** 1. play *****\n");
	printf("***** 0. notplay *****\n");
	printf("*******************\n");
}
void game()
{
	char show1[row][col], show2[row][col];//定义两个字符型的函数,show1为埋雷的函数,show2为玩家游戏页面
	Initboard(show2, ROW, COL, '*');
	Initboard(show1, ROW, COL, '0');
	printboard(show2, ROW, COL);
	setfire(show1, ROW, COL);
	findfire(show1, show2, 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值