【C语言】C语言经典小游戏:贪吃蛇(下)

news2025/7/24 2:56:46

文章目录

  • 一、游戏前准备
  • 二、游戏开始
    • 1、游戏开始函数(GameStart)
      • 1)打印欢迎界⾯(WelcomeToGame)
      • 2)创建地图(CreateMap)
      • 3)初始化蛇⾝(InitSnake)
      • 4)创建⻝物(CreateFood)
  • 三、游戏运⾏
    • 1、准备工作
      • 1)帮助信息(PrintHelpInfo)
      • 2)判断按键状态(宏KEY_PRESS)
      • 3)暂停(Pause)
    • 2、游戏运行函数(GameRun)
      • 1)蛇移动(SnakeMove)
        • 1.a)下一个节点是否是食物(NextIsFood)
        • 1.b)是食物(EatFood)
        • 1.c)不是食物(NoFood)
        • 1.d)撞墙(KillByWall)
        • 1.e)撞到自身(KillBySelf)
  • 四、游戏结束
    • 1、游戏结束函数(GameEnd)

一、游戏前准备

我们首先需要创建三个文件:
Snake.h:结构体、枚举的定义,方法的声明。
Snake.c:方法的实现。
test.c:方法的测试。

首先先在Snake.h文件中定义贪吃蛇的结构体、枚举、以及包含的头文件和各种方法的声明:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<stdbool.h>
#include<time.h>

#define POS_X 24
#define POS_Y 5
#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'

//蛇的方向
enum DIRECTION
{
	UP = 1,//1
    DOWN,//2
    LEFT,//3
    RIGHT//4
};

//蛇的状态
enum GAME_STATUS
{
	OK,//正常运行  0
	KILL_BY_WALL,//撞墙 1
	KILL_BY_SELF,//咬到自己 2
	END_NORMAL//正常结束 3
};

//蛇身的节点
typedef struct SnakeNode
{
	//坐标
	int x;
	int y;
	//指向下一个节点的指针
	struct SnakeNode* next;
}SnakeNode, * pSnakeNode;


//贪吃蛇
typedef struct Snake
{
	pSnakeNode _pSnake;//指向蛇头的指针
	pSnakeNode _pFood;//指向食物节点的指针
	enum DIRECTION _dir;//蛇的方向
	enum GAME_STATUS _status;//游戏的状态
	int _food_weight;//一个食物的分数
	int _score;//总成绩
	int _sleep_time;//休息时间,时间越短,速度越快
}Snake, * pSnake;


//定位光标的位置
void SetPos(short x, short y);

//游戏的初始化
void GameStart(pSnake ps);

//欢迎界面
void WelcomeToGame();

//创建地图
void CreateMap();

//初始化蛇身
void InitSnake(pSnake ps);	

//游戏运行的逻辑
void GameRun(pSnake ps);

//蛇的移动(走一步)
void SnakeMove(pSnake ps);

//判断下一个坐标是否是食物
int NextIsFood(pSnakeNode pn,pSnake ps);

//下一个位置是食物,就吃掉食物
void EatFood(pSnakeNode pn, pSnake ps);

//下一个位置不是食物
void NoFood(pSnakeNode pn, pSnake ps);

//检测蛇是否撞墙
void KillByWall(pSnake ps);

//检测蛇是否撞到自己
void KillBySelf(pSnake ps);

//游戏善后的工作
void GameEnd(pSnake ps);

接着我们再在Snake.c文件中编写定位光标位置的方法:

void SetPos(short x, short y)
{
	//取得坐标
	COORD pos = { x,y };
	//获得输出句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	//设置光标位置
	SetConsoleCursorPosition(hOutput, pos);
}

然后再进入test.c文件设置程序⽀持本地模式,并进⼊游戏的主逻辑。
主逻辑分为3个过程:

  • 游戏开始(GameStart):完成游戏的初始化。
  • 游戏运⾏(GameRun):完成游戏运⾏逻辑的实现。
  • 游戏结束(GameEnd):完成游戏结束的说明,实现资源释放。
