C语言实现扫雷游戏详细流程

目录
  • 前言
  • 头文件部分
  • 主函数部分(源文件)
  • 函数定义(原文件)
    • 1.菜单打印
    • 2.初始化棋盘
    • 3.打印棋盘
    • 4.生成地雷
    • 5.数雷并赋值给trueboard
    • 6.排查雷区
    • 7.展开
    • 8.判断输赢

前言

嘿!是不是写扫雷小游戏的时候发现一个个输入太慢了?是不是想要展开却发现陷入了死递归?让小黄教教你怎么巧妙地解决这个问题吧!

其实总结起来就是一句话“可以让计算机多判断,但是不能让他多算”。只要每次判断一个格子周围雷数的时候赋值到另一个棋盘,后续递归的时候就不判断这个地方的棋盘就解决啦!

PS:采用了多文件的编写方式哦~​

头文件部分

“简单“”对游戏做了一个“小小的”提升,添加了可自行选择棋盘的大小,以及游戏时可以选择如何排查,存疑,确定操作,这样才能算真正的扫雷嘛。

#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#define hang  11
#define lie   11
#define mines 10
//是否进入游戏
void menu();
//游戏难度选择菜单
void menu2();
//游戏操作选择菜单
void menu3();
//初始化棋盘
void star(char arr[100][100], int g, int h);
//打印棋盘
void prin(char arr[100][100],int g,int h);
//生成地雷
void mkmine(char arr[100][100], int g, int h, int f);
//数雷并且赋值给mine棋盘
void countmine(char arr[100][100],int g, int h);
//初步排查是否炸雷
int  paic(char arr1[100][100], char arr2[100][100], int x, int y, int g, int h);
//进一步实现非雷区展开(展开一片全是0的格子)
void paic2(char arr1[100][100], char arr2[100][100], int x, int y, int g, int h);
//判断输赢
int  pand(char arr[100][100], char arr2[100][100], int g, int h,int f);

主函数部分(源文件)

其实写完之后才发现hang,lie,mines没必要提前宏替换哈哈哈哈哈,因为为了实现棋盘大小的设定,所以传参略略有些多。

这一部分其实就是游戏的大体框架,也就是游戏的过程,函数的定义部分我放在了另一个源文件内

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
int main()
{
	char mine[100][100], show[100][100];
	int key = 0, x, y, nandu, i, j, o, v, b;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		scanf("%d", &key);
		if (key == 1)
		{
			menu2();
			scanf("%d", &nandu);
			switch (nandu)
			{
			case 1:
				i = hang, j = lie, o = mines;
				break;
			case 2:
				i = hang + 7, j = lie + 7, o = mines + 30;
				break;
			case 3:
				i = hang + 7, j = lie + 31, o = mines + 89;
				break;
			case 4:
				printf("请输入行数:");
				scanf("%d", &i);
				i += 2;
				printf("请输入列数:");
				scanf("%d", &j);
				j += 2;
				printf("请输入雷数:");
				scanf("%d", &o);
				break;
			}
			star(mine, i, j);
			star(show, i, j);
			mkmine(mine, i, j, o);
			countmine(mine, i, j);
			while (1)
			{
				system("cls");
				prin(show, i, j);
				loop:menu3();
				loop1:scanf("%d", &b);
				if (b == 2)
				{
					printf("请输入确定的雷区-> ");
					scanf("%d%d", &x, &y);
					show[x][y] = '@';
				}
				else if (b == 3)
				{
					printf("请输入存疑的雷区-> ");
					scanf("%d%d", &x, &y);
					show[x][y] = '?';
				}
				else if (b == 1)
				{
					printf("请输入要排查的雷区-> ");
					scanf("%d%d", &x, &y);
					v = (paic(mine, show, x, y, i, j));
					if (v == 1)
					{
						if (pand(show, mine, i, j, o))
						{
							printf("You win!\n");
							break;
						}
						else;
					}
					else if (v == 0)
						break;
					else if (v == 2)
						goto loop;
				}
				else
				{
					printf("worng input,again?\n");
					goto loop1;
				}
			}
		}
		else if (key != 0)
		{
			system("cls");
			printf("wrong input,again?\n\n\n");
		}
	} while (key);
	return 0;
}

