神作!最简单的小游戏《递归标记版扫雷》来了!一看就会!

文章目录

  • 思维导图
  • 扫雷大纲版
  • 函数文件位置
  • Test.c主函数
  • Game.h头文件
  • Game.c函数实现文件
    • 初始化雷盘函数
    • 打印雷盘
    • 布置雷
    • 统计周围坐标雷的个数
    • 玩家开始排雷
    • 递归展开函数
    • 标记函数
  • 笔记创作软件:Effie
    • 同为MarkDown的编辑器
  • GG.

思维导图

神作!最简单的小游戏《递归标记版扫雷》来了!一看就会!_第1张图片

扫雷大纲版

  • 神作!最简单的小游戏《递归标记版扫雷》来了!一看就会!_第2张图片

函数文件位置

  • 参考:万众期待!震惊全网——人人都能上手的最简单的三子棋小游戏来了!

Test.c主函数

#include"Game.h"

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

void game()
{
     
	两个大小一样的雷盘
	char Mine[ROWS][COLS] = {
      0 };//布置雷
	char Pmine[ROWS][COLS] = {
      0 };//用作显示排雷信息
	雷盘的初始化
	char set = 0; 想要初始化字符数组的元素是什么字符
	InitMine(Mine, ROWS, COLS, '0');0 方便根据该ASCII,进行后续的信息统计。
	InitMine(Pmine, ROWS, COLS, '*');

	布置雷。
	DecMine(Mine, ROW, COL);只用布置在真正玩时的区域。
	//ShowMine(Mine, ROW, COL);//看一下补完雷后的样子。

	打印棋盘-只需要显示游戏时的雷盘。
	ShowMine(Pmine, ROW, COL);

	玩家排雷 -需要把两个数组都传过去
	PlayMove(Mine,Pmine,ROW,COL);
}

int main()
{
     
	srand((unsigned int)time(NULL));
	int input = 0;
	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;
}

Game.h头文件

  • 数组名传参一律用 char 变量名[ROWS][COLS]接受。
#include
#include
#include

#define ROW 8
#define COL 8
#define ROWS ROW+2   防止边界排雷时,数组越界
#define COLS COL+2

#define Assmine 10   布置雷的个数。

void InitMine(char m[ROWS][COLS], int x, int y, char c);

void ShowMine(char m[ROWS][COLS], int x, int y);

void DecMine(char m[ROWS][COLS], int x, int y);

void PlayMove(char m[ROWS][COLS], char p[][ROW], int x, int y);

Game.c函数实现文件

初始化雷盘函数

  • 雷用字符'1'表示。
void InitMine(char m[ROWS][COLS], int x, int y, char c)
{
     
	int i = 0;
	int j = 0;
	for (i = 0; i < ROWS; i++)
	{
     
		for (j = 0; j < COLS; j++)
		{
     
			m[i][j] = c;
		}
	}
}

打印雷盘

  • 只需打印玩家排雷时用到的那个雷盘的大小,即行[ROW]列[COL]
void ShowMine(char m[ROWS][COLS], int x, int y)
{
     
	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 ",m[i][j]);
		}
		printf("\n");
	}
	printf("------ 雷盘 ------\n");
}

布置雷

void DecMine(char m[ROWS][COLS], int x, int y)
{
     
	//布置雷
	int count = Assmine;
	while (count)
	{
     
		int sx = rand() % ROW + 1;	//1-8的下标
		int sy = rand() % COL + 1;
		if (m[sx][sy] == '0')
		{
     
			m[sx][sy] = '1';
			count--;
		}
	}
}

统计周围坐标雷的个数

static int CountMine(char board[ROWS][COLS], int x, int y)//计算某个坐标周围的雷数
{
     
	return (board[x - 1][y] + board[x - 1][y + 1] +
		board[x][y + 1] + board[x + 1][y + 1] +
		board[x + 1][y] + board[x + 1][y - 1] +
		board[x][y - 1] + board[x - 1][y - 1]) - 8 * '0';//数字
}
  • 神作!最简单的小游戏《递归标记版扫雷》来了!一看就会!_第3张图片

玩家开始排雷