#include<locale.h>
#include"Snake.h"

void test()
{
	int ch = 0;
	do
	{
		system("cls");
		//创建贪吃蛇
		Snake snake = { 0 };
		//初始化游戏
		//1.打印环境界面和功能介绍
		//2.绘制地图
		//3.创建蛇
		//4.创建食物
		//5.设置游戏的相关信息
		GameStart(&snake);

		//运行游戏
		GameRun(&snake);

		//结束游戏
		GameEnd(&snake);

		SetPos(20, 15);
		printf("再来一局吗!(Y/N):");
		ch = getchar();
		while (getchar() != '\n');//清理\n
	} while (ch == 'Y' || ch == 'y');
	SetPos(0, 27);
}

int main()
{
	//设置适配本地环境
	setlocale(LC_ALL, "");
	srand((unsigned int)time(NULL));
	test();

	return 0;
}

二、游戏开始

1、游戏开始函数(GameStart)

这个模块完成游戏的初始化任务:

  • 控制台窗⼝⼤⼩的设置。
  • 控制台窗⼝名字的设置。
  • ⿏标光标的隐藏。
  • 打印欢迎界⾯。
  • 创建地图。
  • 初始化蛇。
  • 创建第⼀个⻝物。

我们先在Snake.c文件中创建游戏开始的函数GameStart

void GameStart(pSnake ps)
{
	//设置窗口大小和名字
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");

	//获得输出句柄
	HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	//获得光标属性
	CONSOLE_CURSOR_INFO CursorInfo;	
	GetConsoleCursorInfo(houtput, &CursorInfo);
	//隐藏光标
	CursorInfo.bVisible = false;
	//设置光标属性
	SetConsoleCursorInfo(houtput, &CursorInfo);

	//打印欢迎界面
	WelcomeToGame();

	//绘制地图
	CreateMap();

	//创建蛇
	InitSnake(ps);

	//创建食物
	CreateFood(ps);
}

然后再在test.c中进行测试:

void test()
{
	Snake snake = { 0 };
	GameStart(&snake);	
	
	getchar();//暂停程序执行,等待用户输入
}

int main()
{
	test();
	return 0;
}

运行结果:
在这里插入图片描述
可以看到此时窗口的大小和名字已经被成功设置,并且光标也被隐藏了。

接着就可以在GameStart函数中调用其他函数的方法。

1)打印欢迎界⾯(WelcomeToGame)

在游戏正式开始之前,做⼀些功能提醒。

欢迎界面函数:

void WelcomeToGame()
{
	SetPos(40, 14);
	wprintf(L"欢迎来到贪吃蛇小游戏\n");

	SetPos(42, 20);
	system("pause");//等待用户按任意键

	system("cls"); //清屏

	SetPos(25, 14);
	wprintf(L"用↑.↓.←.→来控制蛇的移动,按F3加速,F4减速\n");

	SetPos(25, 15);
	wprintf(L"加速能够得到更高的分数\n");

	SetPos(42, 20);
	system("pause");

	system("cls");
}

再进行测试:

void test()
{
	Snake snake = { 0 };
	GameStart(&snake);	

	getchar();
}

int main()
{
	//设置为本地环境
	setlocale(LC_ALL,"");
	test();
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2)创建地图(CreateMap)

创建地图就是将墙打印出来,因为是宽字符打印,所以使⽤wprintf函数,打印格式串前使⽤L。打印地图的关键是要算好坐标,才能在想要的位置打印墙体。

墙体打印的宽字符先在Snake.h文件中进行宏定义。

#define WALL L'□' 

易错点: 就是坐标的计算
上:(0,0)到(56,0)
下:(0,26)到(56,26)
左:(0,1)到(0,25)
右:(56,1)到(56,25)

