C语言扫雷游戏

本文详细介绍了使用C语言实现的一个基础扫雷游戏,包括菜单设计、游戏流程(do-while循环和switch选择)、棋盘数据结构(9x9扩展到11x11)、雷的随机布置、棋盘初始化和打印、以及排查雷的逻辑。
摘要由CSDN通过智能技术生成

1.菜单的打印

玩游戏菜单不可缺少,首先进行菜单的互动。

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

玩游戏不可能只玩一把,我们利用do(while),循环来实现多把游戏,同时利用switch语句实现功能的选择

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			printf("扫雷\n");
			break;

		case 2:
			printf("退出游戏\n");
			break;

		default:
			printf("输入错误,请重新输入\n");
			break;
		}



	} while (input!=2);
	return 0;
}

这个时候运行代码(游戏代码部分并没有写入)

代码运行结果

2.扫雷游戏的底层逻辑

我们先玩一把扫雷,了解扫雷游戏的运行关系

 基础版是个9*9的棋盘,左上角显示雷的数量,点击一下

 展开了一部分,1代表周围8个格子中有一个雷,2代表周围8个格子中有两个雷,依次类推

 点到雷就game over。

那我们就对扫雷有个基础的了解:

1.如果排查的位置是雷,就game over。

2.如果排查的位置不是雷,就显示周围雷的数量

那么我们首先完成对棋盘的数据的记录

这是一个对数据的记录,我们利用9*9的数组来实现,利用0代表空,1代表雷,来区分这个位置是否有雷,但是如果这样布置会出现一个问题

 按照我们的逻辑这个时候黄色区域中间的0应该会显示为1,虽然可行,但是我们所需要打印的棋盘会很杂乱。所以我们会在创建一个数组,专门来存放我们排查雷的信息,实例如下

        如果我们点击的黄色区域的中间区域,我们就将下面这个“*”的矩阵相同位置替换成“1”,这样就达到了我们的目标。                                                                                                                            但是9*9的格子就够用了吗?

 我们排查雷时,需要排查周围8个方格,但是当我们排查到边界时,这个时候就越界了,所以我们创建一个11*11的数组,边界全部放“0”,这个时候越界的问题就解决了

     01数组我们命名为“ben”,“*”数组我们命名为“xian”,那么01数组应该初始化为0,先数组应该初始化为“*”,同时为了方便,我们都将数组命名字符数组。

  

void game()
{
	//数组的创建
	char ben[11][11];
	char xian[11][11];
	shuzuchushihua(ben, 11, 11);
    shuzuchushihua(xian, 11, 11);
}

这个时候只需要编写shuzuchushihua就可以了,但是这样不方便我们以后代码的更改,如果我们想让棋盘更大我能就需要更改掉所有的11,过于麻烦,这个时候我们可以创建新的头文件来帮助我们

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

  在把头文件放到我们所需的.c文件中就行

 这个时候我们下面的代码改为这样

void game()
{
	//数组的创建
	char ben[ROWS][COLS];
	char xian[ROWS][COLS];
	shuzuchushihua(ben, ROWS, COLS,'0');
	shuzuchushihua(xian, ROWS, COLS,'*');
}

这样就方便我们以后的更改了

棋盘的初始化

我们创建了一个中间量set这样可以分别打印我们的字符了

void shuzuchushihua(char board[ROWS][COLS], int rows, int cols,char set)
{
	int j = 0;
	for (j = 0; j < rows; j++)
	{
		int i = 0;
		for (i = 0; i < cols; i++)
		{
			board[j][i] = set;
		}
	}
}

棋盘的打印

