C语言小游戏之扫雷(万字详解)

news2025/1/8 4:19:00

hello,大家好,今天我们继续为大家带来一个小游戏,扫雷。相信这个游戏又是很多人的童年,那么我们今天就来实现一下这个扫雷游戏。


目录

一、游戏简介

 二、游戏的基本设计

1.游戏基本思路

2.游戏基本框架

3.如何设计布置雷与排查雷?

 4.数组的大小如何设置

5.数组的定义代码展示

 三、游戏具体功能详解

1.初始化数组(InitBoard)

(1)函数的声明和定义

 (2)初始化数组代码展示

 (3)初始化数组代码如下

2.打印数组(DisplayBoard)

(1)打印数组的定义和声明

 (2)代码的实现

 (3)测试代码

 (4)更进一步优化

 (5)运行测试

(6)更进一步的优化界面

(7)代码实现如下

3.布置雷(SetMine)

(1)布置雷函数的定义和声明

 (3)具体的布置雷实现

 (4)测试布雷

 (5)布置雷的代码实现

4.排查雷(FindMine)

(1)排查雷函数的声明和定义

(2)排查雷的实现逻辑

(3)测试

(4)排雷的结束条件

 (5)优化多次排查同一个位置的bug

(6)排查雷代码实现如下

四、游戏完整代码(分文件)

test.c文件

game.h文件

game.c文件

五、完整代码展示(合并为同一个文件)

总结


一、游戏简介

虽然说是一个基本上大家都听过,并且大多数人都玩过的一个小游戏,但是其实很多人当时都是瞎玩的。所以呢,我们先来介绍一下游戏规则。这个游戏,我们可以直接在电脑上搜索到,打开浏览器直接搜索扫雷。我们使用如下图所示的游戏

 点击9*9棋盘,如下图所示,每一行是9个元素,每一列也是9

我们随机点开其中的一个方格,他会进行展开,其中白色方格代表这块没有雷。有数字的方格代表其周围一圈的八个格子里面有雷的个数 。我们就是根据这些提示进行排雷

而一旦踩中了雷以后,就会失败

 二、游戏的基本设计

1.游戏基本思路

1.布置雷:创建一个二维数组,随机生成十个坐标放到位置上

2.排查雷:选择一个坐标,判断是否是雷,如果是,则爆炸,如果不是则遍历以他为中心的9个元素,并显示一个周围雷的个数。

2.游戏基本框架

在我们前面讲解了三子棋还有猜数字小游戏后,相信大家已经对这个思路很熟悉了,我们还是采用分文件的形式写代码,创建test.c,game.h,game.c三个文件。

这里就不在赘述了,直接给出代码,以下都是test.c文件中的代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void meau()
{
	printf("*************************\n");
	printf("******* 1. 开始扫雷 ******\n");
	printf("******* 0. 退出游戏 ******\n");
	printf("*************************\n");

}
void game()
{
	printf("开始扫雷\n");
}
void test()
{
	meau();
	int input = 0;
	do
	{
		printf("请输入选项>:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

当然还是需要测试的,我们进行一次测试,结果符合我们的预期

3.如何设计布置雷与排查雷?

我们的目标是布置雷与排查雷,那么这个时候有一个问题了,我们如果使用一个数组来记录布置雷的话,假如说我们记作,有雷是1,无雷是0。那么未来我开始排查雷的时候,想要扫雷,扫的这个位置是需要显示出周围有几个雷的。那这样的话,加入说我周围只有一个雷,那么打印出来的就只有1。可是这样子的话,我们这个位置就相当于被修改了,莫名奇妙的多出了一个雷,这就导致了一些混乱,产生了大量的bug。所以说这样的方法不太合理,我们需要进行优化。

那么如何进行优化呢?我们想到,既然只使用一个数组会乱,那么我们使用两个数组呢?一个数组仅仅用来放雷,一个数组用来打印出来让人来看。并且要记录这个周围有多少个雷。所以说,这样做的话就是可行的。程序就不会乱套了。

对于我们那个需要让人看的数组而言,我们一开始人是看不见雷的,所以说我们需要一开始打印的全是*号这个字符,为了方便起见,我们显示出周围有几个雷的时候也是使用字符数字来显示出周围有多少个雷。那么这样的话,不妨统一一下,两个数组都是字符数组。

 4.数组的大小如何设置

有很多人不经思考的直接回答说9*9即可,可是当我们在排查雷的时候,遇到边界的坐标如何排查呢,我们如果想要排查他的一圈的话,那么毫无疑问越界了。所以这不是明智之举。我们应当进行在这个数组上加上一圈,所以行和列都应该加上2。这样就不会越界访问了,当然为了统一一下,我们两个数组都是这样加上一圈。

5.数组的定义代码展示

有了前面那么多代码的思考,那么我们能不能实现一下呢。我们先定义一下数组吧。如下图所示,我们为了方便起见我们直接在game.h中define一下,然后我们想要在test.c文件中使用这个define定义常量。就得引入这个game.h这个头文件。然后就可以定义字符数组了。当然我们是要使用行和列都+2的那个define定义的常量。

 三、游戏具体功能详解

1.初始化数组(InitBoard)

(1)函数的声明和定义

很显然,我们要初始化数组两次,所以说,我们除了传数组名,行和列以外,需要传一个初始化成什么样子的一个字符。需要注意的是,这里传的是字符0,字符0和数字0是不一样的,字符0的ASCII值是48。'\0'的ASCII值是0,而如果传一个0的话,那么他最终打印出来的就是一堆'\0'也就是什么都没有。

//初始化数组
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);

 

 (2)初始化数组代码展示

这块还是比较简单的,我们用两层循环即可

注意:此图中出现了一个经典的错误,标准的零分

在第12行中,这个set不应该带有单引号,因为我们set他本身是一个变量,对变量带一个单引号,那么就势必导致一些不可预料的错误。

这也是很多人都喜欢犯的一个错误!!!

 (3)初始化数组代码如下

//初始化数组
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;
		}
	}
}