创建地图函数:

void CreateMap()
{
	//上
	for (int i = 0; i < 29; i++)
	{
		wprintf(L"%lc", WALL);//一个宽字符占2格横坐标
	}
	//下
	SetPos(0, 26);
	for (int i = 0; i < 29; i++)
	{
		wprintf(L"%lc", WALL);
	}
	//左
	for (int i = 1; i <= 25; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc", WALL);
	}
	//右
	for (int i = 1; i <= 25; i++)
	{
		SetPos(56, i);
		wprintf(L"%lc", WALL);
	}
}

再进行测试:

void test()
{
	Snake snake = { 0 };
	GameStart(&snake);	

	getchar();
}

int main()
{
	//设置为本地环境
	setlocale(LC_ALL,"");
	test();
	return 0;
}

运行结果:
在这里插入图片描述

3)初始化蛇⾝(InitSnake)

蛇最开始⻓度为5节,每节对应链表的⼀个节点,蛇⾝的每⼀个节点都有⾃⼰的坐标。

  • 创建5个节点,然后将每个节点存放在链表中进⾏管理。
  • 创建完蛇⾝后,将蛇的每⼀节打印在屏幕上。
  • 蛇的初始位置从(24,5)开始

需要将初始位置在Snake.h文件中进行宏定义:

#define POS_X 24
#define POS_Y 5

设置蛇的属性:

  • 游戏状态是:OK
  • 蛇的移动速度:200毫秒
  • 蛇的默认⽅向:RIGHT
  • 初始成绩:0
  • 每个⻝物的分数:10

蛇⾝打印的宽字符也在Snake.h文件中进行宏定义:

#define BODY L'●' 

初始化蛇⾝函数:

void InitSnake(pSnake ps)
{
	//当前开辟的蛇节点的指针
	pSnakeNode cur = NULL;

	//开辟5个节点
	for (int i = 0; i < 5; i++)
	{
		//开辟空间
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		//如果开辟失败
		if (cur == NULL)
		{
			perror("InitSnake()::malloc()");
			return;
		}
		cur->next = NULL;
		cur->x = POS_X + 2 * i;
		cur->y = POS_Y;

		//头插法插入链表
		//空链表
		if (ps->_pSnake == NULL)
		{
			ps->_pSnake = cur;
		}
		//非空
		else
		{
			cur->next = ps->_pSnake;
			ps->_pSnake = cur;
		}
	}

	//打印蛇身
	cur = ps->_pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}

	//设置蛇的属性
	ps->_status = OK;
	ps->_sleep_time = 200;//毫秒
	ps->_dir = RIGHT;
	ps->_score = 0;
	ps->_food_weight = 10;
}

再进行测试:

void test()
{
	Snake snake = { 0 };
	GameStart(&snake);	

	getchar();
}

int main()
{
	//设置为本地环境
	setlocale(LC_ALL,"");
	test();
	return 0;
}

运行结果:
在这里插入图片描述

4)创建⻝物(CreateFood)

  • 先随机⽣成⻝物的坐标
    • x坐标必须是2的倍数
    • ⻝物的坐标不能和蛇⾝任意节点的坐标重复
  • 创建⻝物节点,打印⻝物

⻝物打印的宽字符在Snake.h文件中进行宏定义:

#define FOOD L'★'

创建⻝物的函数:

void CreateFood(pSnake ps)
{
	//先随机生成食物的坐标
	int x = 0;
	int y = 0;
	again:
	do
	{
		x = rand() % 53 + 2;  //x:2~54
		y = rand() % 25 + 1;  //y:1~25

	} while (x % 2 != 0);

	//食物坐标不能和蛇身体坐标冲突
	pSnakeNode cur = ps->_pSnake;//指向蛇头的指针
	while (cur)
	{
		//随机生成的坐标冲突了就重新生成
		if (x == cur->x && y == cur->y)
		{
			goto again;
		}
		cur = cur->next;
	}

	//创建食物节点
	pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pFood == NULL)
	{
		perror("CreateFood()::malloc()");
		return;
	}
	pFood->x = x;
	pFood->y = y;
	pFood->next = NULL;

	//打印食物节点
	SetPos(x, y);
	wprintf(L"%lc", FOOD);

	ps->_pFood = pFood;//食物节点地址赋值给_pFood
}