函数定义(原文件)

1.菜单打印

就是几个不同的选择界面啦~

#define _CRT_SECURE_NO_WARNINGS
#include"game.h"
void menu()
{
	printf("#################################\n");
	printf("###########0.结束游戏############\n");
	printf("###########1.开始游戏############\n");
	printf("#################################\n");
}
void menu2()
{
	printf("#################################\n");
	printf("######## 请选择游戏难度 #########\n");
	printf("########## 1.简单模式 ###########\n");
	printf("########## 2.普通模式 ###########\n");
	printf("########## 3.困难模式 ###########\n");
	printf("########## 4.自定义模式 #########\n");
	printf("#################################\n");
}
void menu3()
{
	printf("#################################\n");
	printf("###### 请选择您要进行的操作 #####\n");
	printf("########## 1.排查雷区 ###########\n");
	printf("########## 2.雷区确定 ###########\n");
	printf("########## 3.雷区存疑 ###########\n");
	printf("#################################\n");
}

2.初始化棋盘

void star(char arr[100][100], int g, int h)
//初始化的时候比真实棋盘大一圈,方便后面的paic函数,避免出现越界现象
{
	int m, n;
	for (m = 0; m < g; m++)
		for (n = 0; n < h; n++)
			arr[m][n] = ' ';
}

3.打印棋盘

void prin(char arr[100][100], int g, int h)
//打印的时候只需要打印真实棋盘即可
{
	int m, n;
	for (m = 0; m <= h - 2; m++)
		printf("%3d", m);//第一行的坐标,方便玩家找扫雷位置
	printf("\n");
	for (m = 1; m <= g - 2; m++)
	{
		printf("%3d", m);//行号
		for (n = 1; n <= h - 2; n++)
		{
			printf("%3c", arr[m][n]);
		}
		printf("\n");
		//%3d ,%3c都是为了美观
	}
}

4.生成地雷

void mkmine(char arr[100][100], int g, int h,int f)
//种子一定要放在外面,主函数里面,如果放在函数里面生成会特别慢(暂不清楚原因)
{
	int i, k=0, x, y;
	for (i = 0; k < f; i++)
	{
		x = rand() % (g - 2) + 1;
		y = rand() % (h - 2) + 1;//生成的数范围从 1 开始
		if (arr[x][y] == ' ')
		{
			arr[x][y] = '*';//布置雷‘*'
			k++;//计数雷的个数
		}
	}
}

5.数雷并赋值给trueboard

这里是一个优化过程,先计算好每一个格子周围的雷应该是多少,赋值给trueboar,玩家排查的时候只需要从trueboard中找对应点位就好了。避免了每次排查时需要计算周围的雷数所造成时间上的浪费。

void countmine(char arr[100][100], int g, int h)
{
	int m, n, m1, n1, k;
	for ( m = 1; m <= g -2; m++)
		for (n = 1; n <= h - 2; n++)//只用给真实棋盘范围赋值
		{
			k = 0;
			if (arr[m][n] == '*')
				continue;
			else//如果arr[m][n]不是雷
			{
				for (m1 = m - 1; m1 <= m + 1; m1++)
					for (n1 = n - 1; n1 <= n + 1; n1++)
						if (arr[m1][n1] == '*')
							k++;//统计九宫格内‘*'的个数
				arr[m][n] = k+48;//arr是字符数组,所以记录字符‘1'-‘9',k+48即将数字1-9变为字符‘1'-‘9'对应的ascll码值
			}
		}
}

6.排查雷区

如果扫到雷,就把雷的位置给到showboard上面,让玩家死的明明白白哈哈哈哈啊

