扫雷游戏(有讲解)

news2024/9/22 15:39:20

                                      

      ✨欢迎来到脑子不好的小菜鸟的文章✨

      🎈创作不易,麻烦点点赞哦🎈

          所属专栏:游戏    

          我的主页:脑子不好的小菜鸟

 引言: 

1.数组

2.随机数的生成,我在这篇文章里面详细讲述过:猜数字游戏(C语言实现)-CSDN博客

3.知道棋盘的设置:假如棋盘中1表示雷,0表示没有雷,如果扫雷时扫到的地方没有雷,则在显示的棋盘上对应的位置显示周围的八个位置中有多少雷,那么,这里就出现了问题:有1的时候是有雷呢,还是附近有一个雷?所以,在这里,我们要设置两个棋盘,一个是mine棋盘存放雷的信息),另一个是show棋盘展示给玩家的部分

思路:

1.菜单供玩家选择

2.实现主题函数部分:

(1)初始化棋盘

(2)布置雷

(3)玩家扫雷

实现:

首先,我们要将函数分为三个部分:

1.game.h(函数的声明部分)

2.game.c(函数的重要实现部分

3.test.c(函数的测试部分

1.菜单

和猜数字一样,在开头,要生成菜单和供玩家选择的部分,具体实现就参考猜数字文章了啦

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


int main()
{
	int input;
	srand((unsigned int)time(NULL));

	do
	{	
		caidan();
		printf("请输入>:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				printf("开始游戏\n");
				sao_lei();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("选择错误\n");
				break;
		}
		
	} while (input);

	return 0;
}

2.初始化棋盘

(1)mine棋盘:

没雷设置为0,有雷设置为1,由于一开始还没有布置雷,所以全设置为0

(2)show棋盘:

若该位置被排查过且不是雷,则显示周围雷的个数,但是一开始没有开始排查,所以全设置为*

由于*为字符,为了简化代码和模板化,需要将初始化部分写为一个函数,所以将mine数组设置为char类型的数组方便操作

test.c:

void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');
}

game.c:

void InitBorad(char borad[ROWS][COLS], int rows, int cols, char tuan)
{
	int i = 0, j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			borad[i][j] = tuan;
		}
	}
}

若不明白COL,ROW,COLS,ROWS的意义,请根据目录转到:总代码----game.h部分

效果:

3.布置雷:

test.c:

void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);
}

game.c:

void SetBorad(char borad[ROWS][COLS], int row, int col)
{
	int x;
	int y;
	int count = COUNT;

	while(count)
	{
		x = rand() % row + 1;//设置生成雷的部分在坐标为1~行数-1的范围内
		y = rand() % row + 1;

		if (borad[x][y] == '0')//如果这个地方没有设置雷,则布置mine棋盘这里是雷
		{
			borad[x][y] = '1';
			count--;
		}
	}

}

若不明白COUNT的意义,请根据目录转到:总代码----game.h部分

效果:

上面为mine棋盘,下面为show棋盘

4.打印棋盘:

test.c:

void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);

	//打印棋盘
	print_qi_pan(mine, ROW, COL);
	print_qi_pan(show, ROW, COL);
}

game.c:

void print_qi_pan(char borad[ROWS][COLS],int row,int col)
{
	int i = 0, j = 0;
	printf("--------扫雷游戏--------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	/**/

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ",borad[i][j]);
		}
		printf("\n");
	}
	printf("--------扫雷游戏--------\n");

}

5.找雷:

要获取玩家排查坐标,所以要玩家输入坐标x,y,因为需要在展示的棋盘内排查,所以若输入坐标超出棋盘,则需要重新输入,这需要循环来完成,所以有以下代码:

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

如果是雷,则显示:“很遗憾,你被炸死了”,并将mine棋盘打印给玩家,跳出循环:

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

