CC++:贪吃蛇小游戏教程

news2024/12/26 11:16:18

❀创作不易,关注作者不迷路❀😀😀

目录

😀贪吃蛇简介

😃贪吃蛇的实现

🐍生成地图

🐍生成蛇模块

 ❀定义蛇的结构体

❀初始化蛇的相关信息

❀初始化食物的相关信息

🐍光标定位和隐藏

❀如何隐藏光标

❀如何定位光标

🐍蛇的移动

❀Sleep()函数:一个让程序暂停的函数

❀删除轨迹

🐍控制键盘改变蛇的移动方向

🐍吃食物获得积分

🐍蛇死亡,结束游戏

😀完整代码

😀拓展 


😀贪吃蛇简介

贪吃蛇是一款经典的小游戏,通过控制蛇头方向吃食物,使得蛇🐍变长,从而获得积分,通过上下左右键控制蛇的移动方向,寻找吃的东西,每吃到一口就能得到一定的积分,而且蛇的身子会越来越长,难度也越来越大,不能碰墙,也不能咬到自己的身体和尾巴,否则游戏结束,总体来说这款小游戏既简单又耐玩,至今仍是一款风靡全球的小游戏,也是编程入门学习的热门小游戏,今天将带领大家实现这款小游戏

😃贪吃蛇的实现

🐍生成地图

首先生成一张长为60,宽为20的地图

生成地图,只有在边界时输出“+”,其余地方输出“  ”

#define H 20
#define W 60

void show_wall()
{
	for (int i = 0; i <= H; i++)
	{
		for (int j = 0; j <= W; j++)
		{
			if (i == H || j == W)printf("+");
			else printf(" ");
		}
		puts("");
	}

}

🐍生成蛇模块

 ❀定义蛇的结构体
typedef struct body {//记录坐标
	int x; int y;
}BODY;

typedef struct snake {
	int size;//蛇的长度
	BODY list[W * H];//蛇的位置,最大可以铺满整个墙	
	BODY food;//定义BODY类型的food变量,存储食物的位置信息
	COORD coord;//光标相关的结构体,不需要自己写,是本来就有的
	int dx;//x轴移动方向 
	int dy;//y轴移动方向 
	int score;//分数 
	BODY tail;//记录尾巴的位置,后续蛇的移动需要
}SNAKE;

❀初始化蛇的相关信息

初始化时蛇的长度为2,并且在地图最中间生成蛇🐍

void  init_snake(SNAKE* snake)
{
	snake->size = 2;//初始化蛇的长度为2,头和尾长度为2
    //使蛇🐍在地图最中间生成
	snake->list[0].x = W / 2; snake->list[1].x = W / 2 - 1;
	snake->list[0].y = H / 2; snake->list[1].y = H / 2;
	snake->score = 0;//初始分数为0
	snake->dx = 1; snake->dy = 0;//初始移动方向:向右移动
	init_food(&(snake->food));//初始化食物
}
❀初始化食物的相关信息

食物在地图内随机生成,因此要调用随机数生成函数rand()

    所需头文件

#include<time.h>
void init_food(BODY* food)
{
	srand(time(NULL));
	food->x = rand() % W;
	food->y = rand() % H;
	while (food->x == 0 || food->y == 0)
	{
		food->x = rand() % W;
		food->y = rand() % H;
	}
}

生成的食物x轴范围在(0,W-1],y轴范围在(0,H-1],但仅仅对W和H取模是有可能生成在边界(x==0或y==0)的食物,因此生成时不满足条件则再次生成食物

🐍光标定位和隐藏

打印地图之后,我们看到光标在“按任意键关闭此窗口...”这里,而且在不停的闪烁,光标在地图中闪烁并不美观,所以我们需要加以隐藏光标,同时,还需要定位光标到指定位置,比如后续的蛇的移动,食物的生成都需要光标定位

❀如何隐藏光标

头文件

#include<Windows.h>
void hide_cur()//隐藏光标,里面是windows自带的函数,不需要刻意去记,也不需要自己去写,拿来就用
{
	CONSOLE_CURSOR_INFO  cci;
	cci.dwSize = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}

上面的函数是Windows自带的函数,用于隐藏光标,在不同的系统中不一样,Linux系统就跟这个不一样,因此要用的时候查找资料就好

❀如何定位光标

