ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2021.12.5 关于c语言实现简单扫雷游戏

2021-12-07 13:32:27  阅读:184  来源: 互联网

标签:ROWS 游戏 2021.12 int mine game 扫雷 printf 雷盘


目录

整体思路:(test .c)(game .h)(game .c )

第一步: (游戏开始界面)

第二步: 初始化和打印雷盘

第三步:布置雷

第四步:排查雷 

game .h 文件代码汇总:

test .c  文件代码汇总:

game .c  文件代码汇总:

试玩:


对于初学者来说完整的写出扫雷游戏的代码还是相对较难的,但代码的长度相对于三子棋游戏会略短些,此时我们便可以分成各函数最后引用其到主函数中来实现代码的运行,首先整体的思路要确立完整。

整体思路:(test .c)(game .h)(game .c )

我们可先将三子棋拆分成3份源文件来使代码整体的观感更简洁明了

test .c   测试游戏的逻辑

game .h  关于游戏相关函数的申明,符号申明头文件的包含

game .c  游戏相关函数的实现


第一步: (游戏开始界面)

我们需要创建扫雷游戏的开始界面,我们先可写一个菜单函数。以玩家输入的值1或0来判断游戏的开始或结束,同时也要考虑玩家输入1和0之外的数,打印提醒玩家重新输入1或0这两个数字,我们可以便由此联想到循环语句和 switch 语句来实现可重复玩扫雷游戏和对玩家选择的判断。

test.c 中初始界面函数如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include"game.h"

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


int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("扫雷\n");
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新输入\n");
			break;
		}

	} while (input);

	return 0;
}

运行结果如下:


第二步: 初始化和打印雷盘

想实现的效果图如下:(定义:“0”为非雷  “1”为雷  )

首先需要明确几点:

a:扫雷游戏的雷盘包含两种信息,一是存放雷或者时非雷,二是存放字符 “ * ” 来隐藏我们的雷的信息同时进行雷的排查,所以我们可创建两个棋盘,一是用来存放布置好的雷的信息,二是用来存放排查出的雷的信息,进而实现对信息的分开处理。  

b :对于扫雷游戏的完成,我们先需在行列为 9*9 的雷盘中存放雷,即我们可先将存放雷的雷盘全部初始为化为 “0” ,利用时间戳来随机将雷盘中的 “0” 更换为 "1" , 由此我们可以便可以完成雷的随机存放。

c:在存放完雷之后便是玩家选坐标,当该坐标为雷时,玩家炸死,游戏结束,当该坐标不为雷时再进行周边对雷的排查和统计,是以玩家所选坐标为中心的九宫格来进行雷数量的统计,但是当我们选择九宫格边缘的坐标时,我们对以该坐标为中心的九宫格进行雷数量的排查时便会越界,显然我们可初始化两个行列为 11*11 的雷盘,将溢出行列为 9*9 的雷盘部分全部设为 “0” 即可解决对边缘坐标雷的排查溢出问题。

如图所示:

d:我们可将数组的 行 列 用定义的常量来代替,以便将来可对雷盘的大小进行修改。

如图:

 e:我们在打印棋盘的同时为了方便玩家寻找坐标点,我们可在 9*9 的雷盘的边缘打印对应其行和列的数字。

打印雷盘的代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include"game.h"

void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("——————扫雷游戏——————\n");
	//打印 列
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

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

打印结果:  (注意:我们最后仅需打印第二个雷盘,第一个雷盘仅存信息,但不打印)


第三步:布置雷

我们先明确思路  (我们先布置10个雷)(坐标 (x,y)为布置雷的坐标)

a:我们打印出来的雷盘大小虽然是 9*9 的,但是我们实际布置的是 11*11的雷盘。

b:我们所布置的雷应在 9*9 的雷盘中,所以我们利用时间戳得到的 x和y 随机数可以先分别取其行(9)和列(9)的模,其余数范围为 0—8,我们再在 0—8的基础上加1,便可以使我们的 x和y的数值大小在我们所需要的范围区间内,且使得布置的雷都在 9*9 的雷盘中。

布置雷的代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include"game.h"
#include<stdlib.h>

//布置雷
void SetMine(char mine [ROWS][COLS], int row, int col)
{
	//布置10个雷
	int count =0;
	while (count<10)
	{
		//生成随机下标
		int x = rand()%row+1; 
		// 我们将生成的随机值模上我们的 row(行 9) 和 col(列 9) 
		int y = rand()%col+ 1;
		if (mine [x][y] == '0')
		{
			mine [x][y] = '1';
			count++;
		}
	}
}

打印结果为:


第四步:排查雷 

我们先明确好思路:

1.输入排查的坐标
 2.检查坐标处是不是雷
      (1)    是雷      炸死  游戏结束
      (2) 不是雷    统计周围雷的个数   存储排雷的信息到show数组,游戏继续

统计雷周围雷的个数是统计以玩家所选坐标为中心的九宫格内雷的个数,有几个雷,我们便在玩家所选坐标的基础上,显示周围雷的个数的数字。(定义变量count,将九宫格内所有坐标的字符数字ASCII码值都加起来,因为字符数字“1”为雷,字符数字“0”为非雷,我们通过所加出来总的字符数字ASCII码值的大小减去我们的总共八个字符数字“0”ASCII码值的大小,便可知道周围雷的个数的数值大小)