void DY(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf(" ");//空格不能省略,因为会不好看
	for ( i = 1; i <=row; 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个雷,我们利用srand这个函数来实现,同时利用time用作种子生成随机数,并且我们只需要1-9的数,所以我们将其取模10,就可以得到随机的1-9了

void setben(char ben[ROWS][COLS], int row, int col)
{
	int count = 10;//雷的数量
	
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//生成随机的横坐标和纵坐标。
		if ( ben[x][y]=='0')
		{
			ben[x][y] = '1';
			count--;
		}
		
	}
}
我这里用的是row+1,之前定义row为9,9+1=10,效果一样

这里用到的rand函数需要新的头文件

 运行出来的结果

当然我们运行时只会展示“*”这个棋盘,这个01棋盘我们不会展示出来

 排查雷

 我们排查的范围是个9*9的数组,同时将周围的字符“1”的数量显示出来,并且换成一个值替换到字符“*”棋盘中,根据ASCII表可知,字符“1”与字符“0”仅仅相差一位,所以我们可以把排查点周围所有的字符加起来-8*“0”就可以得到雷的数量。

//显示雷的数量
int XS(char ben[ROWS][COLS], int x, int y)
{
	return (ben[x - 1][y - 1]
		+ ben[x - 1][y]
		+ ben[x - 1][y + 1]
		+ ben[x][y - 1]
		+ ben[x][y + 1]
		+ ben[x + 1][y - 1]
		+ ben[x + 1][y]
		+ ben[x + 1][y + 1]
		- 8 * '0');
}

//排查雷
void chazhao(char ben[ROWS][COLS],char xian[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	
	while (win < row * col - 10)//胜利条件
	{
		printf("请输入排查的坐标:");
		scanf_s("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (ben[x][y] == '1')
			{
				printf("game over\n");
				DY(ben, ROW, COL);
				break;
			}
			else
			{
				//得到这个坐标周围雷的数量
				int count = XS(ben, x, y);
				xian[x][y] = count + '0';
				DY(xian, ROW, COL);
				win++;
			}
				
		}
		else
		{
			printf("坐标非法,请重新输入:\n");
			break;
		}
	}
	if (win == row * col - 10)
	{
		printf("game win\n");
	}
}

完整代码


//游戏代码

#include "game.h"
//初始化数组
void shuzuchushihua(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 DY(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	for ( i = 0; i <=row; 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");
	}
}
//生成雷
void setben(char ben[ROWS][COLS], int row, int col)
{
	int count = 10;//雷的数量
	
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//生成随机的横坐标和纵坐标。
		if ( ben[x][y]=='0')
		{
			ben[x][y] = '1';
			count--;
		}
		
	}
}

//显示雷的数量
int XS(char ben[ROWS][COLS], int x, int y)
{
	return (ben[x - 1][y - 1]
		+ ben[x - 1][y]
		+ ben[x - 1][y + 1]
		+ ben[x][y - 1]
		+ ben[x][y + 1]
		+ ben[x + 1][y - 1]
		+ ben[x + 1][y]
		+ ben[x + 1][y + 1]
		- 8 * '0');
}

//排查雷
void chazhao(char ben[ROWS][COLS],char xian[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	
	while (win < row * col - 10)//胜利条件
	{
		printf("请输入排查的坐标:");
		scanf_s("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (ben[x][y] == '1')
			{
				printf("game over\n");
				DY(ben, ROW, COL);
				break;
			}
			else
			{
				//得到这个坐标周围雷的数量
				int count = XS(ben, x, y);
				xian[x][y] = count + '0';
				DY(xian, ROW, COL);
				win++;
			}
				
		}
		else
		{
			printf("坐标非法,请重新输入:\n");
			break;
		}
	}
	if (win == row * col - 10)
	{
		printf("game win\n");
	}
}



	
//菜单代码
#include "game.h"

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

void game()
{
	//数组的创建
	char ben[ROWS][COLS];
	char xian[ROWS][COLS];
	shuzuchushihua(ben, ROWS, COLS,'0');
	shuzuchushihua(xian, ROWS, COLS,'*');
	//打印棋盘
	DY(xian, ROW, COL);
	//DY(ben, ROW, COL);
	//布置雷
	setben(ben,ROW,COL);
	//
	//排查雷
	chazhao(ben,xian, ROW, COL);
}


int main()
{
	int input = 0;
	srand((unsigned)time(NULL));
	do

	{
		menu();
		printf("请选择:");
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}

	} while (input!=2);

	return 0;
}
//函数调用和头文件
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define _CAR_SECURE_NO_WARNINGS 1
//初始化棋盘
void shuzuchushihua(char board[ROWS][COLS], int rows, int cols,char set);
//打印棋盘
void DY(char board[ROWS][COLS], int rows, int cols);
//布置雷
void setben(char ben[ROWS][COLS], int row, int col);
//排查雷
void chazhao(char ben[ROW][COL],char xian[ROW][COL], int row, int col);
//显示雷
int XS(char ben[ROWS][COLS], int x, int y);

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值