地图已经有了,我们发现打印完地图后,光标位置在地图之外,而蛇的初始位置是在地图中间,那么怎么办?使用光标定位,让光标定位到地图中间,然后打印蛇🐍

void show_ui(SNAKE* snake)
{
	for (int i = 0; i < snake->size; i++)
	{	//定位光标位置,windows自带函数
		snake->coord.X = snake->list[i].x; snake->coord.Y = snake->list[i].y;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
        
		if (i == 0)printf("@");//蛇头用@表示
		else printf("*");//蛇的身体用*表示
	}

    snake->coord.X = snake->food.x; snake->coord.Y = snake->food.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("#");//食物用#表示

	snake->coord.X = snake->tail.x; snake->coord.Y = snake->tail.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf(" ");
}

每一次定位光标都需要写一遍这份代码


snake->coord.X = snake->list[i].x; snake->coord.Y = snake->list[i].y;//光标x,y轴分别指向的位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);

定位光标还需要用到系统自带结构体

COORD coord;

 OK,我们运行调试一下:

成功的使光标定位在想要的位置,显示出食物和蛇🐍,但目前蛇并不能移动,我们需要让蛇🐍动起来,因此我们下一步的目标便是让蛇移动

🐍蛇的移动

对于蛇的移动,我们可以将蛇头往前移一个单位,然后蛇的身体跟着蛇头向前移动

void move_snake(SNAKE* snake)
{
	snake->tail.x = snake->list[snake->size - 1].x;
	snake->tail.y = snake->list[snake->size - 1].y;
    
    //蛇的移动,倒过来赋值
	for (int i = snake->size - 1; i > 0; i--)
	{
		snake->list[i].x = snake->list[i - 1].x;
		snake->list[i].y = snake->list[i - 1].y;
	}
   //蛇头的移动单独赋值
	snake->list[0].x += snake->dx;
	snake->list[0].y += snake->dy;
}

这里有一个小技巧,就是赋值的时候要倒着赋值,否则如果正向赋值,即蛇头的位置前进1个单位,这时候在赋值给蛇身体时,只能赋值到蛇头的位置,而其他的位置则被覆盖了,倒过来赋值,则不会出现这样的问题

此时运行结果如图,这里有两个问题,打开控制台就是一连串的*和@,因为程序的运行是很快的,在几毫秒就执行完成了,我们观察不了它如何移动的,其次,一连串的*是由于前面打印出来的*没有删除而残留下来的。接下来我们来解决这两个问题

❀Sleep()函数:一个让程序暂停的函数

程序执行打印*号是很快的,我们不想让它那么快打印,我们应该让它打印一次就停顿一小会,然后继续打印

void start_game(SNAKE* snake)
{
	while (snake->list[0].x >= 0 && snake->list[0].x <= W - 1 && snake->list[0].y >= 0 && snake->list[0].y <= H - 1)
	{
		show_ui(snake);
		control_move(snake);
		eat_food(snake);
		move_snake(snake);
		eat_snake_body(snake);
		Sleep(200);//让程序暂停200ms后再运行
	}
	game_over(snake);
}

运行结果

这一阶段,实现了打印的停顿,有了一个动态的效果,但是每次移动前面的*号没有删除,因此要删除轨迹

❀删除轨迹

如何删除轨迹,可以每一次打印*号后,光标移动到蛇尾,在蛇尾的位置打印空格,用于清除轨迹

snake->coord.X = snake->tail.x; snake->coord.Y = snake->tail.y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf(" ");

运行结果

清除了轨迹之后,蛇的移动效果便制作出来了,目前移动的方向是向右,实际还可以向上下左右移动,下一步我们就开始实现用键盘控制改变移动方向

🐍控制键盘改变蛇的移动方向

通过键盘按键改变移动方向,我们设定w(向上),s(向下),a(向左),d(向右)

void control_move(SNAKE* snake)
{
	char key = 0;
	while (_kbhit())
	{
		key = _getch();
	}
	switch (key)
	{
	case 'd':
		snake->dx = 1;
		snake->dy = 0;
		break;
	case 's':
		snake->dx = 0;
		snake->dy = 1;
		break;
	case 'a':
		snake->dx = -1;
		snake->dy = 0;
		break;
	case 'w':
		snake->dx = 0;
		snake->dy = -1;
		break;
	}
}

获取键盘按键有专门的函数_kbhit()和_getch(),当_kbhit()感应到键盘按下时,通过_getch()将获取键盘按下的值传给key

