浅试扫雷游戏(简易版)

news2024/9/20 14:29:23

目录

1. 扫雷游戏分析和设计

1)扫雷游戏的功能说明

2)游戏的分析和设计

2.扫雷游戏的代码实现


1. 扫雷游戏分析和设计
1)扫雷游戏的功能说明
  • 使用控制台实现经典的扫雷游戏
  • 游戏可以通过菜单实现继续玩或者退出游戏
  • 扫雷的棋盘是9*9的格子
  • 默认随机布置10个雷
  • 可以排查雷
  • 如果位置不是雷,就显示周围有几个雷
  • 如果位置是雷,就炸死游戏结束
  • 把除10个雷之外的所有雷都找出来,排雷成功,游戏结束

游戏的界面:

2)游戏的分析和设计

<1>数据结构的分析

扫雷的过程中,布置的雷和排查出的雷的信息都需要存储,所以我们需要一定的数据结构来存储这些信息,因为我们需要在9*9的棋盘上布置雷的信息和排查雷,我们首先想到的就是创建一个 9*9 的数组来存放信息

 如果这个位置布置雷,我们就存放1,没有布置雷就存放0

排雷的假设

假设我们排查(2,5)这个坐标时,我们访问周围的一圈8个黄色位置,统计周围雷的个数是1
假设我们排查(8,6)这个坐标时,我们访问周围的一圈8个黄色位置,统计周围雷的个数时,最下面的三个坐标就会越界

周围加上一圈的棋盘(11*11)

为了防止越界,我们在设计的时候,给数组扩大一圈,雷还是布置在中间的9*9的坐标上,周围一圈不去布置雷就行,这样就解决了越界的问题。所以我们将存放数据的数组创建成11*11

 

我们在棋盘上布置了雷,棋盘上雷的信息(1)和非雷的信息(0),假设我们排查了某一个位置后,这个坐标处不是雷,这个坐标的周围有1个雷,那我们需要将排查出的雷的数量信息记录存储并打印出来,作为排雷的重要参考信息。

那这个雷的个数信息存放在哪里呢?如果存放在布置雷的数组中,这样雷的信息和雷的个数信息就可能或产生混淆和打印上的困难。这里我们肯定有办法解决,比如:雷和非雷的信息不要使用数字,使用某些字符就行,这样就避免冲突了,但是这样做棋盘上有雷和非雷的信息,还有排查出的雷的个数信息,就比较混杂,不够方便。这里我们采用另外一种方案,我们专门给一个棋盘(对应一个数组mine)存放布置好的雷的信息,再给另外一个棋盘(对应另外一个数组show)存放排查出的雷的信息。这样就互不干扰了,把雷布置到mine数组,在mine数组中排查雷,排查出的数据存放在show数组,并且打印show数组的信息给后期排查参考。
同时为了保持神秘,show数组开始时初始化为字符 '*',为了保持两个数组的类型一致,可以使用同一套函数处理,mine数组最开始也初始化为字符'0',布置雷改成'1'。如下如:

 

char mine[11][11] = {0};//用来存放布置好的雷的信息
char show[11][11] = {0};//用来存放排查出的雷的个数信息

 <2>文件结构设计

test.c //文件中写游戏的测试逻辑
game.c //文件中写游戏中函数的实现等
game.h //3 文件中写游戏需要的数据类型和函数声明等
2.扫雷游戏的代码实现
//game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define EASY_COUNT 10

#define ROW 9
#define COL 9

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