2.打印数组(DisplayBoard)

我们初始化好数组以后,我们肯定希望我们现在就能看到这个数组。这也是方便我们后续进行测试的一个重要步骤,不过需要注意的是,我们打印肯定不是打印这个11*11的数组,而是只打印9*9的数组即可,因为这个人只需要看到9*9的就可以了

(1)打印数组的定义和声明

这里唯一需要注意的是,我们定义和声明函数的时候,数组的大小可千万不要写错了,写出了ROW,注意,我们这里数组的大小仍然是11*11的,只不过因为我只需要9*9就足够了。

//打印数组
void DisplayBoard(char board[ROWS][COLS], int row, int col);

 

 

 (2)代码的实现

对于这个代码,其实也不是很难,同样两个for循环解决

 (3)测试代码

同样的,写一点,测一点,好在结果也确实符合我们的预期,需要注意的是,有的人可能注意到了printf为什么有绿色警告,其实这是因为我们的game.c文件中还没有<stdio.h>这个头文件。为了方便,我们直接把test.c中的<stdio.h>挪到game.h文件中,就可以解决了

 (4)更进一步优化

当然,我们此时打印出来的数组还不够完美,因为打印出来的数组密密麻麻,我们无法识别坐标,所以我们最好能把行标和列表打印出来就更加完美了。

 (5)运行测试

这样一来就完美了

(6)更进一步的优化界面

 这样可以使得测试更好看

(7)代码实现如下

//打印数组
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
	printf("-------扫雷--------\n");
	int i = 0;
	int j = 0;
	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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("-------扫雷--------\n");

}

3.布置雷(SetMine)

(1)布置雷函数的定义和声明

我们布置雷都是往mine数组里面放的,这个数组的大小是11*11,需要操作的行是9,列是9。所以定义和声明为

void SetMine(char board[ROWS][COLS], int row, int col);

 

 (2)雷的个数以及雷坐标的生成

我们开始生成雷的个数和坐标。雷的个数我们可以使用一个define来进行定义。雷的坐标则需要使用一个随机数的使用。代码实现如下

 

 (3)具体的布置雷实现

 (4)测试布雷

如下图所示,我们在布置好雷以后在后面打印一下数组

 结果为下图所示,刚好符合我们的预期,就是10个雷

 (5)布置雷的代码实现

//布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
	//雷的个数
	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--;
		}
	}
}

4.排查雷(FindMine)

(1)排查雷函数的声明和定义

我们在排查的时候,是在mine数组中进行查找,然后将结果反馈给show数组,所以需要两个数组都传过去。我们进行排查的时候,只需要使用行9列9即可

 

 

(2)排查雷的实现逻辑

我们在排查雷的过程中的逻辑是这样,让用户输入一个坐标,通过这个坐标先判断是否合法,如下图所示

 现在我们可以确保我们的坐标是合法的了,在合法的基础上,如果这个坐标中的位置已经是字符1了,那玩家就被炸死了,游戏结束并打印出雷区的棋盘。如果不是字符1,那就开始统计他的一圈有多少个雷,为了方便统起见,我们使用一个函数来进行统计。这个函数我们不妨就定义为