再进行测试:

void test()
{
	Snake snake = { 0 };
	GameStart(&snake);	

	getchar();
}

int main()
{
	//设置为本地环境
	setlocale(LC_ALL,"");
	test();
	return 0;
}

运行结果:
在这里插入图片描述

三、游戏运⾏

在完成了游戏开始部分后,现在我们开始进入游戏运行的部分。

1、准备工作

1)帮助信息(PrintHelpInfo)

游戏运⾏期间,右侧需要打印帮助信息,提⽰玩家。

帮助信息函数:

void PrintHelpInfo()
{
	SetPos(64, 14);
	wprintf(L"%ls", L"不能穿墙,不能咬到自己");

	SetPos(64, 15);
	wprintf(L"%ls", L"用↑.↓.←.→来控制蛇的移动");

	SetPos(64, 16);
	wprintf(L"%ls", L"按F3加速,F4减速");

	SetPos(64, 17);
	wprintf(L"ls", L"按Esc退出游戏,按空格暂停游戏");

	SetPos(64, 19);
	wprintf(L"ls", L"《怀旧》制作");
}

运行结果:
在这里插入图片描述

2)判断按键状态(宏KEY_PRESS)

根据游戏状态检查游戏是否继续,如果是状态是OK,游戏继续,否则游戏结束。
如果游戏继续,就检测按键情况,确定蛇下⼀步的⽅向,或者是否加速减速,是否暂停或者退出游戏。

因此我们还需要判断按键使用情况,通过宏定义来实现:

#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

需要的虚拟按键的罗列:

  • 上:VK_UP
  • 下:VK_DOWN
  • 左:VK_LEFT
  • 右:VK_RIGHT
  • 空格:VK_SPACE
  • ESC:VK_ESCAPE
  • F3:VK_F3
  • F4:VK_F4

3)暂停(Pause)

当我们按空格键之后,游戏要能达到暂停的效果。

暂停函数:

void Pause()
{
	while (1)
	{
		Sleep(200);
		if (KEY_PRESS(VK_SPACE))
		{
			break;
		}
	}
}

2、游戏运行函数(GameRun)

接着再在Snake.c文件中创建游戏运行的函数GameRun

void GameRun(pSnake ps)
{
	//打印帮助信息
	PrintHelpInfo();

	//游戏主体
	do
	{
		//打印总分数和食物分
		SetPos(64, 10);
		printf("总分数:%d\n", ps->_score);
		SetPos(64, 11);
		printf("当前食物的分数:%2d\n", ps->_food_weight);

		//检测按键
		//上
		if (KEY_PRESS(VK_UP) && ps->_dir != DOWN)//按上键时蛇方向不能为下
		{
			ps->_dir = UP;
		}
		//下
		else if (KEY_PRESS(VK_DOWN) && ps->_dir != UP)
		{
			ps->_dir = DOWN;
		}
		//左
		else if (KEY_PRESS(VK_LEFT) && ps->_dir != RIGHT)
		{
			ps->_dir = LEFT;
		}
		//右
		else if (KEY_PRESS(VK_RIGHT) && ps->_dir != LEFT)
		{
			ps->_dir = RIGHT;
		}
		//空格(暂停)
		else if (KEY_PRESS(VK_SPACE))
		{
			Pause();
		}
		//Esc(正常退出游戏)
		else if (KEY_PRESS(VK_ESCAPE))
		{
			ps->_status = END_NORMAL;
		}
		//F3(加速)
		else if (KEY_PRESS(VK_F3))
		{
			//休息时间如果大于80  休息时间减少30   一个食物的分数加2
			if (ps->_sleep_time > 80)
			{
				ps->_sleep_time -= 30;
				ps->_food_weight += 2;
			}
		}
		//F4(减速)
		else if (KEY_PRESS(VK_F4))
		{
			//一个食物的分数如果大于2  休息时间增加30  一个食物的分数-2
			if (ps->_food_weight > 2)
			{
				ps->_sleep_time += 30;
				ps->_food_weight -= 2;
			}
		}

		//蛇的移动
		SnakeMove(ps);

		//休眠时间
		Sleep(ps->_sleep_time);

	} while (ps->_status == OK);
}