//初始化棋盘
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[ROWS][COLS], char show[ROWS][COLS], int row, int col);
//game.c
#include "game.h"
void InitBoard(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 DisplayBoard(char board[ROWS][COLS], int row, int col)
{
    int i = 0;
    printf("--------扫雷游戏-------\n");
    for (i = 0; i <= col; 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 SetMine(char board[ROWS][COLS], int row, int col)
{
    //布置10个雷
    //生成随机的坐标,布置雷
    int count = EASY_COUNT;
    while (count)
    {
        int x = rand() % row + 1;
        int y = rand() % col + 1;
        if (board[x][y] == '0')
        {
            board[x][y] = '1';
            count--;
        }
    }
}

int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
    return (mine[x-1][y]+mine[x-1][y-1]+mine[x][y - 1]+mine[x+1][y-1]+mine[x
                    mine[x+1][y+1]+mine[x][y+1]+mine[x-1][y+1] - 8 * '0');
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
    int x = 0;
    int y = 0;
    int win = 0;
    while (win <row*col- EASY_COUNT)
    {
        printf("请输入要排查的坐标:>");
        scanf("%d %d", &x, &y);
        if (x >= 1 && x <= row && y >= 1 && y <= col)
        {
            if (mine[x][y] == '1')
            {
                printf("很遗憾,你被炸死了\n");
                DisplayBoard(mine, ROW, COL);
                break;
            }
            else
            {
                //该位置不是雷,就统计这个坐标周围有几个雷
                int count = GetMineCount(mine, x, y);
                show[x][y] = count + '0';
                DisplayBoard(show, ROW, COL);
                win++;
            }
        }
        else
        {
            printf("坐标非法,重新输入\n");
        }
    }
    if (win == row * col - EASY_COUNT)
    {
        printf("恭喜你,排雷成功\n");
        DisplayBoard(mine, ROW, COL);
    }
}
//test.c
#include "game.h"
void menu()
{
    printf("***********************\n");
    printf("***** 1. play *****\n");
    printf("***** 0. exit *****\n");
    printf("***********************\n");
}

void game()
{
    char mine[ROWS][COLS];//存放布置好的雷
    char show[ROWS][COLS];//存放排查出的雷的信息
    //初始化棋盘
    //1. mine数组最开始是全'0'
    //2. show数组最开始是全'*'
    InitBoard(mine, ROWS, COLS, '0');
    InitBoard(show, ROWS, COLS, '*');
    //打印棋盘
    //DisplayBoard(mine, ROW, COL);
    DisplayBoard(show, ROW, COL);
    //1. 布置雷
    SetMine(mine, ROW, COL);
    //DisplayBoard(mine, ROW, COL);
    //2. 排查雷
    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("退出游戏\n");
        break;
    default:
        printf("选择错误,重新选择\n");
        break;
    }
    } while (input);
    return 0;
}

版本二:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define ROW 9
#define COL 9

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

#define mine 10;

void menu()
{
	printf("************************\n");
	printf("*******1.  开始  *******\n");
	printf("*******0.  退出  *******\n");
	printf("************************\n");
}

void Init(char arr[ROWS][COLS], int rows, int cols, char parten)
{
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			arr[i][j] = parten;
		}
	}
}

void Print(char arr[ROWS][COLS], int row, int col)
{
	for (int i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (int i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (int j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");
	}
}

void Set_mine(char arr[ROWS][COLS],int row,int col)
{
	int count = mine;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
			count--;
		}
	}
}

int Get_mine(char arr[ROWS][COLS], int x, int y)
{
	int n = 0;
	for (int i = x - 1; i <= x + 1; i++)
	{
		for (int j = y - 1; j <= y + 1; j++)
		{
			n += arr[i][j] - '0';
		}
	}
	return n+'0';
}

void Guess(char array_show[ROWS][COLS], char array_mine[ROWS][COLS])
{
	int x = 0;
	int y = 0;
	int count = ROW * COL- mine;
	while (count)
	{
		printf("请输入:");
		scanf("%d%d", &x, &y);
		while (!(x > 0 && x < 10) || !(y > 0 && y < 10))
		{
			printf("输入错误,请再次输入:");
			scanf("%d%d", &x, &y);
		}
		if (array_mine[x][y] == '1')
		{
			printf(" 拜拜!\n");
			Print(array_mine, ROW, COL);
			break;
		}
		else
		{
			array_show[x][y] = Get_mine(array_mine, x, y);
			Print(array_show, ROW, COL);
		}
		count--;
	}
	if (count == 0)
	{
		printf(" 恭喜!\n");
	}
}