int get_mine_count(char mine[ROWS][COLS], int x, int y);

这个函数返回一个整型数字,传一个数组和需要查询的坐标即可。我们最后只需要将返回的这个整型数字+字符0即可得到对应的字符,然后将这个字符赋值给show数组对应的位置,并打印出来

 那么我们现在该实现get_mine_count这个函数了,这个难度也不大,我们把周围一圈的都加起来然后减去8个字符0就可以解决了

(3)测试

此时我们的test.c文件是这样的。前面打印出来的那些部分我们后期可以将其给删掉。但是现在我们是正在测试中,没有必要删除。

 

被炸死案例

 

 坐标不合法案例

(4)排雷的结束条件

当我们一直排雷下去,我们会发现我们的代码有一点问题,那就是排雷无法结束。所以说我们要在循环加上限制条件,我们可以定义一个变量,每一次没有被炸死则这个变量++。对于我们9*9的棋盘而言只要有81-10=71次没有被炸死,就赢了。所以说我们的代码实现如下

 为了方便测试,我们将雷的数量暂时改为80个,符合我们的预期。

 (5)优化多次排查同一个位置的bug

在这里相信很多人也都发现了一个bug,那就是这个坐标已经被排查过了,还重复排查的话,那win依然会++,这就是一个漏洞了。所以我们要优化这个bug

我们在这个位置加上这样一段代码即可,只要不是'*',就代表这个位置已经被查过了,利用一个continue就可以解决问题了。

 下面是运行测试

(6)排查雷代码实现如下

//排雷时候需要统计的雷个数
int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
		mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] +
		mine[x][y - 1] + mine[x][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("请输入坐标>:\n");
		scanf("%d %d", &x, &y);
		if (show[x][y] != '*')
		{
			printf("这个位置已经被排查过了,请重新输入坐标\n");
			continue;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,你赢了\n");
		DisplayBoard(mine, ROW, COL);
	}
}

四、游戏完整代码(分文件)

test.c文件

#define _CRT_SECURE_NO_WARNINGS 1

#include"game.h"
void meau()
{
	printf("*************************\n");
	printf("****** 1. 开始扫雷 ******\n");
	printf("****** 0. 退出游戏 ******\n");
	printf("*************************\n");

}
void game()
{
	printf("开始扫雷\n");
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化数组
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//打印数组
	//DisplayBoard(mine, ROW, COL);//这是用来测试时使用的
	DisplayBoard(show, ROW, COL);
	//布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);//这是用来测试时使用的
	//排查雷
	FindMine(mine, show, ROW, COL);


}
void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		meau();
		printf("请输入选项>:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

game.h文件

#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 EASY_COUNT 10

//初始化数组
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文件

#define _CRT_SECURE_NO_WARNINGS 1
#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)
{
	printf("-------扫雷--------\n");
	int i = 0;
	int j = 0;
	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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("-------扫雷--------\n");

}
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
	//雷的个数
	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 get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
		mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] +
		mine[x][y - 1] + mine[x][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("请输入坐标>:\n");
		scanf("%d %d", &x, &y);
		if (show[x][y] != '*')
		{
			printf("这个位置已经被排查过了,请重新输入坐标\n");
			continue;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,你赢了\n");
		DisplayBoard(mine, ROW, COL);
	}
}

五、完整代码展示(合并为同一个文件)

#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 EASY_COUNT 10

//初始化数组
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);
void meau()
{
	printf("*************************\n");
	printf("****** 1. 开始扫雷 ******\n");
	printf("****** 0. 退出游戏 ******\n");
	printf("*************************\n");

}
void game()
{
	printf("开始扫雷\n");
	char mine[ROWS][COLS] = { 0 };
	char show[ROWS][COLS] = { 0 };
	//初始化数组
	InitBoard(mine, ROWS, COLS, '0');
	InitBoard(show, ROWS, COLS, '*');
	//打印数组
	//DisplayBoard(mine, ROW, COL);//这是用来测试时使用的
	DisplayBoard(show, ROW, COL);
	//布置雷
	SetMine(mine, ROW, COL);
	//DisplayBoard(mine, ROW, COL);//这是用来测试时使用的
	//排查雷
	FindMine(mine, show, ROW, COL);


}
void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		meau();
		printf("请输入选项>:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}


//初始化数组
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)
{
	printf("-------扫雷--------\n");
	int i = 0;
	int j = 0;
	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 ", board[i][j]);
		}
		printf("\n");
	}
	printf("-------扫雷--------\n");

}
//布置雷
void SetMine(char board[ROWS][COLS], int row, int col)
{
	//雷的个数
	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 get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y - 1] + mine[x - 1][y] + mine[x - 1][y + 1] +
		mine[x + 1][y - 1] + mine[x + 1][y] + mine[x + 1][y + 1] +
		mine[x][y - 1] + mine[x][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("请输入坐标>:\n");
		scanf("%d %d", &x, &y);
		if (show[x][y] != '*')
		{
			printf("这个位置已经被排查过了,请重新输入坐标\n");
			continue;
		}
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				DisplayBoard(mine, ROW, COL);
				break;
			}
			else
			{
				int n = get_mine_count(mine, x, y);
				show[x][y] = n + '0';
				DisplayBoard(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,你赢了\n");
		DisplayBoard(mine, ROW, COL);
	}
}

