您现在的位置是:首页 >技术教程 >C语言(扫雷)网站首页技术教程

C语言(扫雷)

汴京城下君 2024-07-24 00:01:01
简介C语言(扫雷)


在这里插入图片描述

开发过程

  • 准备工作
  • 效果展示

准备工作:
在这里插入图片描述
game.h 一个头文件–>声明函数
test.c 为主文件
game.c 为功能函数实现文件

效果展示
在这里插入图片描述
在这里插入图片描述

开发思路

  • 菜单界面

  • 游戏界面打印(二维数组)

  • 雷的随机产生

  • 排雷(以及判断周围的雷数)

  • 胜利条件

大致思路就是这样,接下来我们一步步去分析

菜单界面

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

这里我们要不断的去 接收用户的输入,当为1时,进入游戏,为0时,退出程序
直接就想到了 条件语句判断,这里我们用switch

不断的:用户完成游戏后,可以再次打印菜单供用户选择

这个操作当然是项目的核心部分了,放在 main()函数

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("退出游戏");
			break;
		default:
			printf("输入有误!!!");
			break;
		}
	} while (input);

	return 0;
}

游戏界面的打印

这里当然是用二维数组,但是我们要去考虑,如果就一个数组的话,能否起到不知情排雷的效果。
当然,一个数组是不可能的,所以我们要建立两个数组
一个是真实的,一个是展示给用户看的

	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出雷的信息

在这里我们要先去考虑一下,该数组若是9×9,在边缘时去判断周围的雷数会越界
我们可以通过建立11×11的数组,其中最外围我们不用,只是设置为默认值

#define ROW 9
#define COL 9

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

对地图的初始化

	//mine 数组在没有布置雷的时候全为 0
	InitBoard(mine, ROWS, COLS, '0');
	//show 数组在没有排查雷的时候全为 *
	InitBoard(show, ROWS, COLS, '*');

我们的InitBoard函数为:

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

对地图的打印

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0, j = 0;
	printf("-----------扫雷游戏--------------
");
	//打印上面0~9注释
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	
	printf("
");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i); //打印竖着1~9的注释
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("
");
	}
	printf("-----------扫雷游戏--------------
");
}

雷的随机产生

我们很容易想到,就是产生随机数,对其数组进行更改元素值。
这就用到了 srand()函数

	//设置随机数的起始
	srand((unsigned int)time(NULL));

随机产生的函数:

我们定义EASY_COUNT(雷的数量)在头文件中

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	//横纵坐标1~9
	while (count)
	{
		int d = rand() % row + 1;
		int c = rand() % col + 1;

		//随机生成十个雷,雷:1
		if (board[d][c] == '0')
		{
			board[d][c] = '1';
			count--;
		}
	}
}

扫雷以及判断胜利条件

扫雷
让用户输入一个坐标,对其值进行判断

  • 若在 show数组内该坐标为*,则该坐标已经被排雷
  • 若在mine数组内该坐标为1则被雷炸失败
  • 否则对其周围进行判断在mine数组内有几颗雷并在show数组的该坐标上显示其数量

判断是否重复输入坐标

			if (show[x][y] != '*')
			{
				printf("该坐标已经排查过了,请重新输入:>
");
			}

失败的代码很简单,一个判断就行了

				if (mine[x][y] == '1')	//是雷
				{
					printf("被炸死咯
");
					DisplayBoard(mine, ROW, COL);
					break;
				}

判断周围有几颗雷的函数为
在这里插入图片描述

int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y] +
		board[x - 1][y - 1] +
		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');
}

整个操作的函数为

void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	int a = 0, b = 0;
	int win = 0;
	while (win<row*col-EASY_COUNT)//判断胜利条件,win小于整体-雷数
	{
		printf("请输入排查的坐标:>
");
		scanf("%d %d", &a, &b);
		x = a + 1;
		y = b + 1;

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] != '*')
			{
				printf("该坐标已经排查过了,请重新输入:>
");
			}
			else
			{
				if (mine[x][y] == '1')	//是雷
				{
					printf("被炸死咯
");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else //不是雷         '0'-'0'=0     '1'-'0'=1  字符->整型   
								// ASCII码值分别为 '1':49     '0':48
				{
					int count = get_mine_count(mine, x, y);//统计该坐标周围有几颗雷
					show[x][y] = count + '0';//转换成数字字符
					//printf("%c
", count + '0');
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
		}
		else
		{
			printf("输入坐标错误,请重新输入:>
");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,扫雷成功!!!
");
		DisplayBoard(mine, ROW, COL);
	}
}

代码整合

test.c

#include "game.h"

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

void game()
{
	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出雷的信息
	//初始化数组的内容为指定内容
	//mine 数组在没有布置雷的时候全为 0
	InitBoard(mine, ROWS, COLS, '0');
	//show 数组在没有排查雷的时候全为 *
	InitBoard(show, ROWS, COLS, '*');

	//DisplayBoard(mine,ROW, COL);
	//设置雷
	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("退出游戏");
			break;
		default:
			printf("输入有误!!!");
			break;
		}
	} while (input);

	return 0;
}

game.c

#include "game.h"

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

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0, j = 0;
	printf("-----------扫雷游戏--------------
");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("
");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("
");
	}
	printf("-----------扫雷游戏--------------
");
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;
	//横纵坐标1~9
	while (count)
	{
		int d = rand() % row + 1;
		int c = rand() % col + 1;

		//随机生成十个雷,雷:1
		if (board[d][c] == '0')
		{
			board[d][c] = '1';
			count--;
		}
	}
}

int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y] +
		board[x - 1][y - 1] +
		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');
}


void FindMine(char mine[ROW][COL], char show[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	int a = 0, b = 0;
	int win = 0;
	while (win<row*col-EASY_COUNT)//判断胜利条件,win小于整体-雷数
	{
		printf("请输入排查的坐标:>
");
		scanf("%d %d", &a, &b);
		x = a + 1;
		y = b + 1;

		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (show[x][y] != '*')
			{
				printf("该坐标已经排查过了,请重新输入:>
");
			}
			else
			{
				if (mine[x][y] == '1')	//是雷
				{
					printf("被炸死咯
");
					DisplayBoard(mine, ROW, COL);
					break;
				}
				else //不是雷         '0'-'0'=0     '1'-'0'=1  字符->整型   
								// ASCII码值分别为 '1':49     '0':48
				{
					int count = get_mine_count(mine, x, y);//统计该坐标周围有几颗雷
					show[x][y] = count + '0';//转换成数字字符
					//printf("%c
", count + '0');
					DisplayBoard(show, ROW, COL);
					win++;
				}
			}
		}
		else
		{
			printf("输入坐标错误,请重新输入:>
");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,扫雷成功!!!
");
		DisplayBoard(mine, ROW, COL);
	}
}

game.h

#pragma once
#include <stdio.h>
#include <time.h>
#include <stdlib.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[ROW][COL],char show[ROW][COL], int row, int col);
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。