如图所示:(本身坐标(x,y)的值就为 0 ,不需要加,仅需加其周边八个坐标中字符数字ASCII码值的大小)

 

我们还要明确的一点为,我们所创建是字符型二维数组,我们需将对应的数字转化为所对应字符的十进制ASCII码值。(字符“0”ASCII码值为 48 ,字符“2”的十进制ASCII码值为 2 +“0”= 50,字符“3”的十进制ASCII码值为 3 +“0”= 51, 我们由此可得 count +“0” 便能达到我们的目的)

排查雷的代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include"game.h"
#include<stdlib.h>

// 我们用来统计雷个数的函数 
int get_mine_count (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 + 1][y] +
			mine[x + 1][y + 1] +
			mine[x][y + 1] +
			mine[x - 1][y + 1] - 8 * '0'; 
//我们加上的值都为各字符数字 ASCII码值,最后我们还要减去8个字符“0的”ASCII码值
}


//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	//1.输入排查的坐标
	//2.检查坐标处是不是雷
	//   (1)是雷      炸死  游戏结束
	//     (2) 不是雷    统计周围雷的坐标   存储排雷的信息到show数组,游戏继续

	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入要排查的坐标\n");
		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 = get_mine_count (mine, x, y);
				//我们定义的二维数组show为字符型数组,我们便须转化为对应数字的ASCII码值
				show[x][y] = count + '0';  
				//显示排查出的信息
				 DisplayBoard(show, row, col);
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
		}
	}
}

到此我们扫雷游戏的制作就完全结束了,以下是各文件的所有代码段汇总

test .c   测试游戏的逻辑

game .h  关于游戏相关函数的申明,符号申明头文件的包含

game .c  游戏相关函数的实现

game .h 文件代码汇总:

#pragma once

#include<stdlib.h>
#include <stdio.h>

//在 game.h 中进行常量的定义
//当要用我们自己所定义的头文件时,我们需在源文件中打(#include"game.h")
#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 mine[ROWS][COLS], int row, int col);

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

test .c  文件代码汇总:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

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

void game()
{
	//存放布置好雷的信息的雷盘   
	char mine[ROWS][COLS] = {0};
	//存放排查出雷的信息的雷盘
	char show[ROWS][COLS] = {0};
	  //初始化雷盘
	InitBoard(mine, ROWS, COLS, '0');  //初始化存放雷的雷盘为 ”0“
	InitBoard(show, ROWS, COLS, '*'); //初始化排查雷的雷盘为 ”*“

	 //打印雷盘
	 DisplayBoard(show, ROW, COL);
	
	//布置雷
	 SetMine(mine, ROW, COL);
	 //DisplayBoard(mine, ROW, COL);

    //排查雷
	 FindMine(mine, show, ROW, COL);
}

int main()
{
	int input = 0;
	srand((unsigned )time(NULL));  // 利用时间戳,来随机生产雷的坐标从而布置雷
	do
	{
		menu();
		printf("请选择");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新输入\n");
			break;
		}

	} while (input);
	return 0;
}

game .c  文件代码汇总:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

//初始化 11*11 的雷盘
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 < rows; j++)
		{
			board[i][j] = set;
		}
	}
}


//打印 9*9 的雷盘
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;
	printf("——————扫雷游戏——————\n");
	//打印列
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i =1; i <= row; i++)
	{
		printf("%d", i);   //打印行
		for (j =1; j <= col; j++)
		{
			printf(" %c", board[i][j]);
		}
		printf("\n");
	}
	printf("——————扫雷游戏——————\n");
}

//布置雷
void SetMine(char mine [ROWS][COLS], int row, int col)
{
	//布置10个雷
	int count =0;
	while (count<10)
	{
		//生成随机下标
		int x = rand()%row+1; 
		// 我们将生成的随机值模上我们的 row(行 9) 和 col(列 9) 
		int y = rand()%col+ 1;
		if (mine [x][y] == '0')
		{
			mine [x][y] = '1';
			count++;
		}
	}
}

// 我们用来统计雷个数的函数 
int get_mine_count (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 + 1][y] +
			mine[x + 1][y + 1] +
			mine[x][y + 1] +
			mine[x - 1][y + 1] - 8 * '0'; 
//我们加上的值都为各字符数字 ASCII码值,最后我们还要减去8个字符“0的”ASCII码值
}


//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	//1.输入排查的坐标
	//2.检查坐标处是不是雷
	//   (1)是雷      炸死  游戏结束
	//     (2) 不是雷    统计周围雷的坐标   存储排雷的信息到show数组,游戏继续

	int x = 0;
	int y = 0;
	while (1)
	{
		printf("请输入要排查的坐标\n");
		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 = get_mine_count (mine, x, y);
				//我们定义的二维数组show为字符型数组,我们便须转化为对应数字的ASCII码值
				show[x][y] = count + '0';  
				//显示排查出的信息
				 DisplayBoard(show, row, col);
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
		}
	}
}

试玩:


以上便是关于 扫雷游戏 的内容了,喜欢可点个赞或收藏哦!

谢谢浏览!(如有问题,请各位大神即使指出,我会及时纠正!)

标签:ROWS,游戏,2021.12,int,mine,game,扫雷,printf,雷盘
来源: https://blog.csdn.net/weixin_63888301/article/details/121734341

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有