所需头文件

#include<conio.h>

然后根据方向,通过switch,case语句修改dx,dy,从而做到改变方向

🐍吃食物获得积分

吃到食物加10分,身体长度加1,然后通过随机函数再次生成新的食物

void eat_food(SNAKE* snake)
{
	if (snake->food.x == snake->list[0].x && snake->food.y == snake->list[0].y)
	{
		snake->size++;
		snake->score += 10;
		init_food(&snake->food);
	}
}

🐍蛇死亡,结束游戏

在本游戏案例中,结束游戏有两种情况:①蛇撞到墙②蛇吃到身体

蛇没撞到墙时,一直在while()循环内,撞到墙则退出循环,游戏结束

void start_game(SNAKE* snake)
{
	while (snake->list[0].x >= 0 && snake->list[0].x <= W - 1 && snake->list[0].y >= 0 && snake->list[0].y <= H - 1)
	{
		show_ui(snake);
		control_move(snake);
		eat_food(snake);
		move_snake(snake);
		eat_snake_body(snake);
		Sleep(1000);
	}
	game_over(snake);//蛇撞到墙,游戏结束
}

蛇吃到自己身体,游戏结束

蛇头的坐标和身体部位的坐标相同时代表吃到身体,通过for循环遍历寻找是否符合吃到身体这一情况

void eat_snake_body(SNAKE* snake)
{
	for (int i = 1; i < snake->size; i++)
	{
		if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y)
		{
			game_over(snake);
			exit(0);
		}
	}
}

😀完整代码

#include<stdio.h>
#include<Windows.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#define H 20
#define W 60
typedef struct body {
	int x; int y;
}BODY;

typedef struct snake {
	int size;//蛇的长度
	BODY list[W * H];//蛇的位置,最大可以铺满整个墙	
	BODY food;
	COORD coord;
	int dx;//x轴移动方向 
	int dy;//y轴移动方向 
	int score;//分数 
	BODY tail;
}SNAKE;
//展示界面 
void show_wall()
{
	for (int i = 0; i <= H; i++)
	{
		for (int j = 0; j <= W; j++)
		{
			if (i == H || j == W)printf("+");
			else printf(" ");
		}
		puts("");
	}

}
void init_food(BODY* food)
{
	srand(time(NULL));
	food->x = rand() % W;
	food->y = rand() % H;
	while (food->x == 0 || food->y == 0)
	{
		food->x = rand() % W;
		food->y = rand() % H;
	}
}
void  init_snake(SNAKE* snake)
{
	snake->size = 2;
	snake->list[0].x = W / 2; snake->list[1].x = W / 2 - 1;
	snake->list[0].y = H / 2; snake->list[1].y = H / 2;
	snake->score = 0;
	snake->dx = 1; snake->dy = 0;
	init_food(&(snake->food));
}
void hide_cur()//隐藏光标,里面是windows特有的函数,不需要刻意去记,拿来就用
{
	CONSOLE_CURSOR_INFO  cci;
	cci.dwSize = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
void show_ui(SNAKE* snake)
{
	for (int i = 0; i < snake->size; i++)
	{	//定位光标位置,windows自带函数
		snake->coord.X = snake->list[i].x; snake->coord.Y = snake->list[i].y;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
		if (i == 0)printf("@");
		else printf("*");
	}
	snake->coord.X = snake->food.x; snake->coord.Y = snake->food.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("#");

	snake->coord.X = snake->tail.x; snake->coord.Y = snake->tail.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf(" ");
}
void move_snake(SNAKE* snake)
{
	snake->tail.x = snake->list[snake->size - 1].x;
	snake->tail.y = snake->list[snake->size - 1].y;
	for (int i = snake->size - 1; i > 0; i--)
	{
		snake->list[i].x = snake->list[i - 1].x;
		snake->list[i].y = snake->list[i - 1].y;
	}
	snake->list[0].x += snake->dx;
	snake->list[0].y += snake->dy;
}
void control_move(SNAKE* snake)
{
	char key = 0;
	while (_kbhit())
	{
		key = _getch();
	}
	switch (key)
	{
	case 'd':
		snake->dx = 1;
		snake->dy = 0;
		break;
	case 's':
		snake->dx = 0;
		snake->dy = 1;
		break;
	case 'a':
		snake->dx = -1;
		snake->dy = 0;
		break;
	case 'w':
		snake->dx = 0;
		snake->dy = -1;
		break;
	}
}
void eat_food(SNAKE* snake)
{
	if (snake->food.x == snake->list[0].x && snake->food.y == snake->list[0].y)
	{
		snake->size++;
		snake->score += 10;
		init_food(&snake->food);
	}
}
void game_over(SNAKE* snake)
{
	snake->coord.X = 30; snake->coord.Y = 25;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("游戏结束!!! 得分:%d", snake->score);
	system("pause");
}
void eat_snake_body(SNAKE* snake)
{
	for (int i = 1; i < snake->size; i++)
	{
		if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y)
		{
			game_over(snake);
			exit(0);
		}
	}
}
void start_game(SNAKE* snake)
{
	while (snake->list[0].x >= 0 && snake->list[0].x <= W - 1 && snake->list[0].y >= 0 && snake->list[0].y <= H - 1)
	{
		show_ui(snake);
		control_move(snake);
		eat_food(snake);
		move_snake(snake);
		eat_snake_body(snake);
		Sleep(300);
	}
	game_over(snake);
}