如果排查的地方不是雷,则在show棋盘上显示周围雷的个数(要运用排查雷的函数: Get_My_Borad):

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//棋盘中不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);//检查周围坐标并算出雷的个数
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';//周围雷的个数
				count--;//没有排查的坐标减一
				print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

 Get_My_Borad:

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

如果不是没有被排查且不是雷的位置个数=不是雷的位置总个数,则打印:”恭喜你,排雷成功“,并打印mine棋盘,再退出循环

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//棋盘中不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);//检查周围坐标并算出雷的个数
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';//周围雷的个数
				count--;//没有排查的坐标减一
				if(count==0)
				{
					printf("恭喜排雷成功\n");
					print_qi_pan(mine, col, row);
					break;
				}
				else
					print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

test.c:

void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);

	//打印棋盘
	print_qi_pan(mine, ROW, COL);
	print_qi_pan(show, ROW, COL);

	//扫雷
	Findlei(mine,show, ROW, COL);

}

game.c:

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

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';
				count--;
				if(count==0)
				{
					printf("恭喜排雷成功\n");
					print_qi_pan(mine, col, row);
					break;
				}
				else
					print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

总代码:

 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 COUNT 10//雷的个数

//以下均为函数声明部分
void sao_lei();
void InitBorad(char borad[ROWS][COLS], int rows, int cols, char tuan);
void print_qi_pan(char borad[ROWS][COLS], int row, int col);
void SetBorad(char borad[ROWS][COLS], int row, int col);
void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
int Get_My_Borad(char mine[ROWS][COLS], int x, int y);

game.c: 

#define _CRT_SECURE_NO_WARNINGS 1
#include "sao_lei_you_xi.h"
//重要部分实现

void InitBorad(char borad[ROWS][COLS], int rows, int cols, char tuan)
{
	int i = 0, j = 0;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			borad[i][j] = tuan;
		}
	}
}

void print_qi_pan(char borad[ROWS][COLS],int row,int col)
{
	int i = 0, j = 0;
	printf("--------扫雷游戏--------\n");
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	printf("\n");
	/**/

	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		for (j = 1; j <= col; j++)
		{
			printf("%c ",borad[i][j]);
		}
		printf("\n");
	}
	printf("--------扫雷游戏--------\n");

}




void SetBorad(char borad[ROWS][COLS], int row, int col)
{
	int x;
	int y;
	int count = COUNT;

	while(count)
	{
		x = rand() % row + 1;
		y = rand() % row + 1;

		if (borad[x][y] == '0')
		{
			borad[x][y] = '1';
			count--;
		}
	}

}

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

void Findlei(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x, y;
	int count = row*col-COUNT;//棋盘中不是雷的个数
	while (1)
	{
		printf("请输入你的坐标:\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y <= col && y >= 1)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				print_qi_pan(mine, ROW, COL);
				break;
			}
			else
			{
				int num= Get_My_Borad(mine, x, y);//检查周围坐标并算出雷的个数
				//printf("%c\n", num+'0');
				show[x][y] = num+'0';//周围雷的个数
				count--;//没有排查的坐标减一
				if(count==0)
				{
					printf("恭喜排雷成功\n");
					print_qi_pan(mine, col, row);
					break;
				}
				else
					print_qi_pan(show, col, row);
			}

		}
		else
		{
			printf("选择错误,请重新选择:\n");
		}
	}
}

test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include "sao_lei_you_xi.h"
//可展示函数

//显示菜单
void caidan()
{
	printf("************************\n");
	printf("*****  1.开始游戏  *****\n");
	printf("*****  0.退出游戏  *****\n");
	printf("************************\n");
}

void sao_lei()
{
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };

	//初始化棋盘
	InitBorad(mine, ROWS, COLS, '0');
	InitBorad(show, ROWS, COLS, '*');

	//设置雷
	SetBorad(mine, ROW, COL);

	//打印棋盘
	print_qi_pan(mine, ROW, COL);
	print_qi_pan(show, ROW, COL);

	//扫雷
	Findlei(mine,show, ROW, COL);

}