总结

本节主要讲解了扫雷游戏的实现。这是一个经典的游戏。其中的很多细节都在里面讲到了。当然还有一些不足之处,我们在网页上的扫雷他是可以进行展开的,可以展开一片的。这一点我们本节咱不讨论。我们会放在后面的文章中将扫雷进行升级,同样的三子棋也在后面的文章中进行升级。

写文章不易,如果对你有帮助的话,不要忘记点赞加收藏哦!!!

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

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

相关文章

蓝牙耳机什么牌子好?口碑最好的蓝牙耳机品牌排行

在现代除了手机或智能手机&#xff0c;人们生活中离不开的另一件事就是“耳机”&#xff0c;尤其是对于心中有音乐的人。那么市面上的蓝牙耳机五花八门&#xff0c;尤其是陆续上新的新品&#xff0c;哪个牌子更好呢&#xff1f;以下是笔者整理的几款口碑好的蓝牙耳机&#xff0…

欧拉角与旋转矩阵

目录1. 欧拉角&#xff11;.&#xff11;欧拉角的表示&#xff11;.&#xff12;内旋和外旋1.3 欧拉角的缺点2 欧拉角到旋转矩阵的表示3 值得注意的点4. 非常感谢您的阅读&#xff01;1. 欧拉角 &#xff11;.&#xff11;欧拉角的表示 我们想描述刚体在现实世界的旋转时&…

chromedriver依赖安装失败 解决办法

1.问题描述 在使用npm下载chromedriver依赖时报错&#xff1a; chromedriver2.27.2 install: node install.js2.解决办法 第一步&#xff1a;根据报错信息中的地址&#xff0c;手动下载 chromedriver 依赖。 https://cdn.npmmirror.com/binaries/chromedriver/2.27/chromedr…

VOLTE呼叫流程介绍

VOLTE呼叫流程介绍&#xff1a; A和B均在IDLE模式&#xff0c;A用户&#xff08;主叫Caller&#xff09;呼叫B用户&#xff08;被叫Callee&#xff09;流程图&#xff1b; A、B均在MME附着&#xff0c;已在AS服务器注册&#xff1b; VOLTE呼叫业务流程 VOLTE呼叫业务流程 VOL…

[附源码]java毕业设计天悦酒店管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

java高级篇 Mybatis-Plus

目录 一、Mybatis-Plus概述 二、特性 三、快速搭建Mybatis-Plus框架 3.1 创建数据库以及表结构和数据 3.2 创建一个springboot工程并引入相关的依赖 3.3 修改配置文件 3.4 创建实体类 3.5 创建dao接口 3.6 为dao接口生成带来实现类 3.7 测试 四、使用mp完成crud操作 4.1 添加…

Linux 基础IO

目录 一、复习C文件IO相关操作 示例代码 fopen的打开模式 C标准库默认打开的三个输入输出流 理解当前路径 二、认识文件相关系统调用接口 示例代码 open函数简介 三、文件描述符 初步认识... 文件描述符的本质&#xff1a; 三个默认打开的文件 文件描述符的分配规则…

SSH客户端工具MobaXterm

前言 SSH客户端远程连接服务器的有xshell(xmanager套件下)&#xff0c;需要收费&#xff0c;也可以通过一些和谐的方式使用。 但是有时候&#xff0c;我们需要使用光明正大的软件SSH到远程服务器&#xff0c;MobaXterm家庭版可以正常的使用。 其他产品&#xff1a; SecureCRT&…

任意代码执行漏洞复现

漏洞简介 在 PostgreSQL 数据库的 jdbc 驱动程序中发现一个安全漏洞。当攻击者控制 jdbc url 或者属性时&#xff0c;使用 PostgreSQL 数据库的系统将受到攻击。 pgjdbc 根据通过 authenticationPluginClassName、sslhostnameverifier、socketFactory 、sslfactory、sslpasswo…