int main()
{

	hide_cur();
	SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));
	init_snake(snake);
	show_wall();
	show_ui(snake);
	start_game(snake);

	free(snake);
	system("pause");

	return 0;
}

😀拓展 

可以实现障碍物,新增关卡等等,以及图形化界面,提升难度,下列代码展示了增加障碍物


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#include<conio.h>

/*
注意:
w:上移
s:下移
a:左移
d:右移
不可以用getchar()来进行控制,getchar()之后要有回车才行,而我们只希望通过wsad这些按键进行操作
但有专门的按键操作函数
#include<conio.h>
char key;//key要给初始值,否则key没值,进不了循环,但初始值也不能是wasd等
while(_kbhit())//判断是否按下按键,按下不等于0
{
   key=_getch();
}
*/

char temp;
//1.设置地图边界
#define W 60
#define H 20

//2.设置贪吃蛇结构体
typedef struct _body {
	int x; //坐标x
	int y; //坐标y
}BODY;

typedef struct snake{
	BODY list[W * H];//贪吃蛇最大占满整个地图
	int size;//实际身体个数,蛇头(@)和蛇身蛇尾(*)
	BODY food;//食物,#
	COORD coord;//(定位光标)的坐标,显示
	int dx;//移动方向
	int dy;//移动方向
	BODY tail;//记录蛇尾,用于清除蛇尾痕迹 
	int score;//分数
	BODY disability;
}SNAKE;

//3.实现显示地图,初始化蛇函数,初始化食物函数

void test_ui()
{
	for (int i = 0; i < H; i++)
	{
		for (int j = 0; j < W; j++)
			printf("=");
		printf("\n");
	}
}
void disability_snake(BODY* disability)
{
	Sleep(5);
	//设置障碍物坐标
	disability->x = rand() % W;
	disability->y = rand() % H;

	while (disability->x == 0 || disability->x == W - 1 || disability->y == 0 || disability->y == H - 1)
	{
		disability->x = rand() % W;
		disability->y = rand() % H;
	}
	
}
void init_food(BODY* food)
{
	//设置随机数种子
	srand(time(NULL));
	//设置食物坐标
	food->x = rand()% W;//[0,W-1],注意%的操作很巧妙
	food->y = rand() % H;//[0,H-1]

	while(food->x == 0 || food->x == W - 1 || food->y == 0 || food->y == H - 1)
	{
		food->x = rand() % W;
		food->y = rand() % H;
	}

}
void init_snake(SNAKE* snake)//初始化
{
	snake->list[0].x = W / 2;
	snake->list[0].y = H / 2;
	snake->list[1].x = W / 2 - 1;
	snake->list[1].y = H / 2;//这里老师写成H/2-1应该是错的
	snake->size = 2;//初始时蛇的长度为2,因为有头有尾

	//设置移动方向
	snake->dx = 1;//默认移动方向向右
	snake->dy = 0;//默认移动方向向左
	
	snake->score = 0;
	init_food(&snake->food);
	disability_snake(&snake->disability);
	while (snake->food.x == snake->disability.x && snake->food.y == snake->disability.y)
	{
		init_food(&snake->food);
		disability_snake(&snake->disability);
	}
};