int main()
{
	int input;
	srand((unsigned int)time(NULL));

	do
	{	
		caidan();
		printf("请输入>:");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				printf("开始游戏\n");
				sao_lei();
				break;
			case 0:
				printf("退出游戏\n");
				break;
			default:
				printf("选择错误\n");
				break;
		}
		
	} while (input);

	return 0;
}

完结撒花,恭喜你今天又进步了呀~

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

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

相关文章

【STM32】STM32学习笔记-串口发送和接收(27)

00. 目录 文章目录 00. 目录01. 串口简介02. 串口相关API2.1 USART_Init2.2 USART_InitTypeDef2.3 USART_Cmd2.4 USART_SendData2.5 USART_ReceiveData 03. 串口发送接线图04. USB转串口模块05. 串口发送程序示例06. 串口发送支持printf07. 串口发送支持printf_v208. 串口发送和…

在线表白网页制作源码,无需数据库,自带网站会员付费

源码介绍 通过在线表白&#xff0c;人们可以以一种浪漫的方式表达自己的感情&#xff0c;只需要填写一些基本信息&#xff0c;就能自动生成精美的表白页面。 为了增加网站的收入&#xff0c;用户可以购买网站会员&#xff0c;以使用指定的网页制作模板。 这个系统无需数据库…

Java中的多线程一

概述 进程 是正在运行的程序 是系统进行资源分配和调用的独立单位每一个进程都有它自己的内存空间和系统资源 线程 进程中的单个顺序控制流&#xff0c;是一条执行路径 单线程&#xff1a; 一个进程如果只有一条执行路径&#xff0c;则称为单线程程序多线程&#xff1a; 一…

编译原理复习笔记--简答题

1、编译过程概述 词法分析&#xff1a;输入源程序&#xff0c;对构成源程序的字符串进行扫描和分解&#xff0c;识别出一个个单词&#xff08;也称单词符号&#xff0c;或简称符号&#xff09;语法分析&#xff1a;在语法分析的基础上将单词序列分解成各类语法短语。语义分析&a…

海外代理IP在游戏中有什么作用?

随着科技的飞速发展&#xff0c;手机和电脑等电子产品已成为互联网连接万物的重要工具&#xff0c;深度融入我们的日常生活&#xff0c;我们借助互联网完成工作、休闲和购物等任务&#xff0c;以求提升生活质量。 不仅如此&#xff0c;网络游戏也是人们心中最爱&#xff0c;它…

Tensorflow2.0笔记 - 创建tensor

tensor创建可以基于numpy&#xff0c;list或者tensorflow本身的API。 笔记直接上代码&#xff1a; import tensorflow as tf import numpy as np import matplotlib.pyplot as plttf.__version__#通过numpy创建tensor tensor0 tf.convert_to_tensor(np.ones([2,3])) print(te…

贯穿设计模式-中介模式+模版模式

样例代码 涉及到的项目样例代码均可以从https://github.com/WeiXiao-Hyy/Design-Patterns.git获取 需求 购买商品时会存在着朋友代付的场景&#xff0c;可以抽象为购买者&#xff0c;支付者和中介者之间的关系 -> 中介者模式下单&#xff0c;支付&#xff0c;发货&#xff0…

Golang中for和for range语句的使用技巧、对比及常见的避坑

前言 基础语法不再赘述&#xff0c;写这个原因是之前的某次面试被问道了&#xff0c;我知道会导致问题但具体答下来不是很通顺。再回想自己开发过程中&#xff0c;很多地方都是使用到了for/for range&#xff0c;但是却从没注意过一些细节&#xff0c;因此专门学习一下进行记录…

手把手教你使用cubemx配置串口

重写fput函数 #include <stdio.h>#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endif /* __GNUC__*//*******************************************************************brief R…

