当前位置: 首页 > article >正文

C语言-----扫雷游戏

扫雷游戏的功能说明

• 使⽤控制台实现经典的扫雷游戏
• 游戏可以通过菜单实现继续玩或者退出游戏
• 扫雷的棋盘是9*9的格⼦
• 默认随机布置10个雷
• 可以排查雷:
◦ 如果位置不是雷,就显⽰周围有⼏个雷
◦ 如果位置是雷,就炸死游戏结束
◦ 把除10个雷之外的所有⾮雷都找出来,排雷成功,游戏结束

test.c //⽂件中写游戏的测试逻辑
game.c //⽂件中写游戏中函数的实现等
game.h //⽂件中写游戏需要的数据类型和函数声明等

逻辑开始:

一、菜单

  1. 输入1进入游戏,输入0退出游戏,输入其他数字显示输入错误,并且重新输入
test.c
#include "game.h"

int main()
{
	menu();
	{
	regain:
		printf("请输入你的选择:");
		int input1;
		scanf("%d", &input1);
		switch (input1)
		{
		case 1:
		{
			printf("进入游戏\n");
			game();
			break;
		}
		case 0:
		{
			printf("退出游戏\n");
			break;

		}
		default:
		{
			printf("输入错误,请重新输入:");
			goto regain;
		}
		}
	}
	return 0;
}
game.c
#include "game.h"

void menu()
{
	printf("****************\n");
	printf("**** 1.Play ****\n");
	printf("**** 0.Quit ****\n");
	printf("****************\n");

}
game.h
#pragma once
#include <stdio.h>
#include "game.h"

//菜单
void menu();

二、生成 9X9 的游戏界面

  1. 使用二维数组实现
  2. 运用两个棋盘,一个用于展示,一个用于设置雷,写出初始化棋盘的函数
  3. 将展示的棋盘char show全部初始化为 '*',将布置雷的棋盘char mine全部初始化为0
  4. 为方便后边测试,可以先把打印棋盘的函数写出

test.c文件增加了以下代码

test.c
#include "game.h"

void game()
{
	//用于布置雷的二维数组
	char mine[ROWS][COLS] = { 0 };

	//用于游戏界面的的二维数组
	char show[ROWS][COLS] = { 0 };

	//用于游戏界面的的二维数组全部初始为 '*'
	set_keyboard(show, ROWS, COLS, '*');

	//用于布置雷的二维数组全部初始化为 '0'
	set_keyboard(mine, ROWS, COLS, '0');

	//打印函数
	printf_keyboard(show, ROW, COL);
	printf_keyboard(mine, ROW, COL);
}

game.c文件增加了以下代码

game.c
#include "game.h"

//初始化棋盘
void set_keyboard(char board[ROWS][COLS], int rows, int cols, char set)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