void show_ui(SNAKE* snake)
{
	//显示蛇
	for (int i = 0; i < snake->size; i++)
	{   
		snake->coord.X = snake->list[i].x;//这个函数是在显示地图后执行的,画完地图后光标是在地图之外的,用这个函数可以重置光标位置,让光标放到我们想要的地方
		snake->coord.Y = snake->list[i].y;
		//定位光标位置,windows自带函数
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
		if (i == 0) {//显示蛇头
			printf("@");
		}
		else{//显示蛇身和蛇尾
			printf("*");
		}
	}
	//显示食物
	snake->coord.X = snake->food.x;
	snake->coord.Y = snake->food.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("#");

	//显示障碍物
	snake->coord.X = snake->disability.x;
	snake->coord.Y = snake->disability.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("?");

	//清除蛇尾的痕迹,否则一连串的*
	snake->coord.X = snake->tail.x;
	snake->coord.Y = snake->tail.y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf(" ");
}
void show_wall()//展示墙
{
	for (int i = 0; i <=H; i++)
	{
		for (int j = 0; j <=W; j++)
		{
			if (i == H || j == W)printf("+");
			else printf(" ");
		}
		puts("");
	}
}

void hide_cur()//隐藏光标,里面是windows特有的函数,不需要刻意去记,拿来就用
{
	CONSOLE_CURSOR_INFO  cci;
	cci.dwSize = sizeof(cci);
	cci.bVisible = FALSE;
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}

void move_snake(SNAKE* snake)
{   
	//记录蛇尾,清除痕迹
	snake->tail = snake->list[snake->size - 1];
	//蛇身的移动,算法逻辑从后往前赋值
	//蛇头的移动,单独赋值
	for (int i = snake->size - 1; i > 0; i--)
	{
		snake->list[i] = snake->list[i - 1];
    }
	snake->list[0].x += snake->dx;
	snake->list[0].y += snake->dy;
}
void control_snake(SNAKE* snake)
{
	char key = 0;
	while (_kbhit())//检测到按下按键
	{
		if (temp == 'w' && _kbhit() == 's')key = temp;
		else if (temp == 's' && _kbhit() == 'w')key = temp;
		else if (temp == 'a' && _kbhit() == 'd')key = temp;
		else if (temp == 'd' && _kbhit() == 'a')key = temp;
		else key = _getch();
	}
	//循环之外,抬起按下动作,或没有按下动作
	//根据按键,修改移动方向
	temp = key;
	switch (key)
	{
	case 'w':
		snake->dy = -1;
		snake->dx = 0;
		break;
	case 's':
		snake->dy = 1;
		snake->dx = 0;
		break;
	case 'a':
		snake->dy = 0;
		snake->dx = -1;
		break;
	case 'd':
		snake->dy = 0;
		snake->dx = 1;
	}
	
}

void snake_eat(SNAKE* snake)
{
	//判断是否吃到食物
	if (snake->list[0].x == snake->food.x && snake->list[0].y == snake->food.y)
	{
		//吃到食物,身体加长,食物消失,重新生成新的食物
		snake->size++;//食物消失也不用重新写,因为一旦生成了食物原来的地方就消失了
		snake->coord.X = snake->disability.x;
		snake->coord.Y = snake->disability.y;
		SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
		printf(" ");
		init_food(&(snake->food));		
		disability_snake(&snake->disability);
		printf(" ");
		while (snake->food.x == snake->disability.x && snake->food.y == snake->disability.y)
		{
			init_food(&snake->food);
			disability_snake(&snake->disability);
		}
		snake->score += 10;
	}
	
}
void game_over(SNAKE* snake)//游戏结束,指定到具体位置打印游戏结束
{
	snake->coord.X = 40;
	snake->coord.Y = 25;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
	printf("游戏结束  总分数:%d", snake->score);
	system("pause");
}
void snake_eat_body(SNAKE* snake)
{
	for (int i = 1; i < snake->size; i++)
	{
		if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y)
		{
			game_over(snake);//吃到身体;游戏结束
			
			exit(0);
		}
	}
}
void snake_push_disability(SNAKE* snake)
{
	if (snake->disability.x == snake->list[0].x && snake->disability.y == snake->list[0].y)
	{
		game_over(snake);
		exit(0);
	}
}
void start_game(SNAKE* snake)
{
	while (snake->list[0].x >=0 && snake->list[0].x < W &&
		snake->list[0].y>=0 && snake->list[0].y < H)//在范围内移动
	{   
		
		//显示蛇和食物
		show_ui(snake);

		//控制移动方向
		control_snake(snake);
		
		//蛇吃到食物
		snake_eat(snake);

		//蛇吃到身体
		snake_eat_body(snake);
		
		//蛇撞到障碍物
		snake_push_disability(snake);

		//移动蛇
		move_snake(snake);

		//延迟300ms
	    Sleep(100);
		
		
	}
	game_over(snake);//碰到墙壁,游戏结束
}