int  paic(char arr1[100][100], char arr2[100][100], int x, int y, int g, int h)
{
	int m, n;
	if (arr1[x][y] == '*')
	{
		system("cls");//清空屏幕,为了美观
		for (m = 0; m < g; m++)
			for (n = 0; n < h; n++)
				if(arr1[m][n]=='*')
					arr2[m][n] = arr1[m][n];//将余下的雷的位置赋给show棋盘,再进行展示
		prin(arr2, g, h);
		printf("You lose!\n\n\n");
		return 0;//输了之后回到主函数就重新开始,所以返回0
	}
	else if (x > g - 2 || x < 1 || y > h - 2 || y < 1)//错误地址(超出棋盘限制)
	{
		printf("wrong location,again?\n");
		return 2;
	}
	else//排查正确
	{
		paic2(arr1,arr2,x,y, g, h);
		return 1;
	}
}

7.展开

只要排查点对应0时才需要判断是否展开,是则必定九宫格内没有雷,展开九宫格,然后对九宫格进行一个判断,如果存在0并且,在showboard上九宫格内存在没有排查的,就进入递归,这样的话,最多递归次数就是棋盘的长,到达边界后就会返回上一层paic2,不会出现指数增长式的递归导致栈溢出

void paic2(char arr1[100][100], char arr2[100][100], int x, int y, int g, int h)
{
	int m1, n1, m, n;
	arr2[x][y] = arr1[x][y];//先赋值,判断是不是0==>有没有展开的必要
	if (arr2[x][y] == '0')
	{
		//展开九宫格内
		for (m1 = x - 1; m1 <= x + 1; m1++)
			for (n1 = y - 1; n1 <= y + 1; n1++)
			{
					arr2[m1][n1] = arr1[m1][n1];
			}
		for (m1 = x - 1; m1 <= x + 1; m1++)
			for (n1 = y - 1; n1 <= y + 1; n1++)
				if (arr2[m1][n1] == '0' && m1 >= 1 && n1 >= 1 && m1 <= g - 2 && n1 <= h - 2)//判断九宫格内是否存在0==>是否可以进一步展开
				{
					for (m = m1 - 1; m <= m1 + 1; m++)
						for (n = n1 - 1; n <= n1 + 1; n++)
							if (arr2[m][n] == ' ' && m >= 1 && n >= 1 && m <= g - 2 && n <= h - 2)
							//进一步筛选如果该 0 九宫格内存在空格(未排查的地方)则展开,若不存在则说明周围已经排查过了,没必要展开,避免了栈溢出
								paic2(arr1, arr2, m, n, g, h);//递归实现展开
				}
	}
}

8.判断输赢

如果showboard上面存在没有被排查的地方,也就是对应字符小于0或大于9且不为‘@’,并且trueboard对应点位不是雷;或者已经排查,但是排查错误,也就是对应字符‘@’,但trueboard对应字符不是雷,就说明没有排查完,均会返回0,表示需要继续

int  pand(char arr1[100][100], char arr2[100][100], int g, int h,int f)
{
	int m, n, count=0,count2=0;
	for (m = 1; m <= g - 2; m++)
		for (n = 1; n <= h - 2; n++)
			if (((arr1[m][n] == ' ' || arr1[m][n] > '?') && arr2[m][n] != '*') || (arr1[m][n] == '@' && arr2[m][n] != '*'))//非雷区必须排查
				return 0;
	return 1;
}