//展示棋盘
void printf_keyboard(char board[ROWS][COLS], int row, int col)
{
	printf("-------扫雷--------\n");
	for (int r = 0; r <= row; r++)
	{
		printf("%d ", r);
	}

	printf("\n");

	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

game.c文件增加了以下代码

#pragma once
#include <stdio.h>
#include "game.h"

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


//菜单
void menu();

//初始化棋盘
void set_keyboard(char board[ROWS][COLS], int rows, int cols, char set);

//展示棋盘
void printf_keyboard(char board[ROWS][COLS], int row, int col);


三、随机布置雷

  1. 使用srand((unsigned int) time(NULL))rand()
  2. 将雷设置为1,雷只能布置在char mine[x][y] == '0'的地方

game.h文件增加了
#include <time.h>
#include "stdlib.h"
#define MINE 10
void set_mine(char board[ROWS][COLS], int row, int col, int mine);

game.h

#pragma once
#include <stdio.h>
#include "game.h"
#include <time.h> 
#include "stdlib.h"

#define ROW 9
#define COL 9
#define ROWS ROW+3
#define COLS COL+2
#define MINE 10


//菜单
void menu();

//初始化棋盘
void set_keyboard(char board[ROWS][COLS], int rows, int cols, char set);

//展示棋盘
void printf_keyboard(char board[ROWS][COLS], int row, int col);

//随机布置雷
void set_mine(char board[ROWS][COLS], int row, int col, int mine);

game.c文件增加以下代码
game.c

//随机布置雷
void set_mine(char board[ROWS][COLS], int row, int col, int mine)
{
	srand((unsigned int) time(NULL));

	while (mine)
	{
		int x = (rand() % row) + 1;
		int y = (rand() % col) + 1;
		if (board[x][y] == '0');
		{
			board[x][y] = '1';
			mine--;
		}
	}

}

test.c文件增加以下代码

test.c

//随机布置雷
set_mine(mine, ROW, COL, MINE);

四、排雷

  1. 注意输入的坐标,横纵坐标都只能是0~9,出现其他数字报错,并重新输入
  2. 所排的坐标要显示周围雷的个数,如果为0,展开周围的棋盘(运用到递归)
  3. 如果所排的坐标是雷,显示游戏结束
  4. 如果输入的坐标是已经输入过的坐标,显示该坐标已经排除
  5. 判断游戏胜利,排除的坐标个数与减掉雷后的格子数相等

test.c文件布局改为以下情况

test.c
void game()
{
	//用于布置雷的二维数组
	char mine[ROWS][COLS] = { 0 };

	//用于游戏界面的的二维数组
	char show[ROWS][COLS] = { 0 };

	//用于游戏界面的的二维数组全部初始为 '*'
	set_keyboard(show, ROWS, COLS, '*');

	//用于布置雷的二维数组全部初始化为 '0'
	set_keyboard(mine, ROWS, COLS, '0');

	//随机布置雷
	set_mine(mine, ROW, COL, MINE);

	//打印函数
	printf_keyboard(show, ROW, COL);
	//printf_keyboard(mine, ROW, COL);
	
	//排雷
	move_mine(show, mine, ROW, COL);
}

game.c文件增加了以下代码

game.c
//计算周围雷的个数
int Count_mine(char mine[ROWS][COLS], int x, int y)
{
	return mine[x][y] - '0';
}

//展开棋盘----递归
void Open_keyboard(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{
	//写递归首先写结束条件

	//越界时,返回
	if ((x > (ROWS - 2)) || (x < 1) || (y > (COLS - 2)) || (y < 1))
	{
		return;
	}

	//遇到以及排过雷的坐标返回
	if (show[x][y] != '*')
	{
		return;
	}

	//计算雷的个数
	int count = 0;
	for (int i = -1; i <= 1; i++)
	{
		for (int j = -1; j <= 1; j++)
		{
			count += Count_mine(mine, x + i, y + j);
		}
	}
	show[x][y] = count + '0';
	
	//按照游戏规则,如果坐标显示雷的数目不为零,则返回
	if (show[x][y] != '0')
	{
		return;
	}

	//展开雷
	for (int i = -1; i <= 1; i++)
	{
		for (int j = -1; j <= 1; j++)
		{
			Open_keyboard(show, mine, x + i, y + j);
		}
	}

}

//排雷
void move_mine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
	int x, y;
	while (1)
	{
		printf("请输入要排查的坐标:");
	regain2:
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= 9) && (y >= 1 && y <= 9))
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '0')
				{
					Open_keyboard(show,mine,x,y);
					printf_keyboard(show, ROW, COL);
				}
				else
				{
					printf("很遗憾,踩到雷了,游戏结束\n以下是雷的位置:");
					printf_keyboard(mine, ROW, COL);
					break;
				}
			}
			else
			{
				printf("该坐标已经排查过了,请输入别的坐标:");
				goto regain2;
			}
		}
		else
		{
			printf("输入错误,重新输入:");
			goto regain2;
		}

		//判断赢
		int Remove_mine_count = 0;
		for (int i = 1; i <= row; i++)
		{
			for (int j = 1; j <= col; j++)
			{
				if (show[i][j] != '*')
				{
					Remove_mine_count++;
				}
			}
		}
		if (Remove_mine_count == ((ROW * COL) - MINE))
		{
			printf("恭喜你,排除所有的雷,游戏胜利\n");
			printf_keyboard(mine, ROW, COL);
			break;
		}
	}
}