void game()
{
	char array_show[ROWS][COLS];
	char array_mine[ROWS][COLS];
	Init(array_show, ROWS, COLS,'*');
	Init(array_mine, ROWS, COLS, '0');
	//Print(array_show, ROW, COL);
	//Print(array_mine, ROW, COL);
	Set_mine(array_mine, ROW, COL);
	//Print(array_mine, ROW, COL);
	Print(array_show, ROW, COL);
	Guess(array_show, array_mine);
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请输入:");
		scanf("%d", &input);
		while (input != 0 && input != 1)
		{
			printf("输入错误,请再次输入:");
			scanf("%d", &input);
		}
		if (input)
		{
			game();
		}
		else
		{
			printf("退出游戏!");
		}
	} while (input);
	return 0;
}

谢谢观看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2037733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

“前缀和”专题篇二

目录 和为K的子数组 和可被K整除的子数组 连续数组 矩阵区域和 和为K的子数组 题目 思路 我们可能想到的是&#xff0c;从头到尾扫描数组&#xff0c;然后分别计算以该位置为开始&#xff0c;一直到数组末尾&#xff0c;符合和为K的子数组&#xff0c;但是这种方法的时间复…

线上研讨会 | CATIA助力AI提升汽车造型设计

报名链接&#xff1a; 2024探索之旅第二季

Linux Shell基础常用脚本命令及应用案例

文章目录 常用的 Shell 命令1. 变量2. 注释3. 输出4. 输入5. 条件判断6. 循环7. 函数8. 运算9. 流程控制10. 文件和目录操作11. 错误处理 Shell 脚本应用案例1. Hello World 脚本2. 创建系统账户及设置密码3. 日志文件备份4. 一键部署 LNMP 环境5. 检查磁盘空间6. 自动安装软件…

Nginx反向代理的使用场景

Nginx Vue使用npm命令打包&#xff1a;npm run build Nginx的定位&#xff1a;主要用于做反向代理&#xff0c;一般都是用它来做前端页面的服务器&#xff0c;动态资源代理到后端服务器。这样做的好处是可以避免跨域请求带来的不便。 我们知道&#xff0c;在前端我们开发的时…

三、AI工作流(低代码)的趋势即将崛起,输入-按钮组件详解,带你轻松玩转按钮组件

对工作流感兴趣的小伙伴可以去试一试。&#x1f525;偷偷的告诉你&#xff0c;它的GPTo4.0 不要&#x1f4b0;。传送门&#xff1a;https://www.nyai.chat/chat?invitenyai_1141439 一、能用AI工作流介绍 能用AI-工作流是一个“低代码”工具、它也是个人或者中小企业的提效工…

C#语言基础速成Day07

“知止而后有定&#xff0c;定而后能静&#xff0c;静而后能安&#xff0c;安而后能虑&#xff0c;虑而后能得。” 目录 前言文章有误敬请斧正 不胜感恩&#xff01;||Day07 C#常见数据结构&#xff1a;1. 集合&#xff08;Collection&#xff09;1.1 **List<T>**1.2 **H…

MATLAB 样条插值

订阅专栏后,复制完整代码到MATLAB上面,即可获得跟本文相同的运行结果。 点击以下链接也可下载: https://download.csdn.net/download/callmeup/89635701 MATLAB插值代码 插值在MATLAB里面很简单,一个函数即可。 本文给出了已知点的坐标、待插值点的横坐标,可按要求插出来…

使用 Gradio 开发 ChatBot

Gradio 提供了 ChatInterface 组件&#xff0c;组件包括一个输入框、一个 ChatBox 区域、和一些按钮。同 interface&#xff0c;ChatInterface 通过一个处理函数进行处理&#xff0c;处理函数包括两个参数 message 和 history&#xff0c;message 是当前用户提交的问题&#xf…

[图解]需要≠需求-《分析模式》漫谈

1 00:00:00,760 --> 00:00:02,910 今天的《分析模式》漫谈 2 00:00:02,920 --> 00:00:04,180 我们来说一下 3 00:00:04,490 --> 00:00:06,490 需要不等于需求 4 00:00:10,490 --> 00:00:11,760 还是第一章 5 00:00:13,120 --> 00:00:15,020 这里 6 00:00:1…