再进行测试:

void test()
{
	Snake snake = { 0 };
	GameStart(&snake);	

	GameRun(&snake);
	getchar();
}

int main()
{
	//设置为本地环境
	setlocale(LC_ALL,"");
	srand((unsigned int)time(NULL));//确保食物产生的坐标是真正随机的
	test();
	return 0;
}

运行结果:
在这里插入图片描述

1)蛇移动(SnakeMove)

  • 先创建下⼀个节点,根据移动⽅向和蛇头的坐标,得到蛇移动到下⼀个位置的坐标。
  • 看下⼀个位置是否是⻝物,是⻝物就做吃⻝物处理。
  • 如果不是⻝物则做前进⼀步的处理。
  • 蛇⾝移动后,判断是否会撞墙或者撞上⾃⼰蛇⾝,从⽽影响游戏的状态。

蛇移动函数:

void SnakeMove(pSnake ps)
{
	//创建蛇即将到的下一个节点  
	pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pNextNode == NULL)
	{
		perror("SnakeMove()::malloc()");
		return;
	}

	//蛇即将到的下一个节点的坐标
	//根据方向和蛇头坐标来得到
	switch (ps->_dir)
	{
	//上
	case UP:
		pNextNode->x = ps->_pSnake->x;
		pNextNode->y = ps->_pSnake->y - 1;
		break;
	//下
	case DOWN:
		pNextNode->x = ps->_pSnake->x;
		pNextNode->y = ps->_pSnake->y + 1;
		break;
	//左
	case LEFT:
		pNextNode->x = ps->_pSnake->x - 2;
		pNextNode->y = ps->_pSnake->y;
		break;
	//右
	case RIGHT:
		pNextNode->x = ps->_pSnake->x + 2;
		pNextNode->y = ps->_pSnake->y;
		break;
	}

	//检测下一个节点是否是食物
	if (NextIsFood(pNextNode, ps))
	{
		//是食物
		EatFood(pNextNode, ps);
	}
	else
	{
		//不是食物
		NoFood(pNextNode, ps);
	}

	//检测蛇是否撞墙
	KillByWall(ps);

	//检测蛇是否撞到自己
	KillBySelf(ps);
}

1.a)下一个节点是否是食物(NextIsFood)

判断传入的节点 pn的坐标是否与食物坐标相同。

下一个节点是否是食物函数:

int NextIsFood(pSnakeNode pn, pSnake ps)
{
	return (ps->_pFood->x == pn->x && ps->_pFood->y == pn->y);
}
1.b)是食物(EatFood)

是食物函数:

void EatFood(pSnakeNode pn, pSnake ps)
{
	//头插法
	//食物节点成为新的蛇头
	ps->_pFood->next = ps->_pSnake;
	ps->_pSnake = ps->_pFood;

	//释放pn节点(下一个位置)
	free(pn);
	pn = NULL;

	//打印蛇身
	pSnakeNode cur = ps->_pSnake;
	while (cur);
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}

	//吃掉单个食物的分数加到总分
	ps->_score += ps->_food_weight;

	//重新创建食物
	CreateFood(ps);
}
1.c)不是食物(NoFood)