game.h文件的代码不变

game.h
#pragma once
#include <stdio.h>
#include "game.h"
#include <time.h> 
#include "stdlib.h"

#define ROW 9
#define COL 9
#define ROWS ROW+3
#define COLS COL+2
#define MINE 10


//菜单
void menu();

//初始化棋盘
void set_keyboard(char board[ROWS][COLS], int rows, int cols, char set);

//展示棋盘
void printf_keyboard(char board[ROWS][COLS], int row, int col);

//随机布置雷
void set_mine(char board[ROWS][COLS], int row, int col, int mine);

//排雷
void move_mine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col);

五、扫雷游戏完整代码

test.c

#include "game.h"

void game()
{
	//用于布置雷的二维数组
	char mine[ROWS][COLS] = { 0 };

	//用于游戏界面的的二维数组
	char show[ROWS][COLS] = { 0 };

	//用于游戏界面的的二维数组全部初始为 '*'
	set_keyboard(show, ROWS, COLS, '*');

	//用于布置雷的二维数组全部初始化为 '0'
	set_keyboard(mine, ROWS, COLS, '0');

	//随机布置雷
	set_mine(mine, ROW, COL, MINE);

	//打印函数
	printf_keyboard(show, ROW, COL);
	//printf_keyboard(mine, ROW, COL);
	
	//排雷
	move_mine(show, mine, ROW, COL);
}

int main()
{
	menu();
	{
	regain1:
		printf("请输入你的选择:");
		int input1;
		scanf("%d", &input1);
		switch (input1)
		{
		case 1:
		{
			printf("进入游戏\n");
			game();
			break;
		}
		case 0:
		{
			printf("退出游戏\n");
			break;

		}
		default:
		{
			printf("输入错误,请重新输入:");
			goto regain1;
		}
		}
	}
	return 0;
}

game.c

#include "game.h"

//界面
void menu()
{
	printf("****************\n");
	printf("**** 1.Play ****\n");
	printf("**** 0.Quit ****\n");
	printf("****************\n");

}

//初始化棋盘
void set_keyboard(char board[ROWS][COLS], int rows, int cols, char set)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

//展示棋盘
void printf_keyboard(char board[ROWS][COLS], int row, int col)
{
	printf("-------扫雷--------\n");
	for (int r = 0; r <= row; r++)
	{
		printf("%d ", r);
	}

	printf("\n");

	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

//随机布置雷
void set_mine(char board[ROWS][COLS], int row, int col, int mine)
{
	srand((unsigned int) time(NULL));

	while (mine)
	{
		int x = (rand() % row) + 1;
		int y = (rand() % col) + 1;
		if (board[x][y] == '0');
		{
			board[x][y] = '1';
			mine--;
		}
	}
}

//计算周围雷的个数
int Count_mine(char mine[ROWS][COLS], int x, int y)
{
	return mine[x][y] - '0';
}

//展开棋盘----递归
void Open_keyboard(char show[ROWS][COLS], char mine[ROWS][COLS], int x, int y)
{
	//写递归首先写结束条件

	//越界时,返回
	if ((x > (ROWS - 2)) || (x < 1) || (y > (COLS - 2)) || (y < 1))
	{
		return;
	}

	//遇到以及排过雷的坐标返回
	if (show[x][y] != '*')
	{
		return;
	}

	//计算雷的个数
	int count = 0;
	for (int i = -1; i <= 1; i++)
	{
		for (int j = -1; j <= 1; j++)
		{
			count += Count_mine(mine, x + i, y + j);
		}
	}
	show[x][y] = count + '0';

	//按照游戏规则,如果坐标显示雷的数目不为零,则返回
	if (show[x][y] != '0')
	{
		return;
	}

	//展开雷
	for (int i = -1; i <= 1; i++)
	{
		for (int j = -1; j <= 1; j++)
		{
			Open_keyboard(show, mine, x + i, y + j);
		}
	}

}

//排雷
void move_mine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col)
{
	int x, y;
	while (1)
	{
		printf("请输入要排查的坐标:");
	regain2:
		scanf("%d %d", &x, &y);
		if ((x >= 1 && x <= 9) && (y >= 1 && y <= 9))
		{
			if (show[x][y] == '*')
			{
				if (mine[x][y] == '0')
				{
					Open_keyboard(show,mine,x,y);
					printf_keyboard(show, ROW, COL);
				}
				else
				{
					printf("很遗憾,踩到雷了,游戏结束\n以下是雷的位置:");
					printf_keyboard(mine, ROW, COL);
					break;
				}
			}
			else
			{
				printf("该坐标已经排查过了,请输入别的坐标:");
				goto regain2;
			}
		}
		else
		{
			printf("输入错误,重新输入:");
			goto regain2;
		}

		//判断赢
		int Remove_mine_count = 0;
		for (int i = 1; i <= row; i++)
		{
			for (int j = 1; j <= col; j++)
			{
				if (show[i][j] != '*')
				{
					Remove_mine_count++;
				}
			}
		}
		if (Remove_mine_count == ((ROW * COL) - MINE))
		{
			printf("恭喜你,排除所有的雷,游戏胜利\n");
			printf_keyboard(mine, ROW, COL);
			break;
		}
	}
}