[C#]实现GRPC通讯的服务端和客户端实例

最近要做两个软件之间消息的通讯&#xff0c;学习了一下GRPC框架的通讯。根据官方资料做了一个实例。 官方资料请参考&#xff1a;Create a .NET Core gRPC client and server in ASP.NET Core | Microsoft Learn 开发平台&#xff1a;Visual Studio 2022 开发前提条件&#x…

llama的神经网络结构;llama的神经网络结构中没有MLP吗;nanogpt的神经网络结构;残差是什么;残差连接:主要梯度消失

目录 解释代码 潜在问题和修正 结论 llama的神经网络结构 神经网络结构概述 举例说明 llama的神经网络结构中没有MLP吗 nanogpt的神经网络结构 1. 词嵌入层(Embedding Layer) 2. Transformer编码器层(Transformer Encoder Layer) 3. 层归一化(Layer Normalizat…

Linux文本处理常见工具

文章目录 文件内容查看查看文本文件内容cattacrevnl 查看非文本文件内容hexdumpodxxd 分页查看文件内容moreless 显示文本前后的行内容headtail文件描述符如果找到文件描述符 查看最新日志范例&#xff1a;找出IP地址的那一行 cut--按列抽取文本按分隔符按字符位置取网卡ip tr-…

Rocky系统部署k8s1.28.2单节点集群(Containerd)+Kuboard

目录 Kubernetes介绍 Kubernetes具备的功能 Kubernetes集群角色 Master管理节点组件 Node工作节点组件 非必须的集群插件 Kubernetes集群类型 Kubernetes集群规划 集群前期环境准备 开启Bridge网桥过滤 关闭SWAP交换分区 安装Containerd软件包 K8s集群部署方式 集…

关于归并排序:

![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_urlhttps%3A%2F return 语句开始之后&#xff0c;会执行之前剩余遗留下的语句和状态#include<bits/stdc.h> using namespace std…

Xilinx XAPP585相关

XAPP585中相关的状态机 第一个状态机&#xff1a;这里主要是在对时钟线延迟的基础上&#xff0c;通过BITSLIP操作&#xff0c;做时钟的对齐&#xff1b; 第二个状态机&#xff1a;这里对c_delay_in所做的操作&#xff0c;主要是对时钟线的延迟进行控制&#xff1b; delay_con…

远程代码执行漏洞

1.简介 远程代码执行(remote code execution)简称RCE&#xff0c;由于应用程序在调用一些能够将字符串转换为代码的函数(如PHP中的eval)时&#xff0c;没有考虑用户是否控制这个字符串&#xff0c;则会导致代码执行漏洞的发生Webshell能够执行代码&#xff0c;本质上就是利用了…

新AI工程师Genie强势来袭,84秒解决代码问题

&#x1f989; AI新闻 &#x1f680; 新AI工程师Genie强势来袭&#xff0c;84秒解决代码问题 摘要&#xff1a;新兴AI软件工程师Genie因其超凡能力而引发关注&#xff0c;它在SWE-Bench排行榜上以30.07%的问题解决率远超第二名。Genie能模拟人类工程师的思维&#xff0c;自动…

CV党福音:YOLOv8实现语义分割(一)

前面我们得知YOLOv8不但可以实现目标检测任务&#xff0c;还包揽了分类、分割、姿态估计等计算机视觉任务。在上一篇博文中&#xff0c;博主已经介绍了YOLOv8如何实现分类&#xff0c;在这篇博文里&#xff0c;博主将介绍其如何将语义分割给收入囊中。 YOLOv8语义分割架构图 …

LeetCode - 54 - 螺旋矩阵

力扣54题 题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 题解思路&#xff1a; 54题和59题 螺旋矩阵Ⅱ 有些微区别&#xff0c;59是nn的方形矩阵&#xff0c;但是54需要考虑行和列不相等的情况…

Webpack中搭建本地服务dev-server

开发过程中关于实现文件内容发生变化时&#xff0c;可监听文件变化内容、自动完成编译热更新&#xff0c;webpack提供了几种可选方式&#xff1a; 1. webpack watch mode监听文件变化 watch可在导出配置中添加或者在webpack 启动命令中添加--watch 注意&#xff1a;watch 的配…