int main(int argc,char *argv[])
{
	hide_cur();//隐藏光标
	SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));//创建空间
	init_snake(snake);
	//显示地图边界
	show_wall();
	//显示蛇和食物
	show_ui(snake);
	//启动游戏
	start_game(snake);

	free(snake);//释放空间
	//while (1);//先不让程序结束,就暂时不显示程序结束的那段字
	
	return 0;
}

 

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

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

相关文章

【zabbix6自定义监控带参数】

目录 一、环境准备二、选择监控的数据三、在zabbix_server主机测试四、在web界面上配置监控项五、在web界面上添加触发器 一、环境准备 注意&#xff1a;避免一些问题&#xff0c;可以把防火墙&#xff0c;selinux都关闭 安装zabbix-sever&#xff1a;https://blog.csdn.net/q…

等保测评练习卷25

等级保护初级测评师试题25 姓名&#xff1a; 成绩&#xff1a; 一、判断题&#xff08;10110分&#xff09; 1.安全区域边界对象主要根据系统中网络访问控制设备的部署情况来确定&#xff08;&#xff09;不是网络访问控制设备而…

zero - hackmyvm

简介 靶机名称&#xff1a;Zero 难度&#xff1a;简单 靶场地址&#xff1a;https://hackmyvm.eu/machines/machine.php?vmZero 本地环境 虚拟机&#xff1a;vitual box 靶场IP&#xff08;Zero&#xff09;&#xff1a;未知 windows_IP&#xff1a;192.168.130.158 k…

Vulnhub靶场DC-9练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 发现SQL注入点2. Sqlmap跑数据3. 文件包含4. SSH爆破端口敲门服务5. 提权&#xff08;写入/etc/passwd&#xff09; 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-9.z…

数据化项目中如何优化数据分析报表的响应速度

引言&#xff1a;在数据化项目中&#xff0c;优化数据分析报表的响应速度是一个关键任务&#xff0c;它直接影响到用户的体验和决策效率。以下是一些有效的策略和方法来优化数据分析报表的响应速度&#xff1a; 一.从IAAS层优化&#xff1a; 硬件与网络资源优化&#xff1a;提…

无法读取配置节“dataConfiguration”

无法读取配置节“dataConfiguration”&#xff0c;因为它缺少节声明 问题 在web.config中加了<dataConfiguration defaultDatabase"DefaultDB" />&#xff0c;服务器运行报无法读取配置节“dataConfiguration” 分析检查配置文件&#xff1a; Web.config…

前端常用的【设计模式】和使用场景

设计原则 最重要的&#xff1a;开放封闭原则 对扩展开放对修改封闭 工厂模式 用一个工厂函数&#xff0c;来创建实例&#xff0c;隐藏 new 如 jQuery 的 $ 函数&#xff0c;React 的 createElement 函数 单例模式 全局唯一的实例(无法生成第二个) 如 Vuex 和 Redux 的 store…

基于设备上解码的 Yolo 检测

什么是NDVI&#xff1f; 该存储库 ( 修改自 device-decoding) 包含直接使用 DepthAI SDK (main_sdk.py) 或 DepthAI API (main_api.py) 在设备上解码运行 Yolo 目标检测的代码。目前&#xff0c;支持的版本有&#xff1a;YoloV3 & YoloV3-tiny,YoloV4 & YoloV4-tiny,Y…

滑动窗口大总结!!!妈妈以后再也不担心我不会做滑动窗口啦~

写在前面&#xff1a;全部题都源于力扣 讲解题目一&#xff1a;最小覆盖子串题目二&#xff1a;字符串排列题目三&#xff1a;找所有字母异位词题目四&#xff1a;无重复字符的最长子串题目五&#xff1a;滑动窗口的最大值 讲解 滑动窗口算法技巧主要用来解决子数组问题&#…

B 端产品设计:导航系统构建指南