下⼀个节点成为新的蛇头,并将之前蛇⾝最后⼀个节点打印为空格,并释放掉。

注意: 释放最后⼀个结点后,还得将结点的指针改为NULL,保证蛇尾打印可以正常结束,不会越界访问。

不是食物函数:

void NoFood(pSnakeNode pn, pSnake ps)
{
	//头插法  
	//下一个节点成为新的蛇头
	pn->next = ps->_pSnake;
	ps->_pSnake = pn;

	//打印蛇身
	pSnakeNode cur = ps->_pSnake;
	while (cur->next->next)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}

	//蛇身最后一个节点打印为空白(2个空格)
	SetPos(cur->next->x, cur->next->y);
	printf(" ");

	//再释放掉并置为NULL
	free(cur->next);
	cur->next = NULL;
}
1.d)撞墙(KillByWall)

判断蛇头的坐标是否和墙的坐标冲突。

撞墙函数:

void KillByWall(pSnake ps)
{
	if (ps->_pSnake->x == 0 || ps->_pSnake->x == 56 ||
		ps->_pSnake->y == 0 || ps->_pSnake->y == 26)
	{
		ps->_status = KILL_BY_WALL;
	}
}
1.e)撞到自身(KillBySelf)

判断蛇头的坐标是否和蛇⾝体的坐标冲突。

撞到自身函数:

void KillBySelf(pSnake ps)
{
	//记录除蛇头外的第一个蛇身节点
	pSnakeNode cur = ps->_pSnake->next;
	//遍历除蛇头的所有蛇身节点坐标
	while (cur)
	{
		if (cur->x == ps->_pSnake->x && cur->y == ps->_pSnake->y)
		{
			ps->_status = KILL_BY_SELF;
			break;
		}
		cur = cur->next;
	}
}

四、游戏结束

1、游戏结束函数(GameEnd)

当游戏状态不再是OK(游戏继续)的时候,要告知游戏结束的原因,并且释放蛇⾝节点。

Snake.c文件中创建游戏运行的函数GameRun

void GameEnd(pSnake ps)
{
	//判断游戏状态
	SetPos(24, 12);
	switch (ps->_status)
	{
	//正常结束
	case END_NORMAL:
		wprintf(L"您主动结束游戏\n");
		break;
	//撞墙
	case KILL_BY_WALL:
		wprintf(L"您撞到墙上,游戏结束\n");
		break;
	//咬到自身
	case KILL_BY_SELF:
		wprintf(L"您咬到了自己,游戏结束\n");
		break;
	}

	//释放蛇身链表
	pSnakeNode cur = ps->_pSnake;
	while (cur)
	{
		pSnakeNode del = cur;
		cur = cur->next;
		free(del);
	}
}

当完成了上面的所有方法后,我们就可以在test.c文件中来实现整个游戏了。

#include<locale.h>
#include"Snake.h"

void test()
{
	int ch = 0;
	do
	{
		Snake snake = { 0 };
		GameStart(&snake);
		GameRun(&snake);
		GameEnd(&snake);

		SetPos(20, 15);
		printf("再来一局吗!(Y/N):");
		ch=getchar();
		while (getchar() != '\n');
	} while (ch == 'Y' || ch == 'y');
	SetPos(0, 27);
}