021_SSSS_Diffusion Models Already Have a Semantic Latent Space

Diffusion Models Already Have a Semantic Latent Space 1. Introduction 本文指出&#xff0c;现有的Diffusion模型可以在不同的领域有出色的表现&#xff0c;但是缺少可以控制其生成过程的语义隐空间&#xff08;Semantic Latent Sapce&#xff09;。本文提出了非对称的反…

C++模拟OpenGL库——图片处理及纹理系统(三):图片缩放操作:简单插值二次线性插值

目录 简单插值 二次线性插值 简单插值 如图&#xff0c;我们想把一张小图缩放成一张大图&#xff0c;自然的想法就是按照它们的长宽比例进行缩放&#xff08;zoomX&#xff09;。 但是问题也显而易见&#xff0c;在缩放的过程中&#xff0c;小图的像素并不能一一映射到大图的…

蜂巢能源冲刺科创板上市:拟募资150亿元,上半年收入37亿元

11月18日&#xff0c;蜂巢能源科技股份有限公司&#xff08;下称“蜂巢能源”&#xff09;在上海证券交易所递交招股书&#xff0c;准备在科创板上市。本次冲刺科创板上市&#xff0c;蜂巢能源计划募资150亿元&#xff0c;主要用于动力锂离子电池项目、研发中心建设项目等。 据…

Unity游戏Mod/插件制作教程02 - 开发环境准备

前言 虽然本教程的目标读者是有C#基础的玩家&#xff0c;但是作为流程&#xff0c;基础的开发软件部分我还是要记录一下。 安装VisualStudio VisualStudio是我们开发插件最重要的工具&#xff0c;也许你习惯其他开发.net的工具&#xff0c;但是免费的VisualStudio已经足够好用…

王道OS 1.1_1 操作系统的概念、功能和目标

王道OS 1.1_1 操作系统的概念、功能和目标 chap1 计算机系统概述 参考资料 B站王道考研操作系统概念 第9版 &#xff08;原书、译本&#xff09; 好久没有写博客总结整理和输出了&#xff0c;学习的惰性在一次次的考试周从零开始的经历中达到了巅峰&#xff0c;现在想重振旗鼓…

换工作有感

最近很长一段时间没有更新博客&#xff0c;更新关于vim相关的操作&#xff0c;主要是最近在忙于换工作的事情。其实本来我也没打算换工作的&#xff0c;主要是最近公司的一些骚操作让我觉得心里很不爽&#xff0c;所以一怒之下提出离职。 背景 先来说说这个事情的背景吧&#…

2022年 SecXOps 安全智能分析技术白皮书 附下载地址

近年来&#xff0c;互联网、大数据和人工智能 等技术都得到了飞速的发展&#xff0c;网络攻击的方法也越来越复杂&#xff0c;过去广泛、漫无目的的攻击威胁&#xff0c;在数年内迅速地转化为有目标、有组织、长期 潜伏的多阶段组合式高级可持续威胁&#xff08;Advanced Persi…

计算机网络——第五章网络层笔记(5)

网络地址翻译&#xff08;NAT&#xff09; Private IP address:不可路由的地址、也可用于广域网链路上 NAT&#xff1a;net address translate 私有IP地址和公有IP地址之间的转换。 PAT&#xff1a;port address translate 将多个私有IP地址影射到同一个公有IP地址的不同…

跑步时戴什么耳机好、分享五款最适合跑步的运动耳机排名清单

在进行户外跑步、骑行等运动&#xff0c;往往会感到枯燥乏味&#xff0c;很难坚持下去&#xff0c;就像我经常跑一圈就觉得没了动力&#xff0c;但是当我戴上耳机听音乐跑步时&#xff0c;不知不觉就结束了&#xff0c;就感觉时间过得很快。不过话有说回来&#xff0c;适合跑步…

【JVM】jvm的体系结构

JVM体系结构如下图所示&#xff1a; JVM大致可以分为五大模块&#xff1a; 类加载子系统&#xff08;Class Loader SubSystem&#xff09;运行时数据区&#xff08;Runtime Data Area&#xff09;执行引擎&#xff08;Execution Engine&#xff09;Java本地接口&#xff08;Ja…

Java native关键字 实现

需要用到gcc mingw64: 下载安装MinGW-w64详细步骤&#xff08;c/c的编译器gcc的windows版&#xff0c;win10真实可用&#xff09;_jjxcsdn的博客-CSDN博客_mingw-w64 我也是根据上面地址安装的 在d盘创建一个.java文件 编写内容 testInt方法用 native关键字修饰 静态块里需要…