到此这篇关于C语言实现扫雷游戏详细流程的文章就介绍到这了,更多相关C语言扫雷内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 基于C语言扫雷游戏的设计与实现

    目录 1 引言 2 相关工作 3 本文方法 4 结果与分析 5 总结 整体代码 1 引言 伴随着信息技术的快速发展,近年来,人们的生活已经离不开计算机.生活娱乐几乎都是在计算机上进行的.其中的扫雷游戏就是之一.扫雷游戏是微软公司在1992年在windows系统上发布的一款益智类小游戏,直到今天这款小游戏依然存在,可见此款游戏的成功.本文将用Visual Studio 2019作为开发工具来模拟实现扫雷游戏.经过大一第一学期的学习,我们对C语言的理论及其相关知识有了一定的认识和了解.本文可以把我们

  • C语言实现第一次防死版扫雷游戏

    目录 前言 一.功能描述 二.实现的步骤 1.菜单的打印函数: 2.初始化雷盘函数: 3.打印雷盘函数: 4.埋雷函数: 5.排雷函数: 6.防止第一次死的函数: 7.展开函数: 总结 前言 扫雷这款经典的游戏想必大多数人都玩过了,今天用C语言实现了扫雷小游戏,小伙伴们快来看看吧. 一.功能描述 扫雷代码有以下功能: 1.若输入的坐标周围没雷,可以直接展开 2.防止第一次玩就直接踩雷,被炸死 3.若输入的坐标周围有雷,会显示周围雷的个数 4.若排雷失败,会展示出雷图的雷分布是怎样的 二.实现的步

  • 基于C语言实现简易扫雷游戏

    本文实例为大家分享了C语言实现简易扫雷游戏的具体代码,供大家参考,具体内容如下 1.头文件 #define _CRT_SECURE_NO_WARNINGS //包含头文件 #include <stdio.h> #include <stdlib.h> //定义数值 #define ROW 9 #define COL 9 #define ROWS ROW+2 #define COLS COL+2 //定义雷的数量 #define mine_num 10 //函数定义 //初始化 voi

  • C语言实现扫雷游戏详解(附源码)

    目录 1.游戏的功能 2.游戏实现的基本思路 2.1实现菜单给玩家选择 2.2初始化棋盘 2.3数组大小的问题 2.4对棋盘赋值 2.5打印棋盘 2.6布置雷 2.7排查雷 3.代码基本实现部分 3.1主函数部分 3.2 初始化棋盘 3.3对两个棋盘进行赋值 3.4打印棋盘 3.5布置雷 3.6排查雷  3.7函数声明 4.扫雷游戏的源代码 总结 1.游戏的功能 游戏的主要功能有 1:棋盘内有若干个雷 2:玩家输入要排查雷的坐标 3:在玩家输入的坐标处显示周围八个坐标有几个雷 3:若玩家将所有的

  • C语言实现自定义扫雷游戏(递归版)

    本文实例为大家分享了C语言自定义扫雷游戏的具体代码,供大家参考,具体内容如下 实现过程 对于用C语言实现扫雷游戏得实现,可将游戏过程分为两个板块. 实现游戏关键功能得函数 搭建合理得游戏过程 实现游戏关键功能 为了将游戏功能方便管理和键入,首先我们创建一个头文件,mine.h对游戏功能进行声明.然后创建对应的源文件mine.c对这些函数进行定义. 对于游戏功能,我们首先想到的是构建一个目标规格的雷盘,也就是二维数组.为了使游戏更具可玩性,所以雷盘的规格应可以自定义.所以在mine.h头文件中,应

  • 基于C语言实现简单的扫雷小游戏

    本文实例为大家分享了C语言实现简单的扫雷小游戏的具体代码,供大家参考,具体内容如下 首先来规划一下扫雷游戏实现的几个步骤: 初始化棋盘:二维数组的遍历及赋值 为了后续代码的简洁方便,我们用'0'来初始化 void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) { int i = 0; int j = 0; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++

  • C语言实现递归版扫雷游戏实例

    目录 思路 清晰的逻辑 菜单 棋盘 布置雷 排雷 判断输赢 text.c实现 game.c实现 game.h实现 递归部分详解 总结 思路 清晰的逻辑 为方便将其分为三个文件:text.c(测试) game.c(函数实现) game.h(头文件声明) 在排雷的时候为了方便,我们需要将每一行每一列对应的行数,列数打印出来. #define LEI 10 #define ROW 10 #define LOW 10 #define ROWS ROW+2 #define LOWS LOW+2 //在定义

  • C语言实现扫雷游戏小项目

    本文实例为大家分享了C语言实现扫雷游戏的具体代码,供大家参考,具体内容如下 一.基本实现功能 1.建立一个游戏菜单 2.创建游戏盘,一个埋雷,一个显示. 3.打印游戏盘. 4.翻开坐标如若没踩到雷显示周围一圈8个有几个雷. 5.判断胜利 翻开的格子数等于没埋雷的个数. 二.源代码展示 1.头文件  minesweep.h #pragma once #include <stdio.h> #include <Windows.h> #include <string.h> #i

  • C语言扫雷游戏的简单实现

    今天来用c语言做一个扫雷功能的简单实现,首先创建一个test.c来用于在写代码的途中测试扫雷代码,game.h来存放实现扫雷函数需要用到的头文件,game.c来存放最终的成品. 首先用函数打印一个菜单,让玩家选择进行游玩扫雷游戏或者退出,考虑到玩家会输入1和2以外的数字,我们加上一个fefault,将菜单放入do-while循环中,while的结束条件为choose为0,玩家在结束一场游戏后可以重新走一边循环,保证用户在结束一把扫雷之后可以选择继续进行下一局或是退出游戏. void menu()

  • C语言实现扫雷游戏详细流程

    目录 前言 头文件部分 主函数部分(源文件) 函数定义(原文件) 1.菜单打印 2.初始化棋盘 3.打印棋盘 4.生成地雷 5.数雷并赋值给trueboard 6.排查雷区 7.展开 8.判断输赢 前言 嘿!是不是写扫雷小游戏的时候发现一个个输入太慢了?是不是想要展开却发现陷入了死递归?让小黄教教你怎么巧妙地解决这个问题吧! 其实总结起来就是一句话“可以让计算机多判断,但是不能让他多算”.只要每次判断一个格子周围雷数的时候赋值到另一个棋盘,后续递归的时候就不判断这个地方的棋盘就解决啦! PS:采

  • C语言实现扫雷游戏详细代码实例

    扫雷游戏 思路:先制作一个菜单让玩家选择是玩游戏还是退出游戏,菜单做好了,接着我们开始制作扫雷的棋盘并初始化,初始化弄完了我们下一步开始埋雷,雷埋好了就开始扫雷. 大概思路就是这样具体实现看下面: 菜单的实现代码: int main() { int input = 0; srand((unsigned int)time(NULL)); do { printf("**************************\n"); printf("*** 1. play 0. exi

  • C语言实现扫雷游戏详细代码

    本文实例为大家分享了C语言实现扫雷游戏的详细代码,供大家参考,具体内容如下 一.思想实现 本文的扫雷游戏主要实现以下的功能: 1.显示雷和其信息 2.输入一个坐标可观测其周围九格内的地雷数 3.点击到地雷则游戏结束 用到的IDE为VS2013 二.源代码 创建一个头文件saolei.h 存放关于所有自定义函数的声明 #define COL 9 char** creatMat(int row, int col); void intMat(char** Mat, int row, int col,

  • C语言实现扫雷游戏(可以自动展开)

    前言 本篇博客主要介绍如何使用C语言实现扫雷游戏. 一.游戏规则 在一张ROW行COL列的地图上存在MINE_COUNT个地雷.玩家输入坐标翻开格子,若没有踩雷,则计算此格子周围8个格子的地雷总数,并将此格子的星号用数字代替.若数字为0,则继续递归计算与此格子相邻的4个格子周围的地雷情况(即自动展开).若踩雷,则游戏结束.当地图上的数字与星号之和等于格子总数时,判定为玩家胜利.宏定义如下: #define ROW 9 #define COL 9 #define MINE_COUNT 10 二.游

  • C语言实现扫雷游戏(可展开)

    本文实例为大家分享了C语言实现扫雷游戏的具体代码,供大家参考,具体内容如下 # 一.游戏的思路 先理清游戏大概需要实现的功能,菜单功能的实现.棋盘初始化.打印棋盘.布置雷等.运用两个数组,一个放入布置雷的信息,另一个放入排查雷的信息.选一个坐标扫雷,坐标有雷则游戏结束,没有就计算选中坐标的周围8个格子中雷的总数放入选中的坐标中,若选中的坐标周围8个格子中都没有雷则自动展开.考虑到棋盘边框的情况,实际数组要比打印出的棋盘多两行两列.下面是宏定义和函数声明: ROW.COL为打印行.列,ROWS.C

  • C语言版扫雷游戏

    本文实例为大家分享了C语言版扫雷游戏的具体代码,供大家参考,具体内容如下 1.思路 一.创建二维数组,来表示地图 每一个格子要表示的信息: 1.未翻开状态(草地)和已翻开状态(数字) 2.该格子是地雷或者不是地雷(1表示是地雷,0表示不是) 二.使用两个二维数组来分别表示以上的两种状态 第一个二维数组 char showMap[9][9];表示每个格子的翻开和未翻开状态 表示未翻开,字符'0'-'8'表示已翻开的数字 第二个二维数组 char mineMap[9][9];表示每个格子是否是地雷

  • C语言实现扫雷游戏(含注释详解)

    本文实例为大家分享了C语言实现扫雷游戏的具体代码,供大家参考,具体内容如下 前言 一.游戏规则介绍 扫雷是一个十分经典的游戏,一张棋盘中有很多个不确定是雷还是安全区域的格子,当点击之后若没有雷则会在该区域显示周围八个格子雷的数目,若有雷则游戏结束.今天我就跟大家分享一下如何用c语言实现初阶版扫雷. 二.基本思路流程介绍 1.创建一个用户交互菜单 2.创建一个Show_Mines棋盘用来埋雷并初始化 3.创建一个Show_Table 棋盘用来和用户交互并初始化 4.玩家选择想要扫描的坐标 5.判定

  • C语言实现扫雷游戏(含注释详解)

    本文实例为大家分享了C语言实现扫雷游戏的具体代码,供大家参考,具体内容如下 前言 一.游戏规则介绍 扫雷是一个十分经典的游戏,一张棋盘中有很多个不确定是雷还是安全区域的格子,当点击之后若没有雷则会在该区域显示周围八个格子雷的数目,若有雷则游戏结束.今天我就跟大家分享一下如何用c语言实现初阶版扫雷. 二.基本思路流程介绍 1.创建一个用户交互菜单 2.创建一个Show_Mines棋盘用来埋雷并初始化 3.创建一个Show_Table 棋盘用来和用户交互并初始化 4.玩家选择想要扫描的坐标 5.判定

  • C语言实现扫雷游戏(可展开)

    本文实例为大家分享了C语言实现扫雷游戏的具体代码,供大家参考,具体内容如下 # 一.游戏的思路 先理清游戏大概需要实现的功能,菜单功能的实现.棋盘初始化.打印棋盘.布置雷等.运用两个数组,一个放入布置雷的信息,另一个放入排查雷的信息.选一个坐标扫雷,坐标有雷则游戏结束,没有就计算选中坐标的周围8个格子中雷的总数放入选中的坐标中,若选中的坐标周围8个格子中都没有雷则自动展开.考虑到棋盘边框的情况,实际数组要比打印出的棋盘多两行两列.下面是宏定义和函数声明: ROW.COL为打印行.列,ROWS.C

  • Java实现斗地主与猜数字游戏详细流程

    目录 斗地主小游戏之洗牌发牌 任务描述 运行结果 任务目标 实现思路 实现代码 猜数字游戏 任务描述 运行结果 任务目标 实现思路 实现代码 总结 斗地主小游戏之洗牌发牌 任务描述 编写一个斗地主发牌洗牌的程序,要求按照斗地主的规则完成洗牌发牌的过程,牌面由花色色和数字(包括J,Q,K,A字母)组成,花色有红桃,黑桃,方块,梅花组成.还设有大王和小王.将这54张牌的顺序打乱,有三位玩家参与游戏,每人轮流一次摸一张牌,剩余的三张作为底牌,程序结束,打印出每人手中的纸牌和底牌. 运行结果 任务目标

随机推荐