Kubernetes (八) 金丝雀发布

一. 金丝雀发布作用&#xff1a; 金丝雀发布是指在生产环境中逐步推出新版本应用程序&#xff0c;只在一小部分用户或流量中使用该版本&#xff0c;并根据反馈逐步扩…

扩展欧几里得算法总结

知识概览 裴蜀定理&#xff1a;对于任意正整数a&#xff0c;b&#xff0c;一定存在非零整数x&#xff0c;y&#xff0c;使得 而且(a, b)是a和b能凑出来的最小的正整数。 通过扩展欧几里得算法可以求得裴蜀定理中x和y的值&#xff0c;x和y的通解为 &#xff0c; 例题展示 扩展欧…

系列十三、集合

一、集合 1.1、概述 集合与数组类似&#xff0c;只不过集合中的数据量可以动态的变化。 1.2、体系图 1.3、List集合 1.3.1、特点 存放的数据可以重复且有序。 1.3.2、常见操作 /*** List集合常见操作* */ Test public void listOperateTest() {List<String> cityList …

vue3 +TS 安装使用pinia状态管理

目录 一.安装 1.下载安装依赖 2.创建src/stores/index.ts文件 3.创建src/stores/states.ts文件 4.创建src/stores/interface/index.ts文件 5.修改main.ts 6.目录结构如下 7.测试使用 8.去到首页点击按钮&#xff0c;打开控制台查看 一.安装 1.下载安装依赖 npm insta…

逆向数据宽度与符号

正数与负数的 刚好是半 所以 0 表示正数 1表示负数 有符号与无符号是程序员定的 并不是开头是1就表示负数 0表示正数 得看有无符号 双字 32bit 4字节

批量置入视频封面:一分钟教程,简单易学

在视频制作过程中&#xff0c;为视频添加引人注目的封面是吸引观众的关键。而当我们需要批量处理多个视频时&#xff0c;如何快速、准确地置入封面就显得尤为重要。本文将为您揭示这一高效技巧&#xff0c;让您在一分钟内学会批量置入视频封面&#xff0c;提升视频的吸引力与观…

C++学习笔记(二十七):c++ 动态数组vector及优化

c的动态数组vector是STL的内容&#xff0c;关于STL&#xff0c;有兴趣可自行网上搜索资料。本节主要介绍vector的基本内容以及vector的简单优化。vector当超过数组最大范围&#xff0c;需要往里面添加新的元素时&#xff0c;会在内存中创建一个比上一个更大的数组&#xff0c;将…

RT-Thread:ADC 框架应用,通过 STM32CubeMX 配置 STM32 ADC驱动

关键词&#xff1a;ADC,RT-Thread ADC,STM32 ADC应用 说明&#xff1a;本笔记是记录如何开启 RT-Thread 框架的ADC功能&#xff0c;使用系统自带的ADC函数&#xff0c;并通过 STM32CubeMX 配置 STM32 ADC驱动 。 1. 打开board.h 文件&#xff0c;找到ADC 使用配置的流程&…

CMake入门教程【核心篇】动态库与静态库的差别

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1.概述2.动态库(Shared Libraries)主要特点使用场景3.静态库(Static Libraries)主要特点

java继承Thread实现多线程

1、AdminController文件 package com.controller;import com.myThread.AdminThread; import org.springframework.web.bind.annotation.*;RestController CrossOrigin RequestMapping("/admin") public class AdminController{GetMapping("/{id}")public …

离线安装jenkins:使用rpm安装包

目录 一、安装jdk1.8二、安装yum软件包三、下载rmp安装包四、安装jenkins的rpm安装包五、创建jenkins文件目录六、设置环境变量七、配置jdk位置八、配置Jenkins配置文件九、启动Jenkins十、访问Jenkins十一、安装Jenkins插件 一、安装jdk1.8 根据博客Linux操作系统安装jdk1.8并…