game.h

#pragma once
#include <stdio.h>
#include "game.h"
#include <time.h> 
#include "stdlib.h"

#define ROW 9
#define COL 9
#define ROWS ROW+3
#define COLS COL+2
#define MINE 10


//菜单
void menu();

//初始化棋盘
void set_keyboard(char board[ROWS][COLS], int rows, int cols, char set);

//展示棋盘
void printf_keyboard(char board[ROWS][COLS], int row, int col);

//随机布置雷
void set_mine(char board[ROWS][COLS], int row, int col, int mine);

//排雷
void move_mine(char show[ROWS][COLS], char mine[ROWS][COLS], int row, int col);

http://www.kler.cn/a/517234.html

相关文章:

  • 数据结构:二叉树—面试题(一)
  • Qt——引用第三方SDK lib库的使用方法
  • 国产低功耗带LCD驱动和触摸按键功能的MCU
  • pytest自动化测试 - pytest夹具的基本概念
  • 考研机试题:打印数字菱形
  • springboot 配置redis
  • 一款专业通用开源的MES生产执行管理系统
  • Unity常用特性(Attribute)用法
  • 睡眠时间影响因素K-Means可视化分析+XGBoost预测
  • 第15个项目:一个有趣的豆瓣电影TOP爬虫
  • ISIS基础知识
  • 2024-2025自动驾驶技术演进与产业破局的深度实践——一名自动驾驶算法工程师的年度技术总结与行业洞察
  • 基于SpringBoot+Vue的智慧动物园管理系统的设计与实现
  • 智能运维分析决策系统:赋能数字化转型的智慧引擎
  • qt 设置鼠标样式的几种方法
  • ceph新增节点,OSD设备,标签管理(二)
  • 付费会员制与开源AI智能名片S2B2C商城小程序在现代营销中的应用
  • 八股学习 微服务篇
  • 【Ubuntu】使用远程桌面协议(RDP)在Windows上远程连接Ubuntu
  • AI Agent的记忆系统实现:从短期对话到长期知识
  • React Native 0.77发布,新样式特性,Android 16KB页面支持,Swift模板
  • Vue 使用moment格式化时间
  • Meta的AIGC视频生成模型——Emu Video
  • 联想电脑怎么设置u盘启动_联想电脑设置u盘启动方法(支持新旧机型)
  • ansible自动化运维实战--script、unarchive和shell模块(6)
  • LeetCode 热题 100_实现 Trie (前缀树)(54_208_中等_C++)(图;前缀树;字典树)