两年前写的一篇关于导航菜单的文章帮助许多学生进入 B 端设计领域。然而&#xff0c;两年过去了&#xff0c;行业在不断发展&#xff0c;文章中的许多观点并不适用于当前的 B 端设计环境。如今的 B 端设计越来越受到重视&#xff0c;所以最近打算深入挖掘之前不太过时的文章内容…

strimzi operator 部署kafka集群(可外部访问)

Strimzi介绍 官方文档:https://strimzi.io/docs/operators/0.42.0/overview#kafka-components_str Strimzi介绍 Strimzi 是一个用于 Apache Kafka 在 Kubernetes 上部署和管理的开源项目。它提供了一组 Kubernetes 自定义资源定义(Custom Resource Definitions,CRDs)、控制…

充电宝有必要买贵的吗?充电宝可以带上高铁吗?充电宝选购方法

市面上的充电宝可以说是非常的多&#xff0c;但是能选到一款适合自己的充电宝基本是不容易的&#xff0c;然而&#xff0c;当我们准备选购充电宝时&#xff0c;常常会面临诸多疑问。其中&#xff0c;“充电宝有必要买贵的吗”就是一个备受关注的问题。价格似乎成为了我们在众多…

[Git][认识Git]详细讲解

目录 1.什么是仓库&#xff1f;2.认识工作区、暂存区、版本库3.认识 .git1.index2.HEAD && master3.objects4.总结 1.什么是仓库&#xff1f; 仓库&#xff1a;进⾏版本控制的⼀个⽂件⽬录 2.认识工作区、暂存区、版本库 工作区&#xff1a;在电脑上写代码或⽂件的⽬录…

【C++】C++应用案例-通讯录管理系统

目录 一、整体介绍 1.1、需求和目标 1.2、整体功能描述 二、页面及功能描述 2.1 主菜单 2.2 添加联系人菜单 2.3 显示联系人菜单 2.4 修改联系人菜单 2.5 退出功能 三、流程设计 3.1 主流程 3.2 添加操作流程 3.3 显示联系人操作流程 3.4 修改联系人操作流程 四…

V.PS荷兰阿姆斯特丹VPS详细测评

V.PS怎么样&#xff1f; V.PS的荷兰VPS位于荷兰阿姆斯特丹数据中心&#xff0c;实际的网络从测评的数据来看&#xff1a;电信走的CN2 GIA/AS4809网络、联通走的是CUII/AS9929网络、移动走的是CUII/AS9929网络&#xff0c;也就是说三网都是走的运营商的轻负载线路。 默认的CPU型…

c/c++自增运算符

自增运算符在前&#xff1a;先自增再取值 自增运算符在后&#xff1a;先取值再自增 如图&#xff1a; lptmp等于tmp&#xff0c;但是t等于128&#xff0c;也就说&#xff0c;当位于后面时&#xff0c;先取值&#xff0c;再自增。

数论第四节:二元一次不定方程、勾股数

不定方程定义 解不确定的方程称为不定方程。一般化的定义为&#xff1a;不定方程是指未知数的个数多余方程的个数&#xff0c;或未知数受到某种限制&#xff08;如整数、正整数等&#xff09;的方程和方程组。 二元一次不定方程定义 形如axbyc的形式的方程。其中a,b不等于0&…

python print 函数参数:sep 自定义分隔符,end 自定义结尾符

1. 简述 print 函数可以将内容打印到标准输出&#xff0c;如果不指定 end 参数&#xff0c;默认在输出的内容之后加一个 “回车符\n”。 以下是 print 函数常用的参数用法&#xff1a; print(object, …, sepstr, endstr) object, …&#xff1a;要打印的内容&#xff0c;可以…

如何基于欧拉系统完成第三方软件仓库的安装

首先&#xff0c;我们需要写一个镜像脚本 rootlocalhost yum.repos.d]# vim docker-ce.repo内容如下 [docker-ce] namedocker baseurlhttps://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/rhel/9/x86_64/stable/ //我们使用的是清华的镜像源 gpgcheck0 tips:这里告诉大家一…

来点八股文(五) 分布式和一致性

Raft raft 会进入脑裂状态吗&#xff1f;描述下场景&#xff0c;怎么解决&#xff1f; 不会。raft通过选举安全性解决了这个问题&#xff1a; 一个任期内&#xff0c;follower 只会投票一次票&#xff0c;且先来先得&#xff1b;Candidate 存储的日志至少要和 follower 一样新…