int main()
{
	//设置为本地环境
	setlocale(LC_ALL,"");
	srand((unsigned int)time(NULL));//产生随机的食物
	test();
	return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

点击查看:贪吃蛇源代码

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

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

相关文章

NTT印地赛车:数字孪生技术重构赛事体验范式,驱动观众参与度革命

引言&#xff1a;数字孪生技术赋能体育赛事&#xff0c;开启沉浸式观赛新纪元 在传统体育赛事观赛模式遭遇体验天花板之际&#xff0c;NTT与印地赛车系列赛&#xff08;NTT INDYCAR SERIES&#xff09;的深度合作&#xff0c;通过数字孪生&#xff08;Digital Twin&#xff09…

30.【新型数据架构】-区块链数据架构

30.【新型数据架构】-区块链数据架构:分布式账本,不可篡改性,用于数据溯源 一、区块链数据架构的本质:分布式账本的革新 区块链的核心是分布式账本技术(Distributed Ledger Technology, DLT),它颠覆了传统中心化数据库的架构模式: 去中心化存储: 账本数据不再集中存储…

在CSDN发布AWS Proton解决方案:实现云原生应用的标准化部署

引言&#xff1a;云原生时代的部署挑战 在云原生应用开发中&#xff0c;基础设施管理的复杂性已成为团队面临的核心挑战。随着微服务架构的普及&#xff0c;每个服务可能包含数十个AWS资源&#xff08;如Lambda、API Gateway、ECS集群等&#xff09;&#xff0c;传统的手动配置…

C++11 Move Constructors and Move Assignment Operators 从入门到精通

文章目录 一、引言二、基本概念2.1 右值引用&#xff08;Rvalue References&#xff09;2.2 移动语义&#xff08;Move Semantics&#xff09; 三、移动构造函数&#xff08;Move Constructors&#xff09;3.1 定义和语法3.2 示例代码3.3 使用场景 四、移动赋值运算符&#xff…

11 - ArcGIS For JavaScript -- 高程分析

这里写自定义目录标题 描述代码实现结果 描述 高程分析是地理信息系统(GIS)中的核心功能之一&#xff0c;主要涉及对地表高度数据(数字高程模型, DEM)的处理和分析。 ArcGIS For JavaScript4.32版本的发布&#xff0c;提供了Web端的针对高程分析的功能。 代码实现 <!doct…

通道注意力

一、 什么是注意力 其中注意力机制是一种让模型学会「选择性关注重要信息」的特征提取器&#xff0c;就像人类视觉会自动忽略背景&#xff0c;聚焦于图片中的主体&#xff08;如猫、汽车&#xff09;。 transformer中的叫做自注意力机制&#xff0c;他是一种自己学习自己的机制…

2048游戏的技术实现分析-完全Java和Processing版

目录 简介Processing库基础项目构建指南项目结构核心数据结构游戏核心机制图形界面实现性能优化代码详解设计模式分析测试策略总结与展望简介 2048是一款由Gabriele Cirulli开发的经典益智游戏。本文将深入分析其Java实现版本的技术细节。该实现使用了Processing库来创建图形界…

全国县域统计年鉴PDF-Excel电子版-2022年

全国县域统计年鉴PDF-Excel电子版-2022年.ziphttps://download.csdn.net/download/2401_84585615/89784662 https://download.csdn.net/download/2401_84585615/89784662 《中国县域统计年鉴》是一部全面反映中国县域社会经济发展状况的资料性年鉴。自2014年起&#xff0c;该年…

gitlab CI/CD本地部署配置

背景: 代码管理平台切换为公司本地服务器的gitlab server。为了保证commit的代码至少编译ok&#xff0c;也为了以后能拓展test cases&#xff0c;现在先搭建本地gitlab server的CI/CD基本的编译job pipeline。 配置步骤&#xff1a; 先安装gitlab-runner: curl -L "ht…

AI大模型在测试领域应用案例拆解:AI赋能的软件测试效能跃迁的四大核心引擎(顺丰科技)

导语 5月份QECon深圳大会已经结束&#xff0c;继续更新一下案例拆解&#xff0c;本期是来自顺丰科技。 文末附完整版材料获取方式。 首先来看一下这个案例的核心内容&#xff0c;涵盖了测四用例设计、CI/CD辅助、测试执行、监控预警四大方面&#xff0c;也是算大家比较熟悉的…

从零搭建uniapp项目

目录 创建uni-app项目 基础架构 安装 uni-ui 组件库 安装sass依赖 easycom配置组件自动导入 配置view等标签高亮声明 配置uni-ui组件类型声明 解决 标签 错误 关于tsconfig.json中提示报错 关于非原生标签错误&#xff08;看运气&#xff09; 安装 uview-plus 组件库…

OpenCV CUDA模块图像处理------图像融合函数blendLinear()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数执行 线性融合&#xff08;加权平均&#xff09; 两个图像 img1 和 img2&#xff0c;使用对应的权重图 weights1 和 weights2。 融合公式…

图片压缩工具 | 图片生成PDF文档

OPEN-IMAGE-TINY&#xff0c;一个基于 Electron VUE3 的图片压缩工具&#xff0c;项目开源地址&#xff1a;https://github.com/0604hx/open-image-tiny ℹ️ 需求描述 上一版本发布后&#xff0c;有用户提出想要将图片转换&#xff08;或者说生成更为贴切&#xff09;PDF文档…

VSCode - VSCode 放大与缩小代码

VSCode 放大与缩小代码 1、放大 点击顶部菜单栏【查看】 -> 点击外观 -> 点击【放大】 或者&#xff0c;使用快捷键&#xff1a;Ctrl # 操作方式先按住 Ctrl 键&#xff0c;再按 键2、缩小 点击顶部菜单栏【查看】 -> 点击外观 -> 点击【缩小】 或者&#x…

11-Oracle 23ai Vector Embbeding和ONNX

Embedding &#xff08;模型嵌入&#xff09;是 AI 领域的一个核心概念 一、Embedding&#xff08;嵌入&#xff09;的含义 Embedding 是一种将 非结构化数据​&#xff08;如文本、图像、音频、视频&#xff09;转换为 数值向量的技术。 其核心是通过 嵌入模型​&#xff08;…

OpenCV 图像色彩空间转换与抠图

一、知识点: 1、色彩空间转换函数 (1)、void cvtColor( InputArray src, OutputArray dst, int code, int dstCn 0, AlgorithmHint hint cv::ALGO_HINT_DEFAULT ); (2)、将图像从一种颜色空间转换为另一种。 (3)、参数说明: src: 输入图像&#xff0c;即要进行颜…

Amazing晶焱科技:电子系统产品在多次静电放电测试后的退化案例

在我们的电子设计世界里&#xff0c;ESD&#xff08;静电放电&#xff09;问题总是让人头疼。尤其是当客户面临系统失效的困境时&#xff0c;寻找一个能够彻底解决问题的方案就变得格外重要。这一次&#xff0c;我们要谈的是一个经典案例&#xff1a;电子系统产品在多次静电放电…

C# 快速检测 PDF 是否加密,并验证正确密码

引言&#xff1a;为什么需要检测PDF加密状态&#xff1f; 在批量文档处理系统&#xff08;如 OCR 文字识别、内容提取、格式转换&#xff09;中&#xff0c;加密 PDF 无法直接操作。检测加密状态可提前筛选文件&#xff0c;避免流程因密码验证失败而中断。 本文使用 Free Spire…

华为云Flexus+DeepSeek征文| 华为云Flexus X实例单机部署Dify-LLM应用开发平台全流程指南

华为云FlexusDeepSeek征文&#xff5c; 华为云Flexus X实例单机部署Dify-LLM应用开发平台全流程指南 前言一、相关名词介绍1.1 华为云Flexus X实例介绍1.2 Dify介绍1.3 DeepSeek介绍1.4 华为云ModelArts Studio介绍 二、部署方案介绍2.1 方案介绍2.2 方案架构2.3 需要资源2.4 本…

Python: 操作 Excel折叠

💡Python 操作 Excel 折叠(分组)功能详解(openpyxl & xlsxwriter 双方案) 在处理 Excel 报表或数据分析时,我们常常希望通过 折叠(分组)功能 来提升表格的可读性和组织性。本文将详细介绍如何使用 Python 中的两个主流 Excel 操作库 —— openpyxl 和 xlsxwriter …