void PlayMove(char m[ROWS][COLS], char p[ROWS][COLS], int row, int col)
{
     
	int win = 0;赢的条件。
	int r = 0;
	int c = 0;
	while (win<row*col-Assmine)
	{
     
		printf("请输入要排查的坐标:>");
		scanf("%d%d", &r, &c);
		if (r >= 1 && r <= ROW && c >= 1 && c <= COL)
		{
     
			if (m[r][c] == '1')//是地雷
			{
     
				printf("很遗憾,您被炸死了!\n");
				ShowMine(m,ROW,COL);
				break;
			}
			else
			{
     
				int ret = CountMine(m, ROW, COL);
				p[r][c] = ret + '0';
				OpenMine(m, p, ROW, COL, r, c);
				ShowMine(p, ROW, COL);
				win++;
			}
		}
		else
		{
     
			printf("坐标输入错误,请重新输入!\n");
		}
	}
	if (win==row*col-Assmine)
	{
     
		printf("恭喜!扫雷成功·!!\n");
		ShowMine(p, ROW, COL);
	}
}

递归展开函数

static void OpenMine(char m[ROWS][COLS], char p[ROWS][COLS], int row, int col, int x, int y)
{
     
	int ret = CountMine(m, x, y); 调用统计雷个数的函数。
	if (ret == 0)
	{
     
		p[x][y] = ' ';
		if (x - 1 >0 && y - 1 >0 && m[x - 1][y - 1] == '0') 要确定周围8个坐标本身不是雷,才递归它周围的。
		{
     
			OpenMine(m, p, row, col, x - 1, y - 1);
		}
		else if (x > 0 && y - 1 > 0 && m[x][y - 1] == '0') 还要注意递归后坐标的临界值限制条件 比如行列不能大于ROW,COL 都应该大于0
		{
     
			OpenMine(m, p, row, col, x, y - 1);
		}
		else if (x + 1 <= ROW && y - 1 > 0 && m[x + 1][y - 1] == '0')
		{
     
			OpenMine(m, p, row, col, x + 1, y - 1);
		}
		else if (x - 1 > 0 && y > 0 && m[x - 1][y] == '0')
		{
     
			OpenMine(m, p, row, col, x - 1, y);
		}
		else if (x + 1 <= ROW && y > 0 && m[x + 1][y] == '0')
		{
     
			OpenMine(m, p, row, col, x + 1, y);
		}
		else if (x - 1 > 0 && y + 1 <= COL && m[x - 1][y + 1] == '0')
		{
     
			OpenMine(m, p, row, col, x - 1, y + 1);
		}
		else if (x > 0 && y + 1 <= COL && m[x][y + 1] == '0')
		{
     
			OpenMine(m, p, row, col, x, y + 1);
		}
		else if (x + 1 <= ROW && y + 1 <=COL && m[x + 1][y + 1] == '0')
		{
     
			OpenMine(m, p, row, col, x + 1, y + 1);
		}
	}
	else
	{
     
		p[x][y] = ret + '0'; 显示该坐标周围有几个雷
	}
}

标记函数

参考小游戏——扫雷(可以标记)

static void SignMine(char show[ROWS][COLS], int row, int col, const int count)
{
     
    int input = 0;
    int a = 0;
    int b = 0;
    do
    {
     
        printf("是否需要标记雷: 1.是        0.否\n");
        scanf("%d", &input);
        switch(input)
        {
     
        case 1:
            printf("请输入要标记的坐标:>");
            scanf("%d%d", &a, &b);
            if(show[a][b]=='\03')
            {
     
                show[a][b]='*';
                Print(show,row,col); 标记后打印一下棋盘
            }
            else if(show[a][b]=='*')
            {
     
                printf("该坐标已经被标记\n");
            }
            break;
        case 0:
            break;
        }
    }while(input);
}
————————————————
版权声明:本文为CSDN博主「Lsxlsxls」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Lsxlsxls/article/details/80406145

笔记创作软件:Effie

  • 只要是可以白嫖。
  • 思维导图免费用。
  • 功能简洁又不简陋。

同为MarkDown的编辑器

  • 该软官网
  • 使用技巧可以看这里:CSDN 文本编辑器Markdown…十分钟新手快速入门指南也可看官网。

GG.

  • 建议写完一个函数,调试一下。
  • 如有bug…,断点调试。

你可能感兴趣的:(C,Training,camp,网页游戏,c语言,游戏开发,前端,递归算法)