C语言贪吃蛇(可在头文件中添加食物,选择撞墙是否会死)

1. 项目目标

项目为控制台程序,在控制台上实现。

1. 实现游戏开始界面,让用户选择模式(撞墙/循环)等;

2. 实现地图的绘制;

3. 实现贪吃蛇,并使其根据用户的命令移动;

4. 实现食物的随机刷新,并为每一种食物设置分值;

5. 在游戏过程中打印适当的提示信息以及实时信息的刷新;

6. 实现贪吃蛇的变长;

7. 实时检测游戏状态(正常/撞墙/撞到自己);

2. 所需知识

C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等。

这些知识,想必大家在学习C语言的过程中已经熟练到出神入化了,但是对于Win32 API可能会感到有点陌生。

接下来我们重点介绍一下Win32 API。

2.1 WIn32 API

Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是一个很大的服务中心,调用这个服务中心的各种服务(每⼀种服务就是⼀个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Programming Interface,简称 API 函数。

Win32 API也就是Microsoft Windows 32位平台的应用程序编程接口。

利用Win32 API提供的函数,我们就可以比较方便地在控制台上进行信息的打印,地图的绘制等。

以下为这个项目需要用到的一些API函数。


2.1.1 GetStdHandle 函数 - Windows Console | Microsoft Learn

HANDLE GetStdHandle(DWORD nStdHandle);

GetStdHandle是⼀个Windows API函数。它用于从⼀个特定的标准设备(标准输入、标准输出或标准错误)中取得⼀个句柄(用来标识不同设备的数值,类型为HANDLE),使用这个句柄可以操作设备。

句柄其实就类似于FILE*指针:当你需要对某个文件进行操作时,你需要将对应的文件指针传入对应的函数;当你需要对某个设备进行操作时,你需要将对应的句柄传入对应的函数。

他的参数有以下三个:

含义
STD_INPUT_HANDLE标准输入设备
STD_OUTPUT_HANDLE标准输出设备
STD_ERROR_HANDLE标准错误设备

 

控制台的屏幕属于标准输出设备,所以在该项目中我们在使用这个函数时传入的都是STD_OUTPUT_HANDLE,然后定义一个HANDLE类型的变量来接收其返回的句柄即可。

例如:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

 2.1.2 GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

BOOL WINAPI GetConsoleCursorInfo(
 HANDLE hConsoleOutput,
 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);

GetConsoleCursorInfo函数用于检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息 。

它的第一个参数为标准输出设备的句柄,第二个参数为一个指向 CONSOLE_CURSOR_INFO(CONSOLE_CURSOR_INFO 结构 - Windows Console | Microsoft Learn) 结构的指针,该结构接收有关控制台游标的信息。

CONSOLE_CURSOR_INFO结构的定义如下

typedef struct _CONSOLE_CURSOR_INFO {
 DWORD dwSize;
 BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

• dwSize:表示光标填充的字符单元格的百分比, 此值介于1到100之间。

                  光标外观会变化,范围从完全填充单元格到单元底部的水平线条。

• bVisible:表示光标的可见性。 如果光标可见,则此成员为 TRUE。

在使用时,我们需要先定义一个CONSOLE_CURSOR_INFO类型的变量,然后将其传入函数中。

此时,这个变量中就存储了当前光标的大小和可见性信息,我们可以通过访问这个结构体变量的成员来修改光标的参数。

例如:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

但是,该变量只是获得了一个备份并将其储存,并没有直接与光标建立联系。

要使修改后的参数得到应用,我们还需要调用GetConsoleCursorInfo函数。


2.1.3 SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn

BOOL WINAPI SetConsoleCursorInfo(
 HANDLE hConsoleOutput,
 const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

SetConsoleCursorInfo函数用于设置光标的参数,本质上就是让刚才获得的CONSOLE_CURSOR_INFO类型的变量存储的信息得到应用。

它的参数与GetConsoleCursorInfo函数一模一样,只需要在设置完光标参数之后,将变量再统统扔给它即可。

例如:

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

 2.1.4 SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn

BOOL WINAPI SetConsoleCursorPosition(
 HANDLE hConsoleOutput,
 COORD pos
);

SetConsoleCursorPosition函数用于设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD(COORD 结构 - Windows Console | Microsoft Learn)类型的pos中,调用SetConsoleCursorPosition函数将光标位置设置到指定的位置。

COORD结构体的定义如下:

typedef struct _COORD {
  SHORT X;
  SHORT Y;
} COORD, *PCOORD;

COORD 是Windows API中定义的一个结构体,表示一个字符在控制台屏幕幕缓冲区上的坐标,坐标系 (0,0) 的原点位于缓冲区的顶部左侧单元格。

水平向右为x轴正方向,竖直向下为y轴正方向。

y轴的单位长度(一个中文字符的高度/宽度)是x轴单位长度的两倍。

例如: 

COORD pos = { 10, 5};
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值)
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(hOutput, pos);

这段代码就是将光标的位置设置到(10,5)的位置。

由于在项目中,无论是绘制地图,打印蛇,打印食物还是在指定位置打印信息都需要设置光标位置,所以我们将设置光标位置的功能封装为了一个函数SetPos。

//设置光标的坐标
void SetPos(short x, short y)
{
 COORD pos = { x, y };
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值)
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(hOutput, pos);
}

2.1.5 getAsyncKeyState 函数 (winuser.h) - Win32 apps | Microsoft Learn

SHORT GetAsyncKeyState(
 int vKey
);

GetAsyncKeyState函数用于获取按键的状态。

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。

虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn 

GetAsyncKeyState 的返回值是short类型,在上一次调用 GetAsyncKeyState 函数后,如果返回的16位的short数据中:

• 最高位是1,说明按键的状态是按下,如果最高是0,说明按键的状态是抬 起。

• 如果最低位被置为1则说明,该按键被按过,否则为0。

如果我们要判断一个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.

为了使用方便,我们定义了下面这个宏:

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

2.2 C语言的国际化特性

如果你需要用一些中文的宽字符来表示表示墙体,蛇,食物的话,就需要用到这个知识。

例如:打印墙体使用宽字符:□,打印蛇使用宽字符●,打印食物使用宽字符★

具体的细节,如果感兴趣的话可以自己去了解,在该项目中,你只需要知道setlocale函数即可。

setlocale - C++ Reference

char* setlocale (int category, const char* locale);

要使程序能够打印这些宽字符,只需要下面这个语句即可:

setlocal(LC_ALL, "");

3. 项目实现

3.1 Snake.h

这里我没有使用宽字符来表示墙,蛇,和食物,而是直接使用的汉字,目的是为了方便读者分辨定义的符号是什么意思。

要增加食物数量或种类的话,将FOOD_MAX的值修改之后,在FOOD_SHAPES和FOOD_WEIGHTS中分别添加其符号和分值即可。

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

#define WALL L'墙'
#define BODY L'蛇'

#define FOOD_MAX 3//食物种数

#define FOOD_SHAPES {L'史', L'蕉', L'苹'}//食物外形列表
#define FOOD_WEIGHTS {1145, 10, 20}//食物分值列表

#define ORIGIN_LEN 5
#define ORIGIN_X 24
#define ORIGIN_Y 5
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk) & 0x1) ? 1 : 0)

//类型定义
enum DIRECTIONS//方向
{
	UP,//上
	DOWN,//下
	LEFT,//左
	RIGHT//右
};

enum STATUS//游戏状态
{
	NORMAL,//正常
	END_NORMAL,//正常退出
	END_WALL,//撞墙结束
	END_SELF//撞到自己结束
};

//蛇身结点
typedef struct SnakeNode
{
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode, *pSnakeNode;

//食物结点
typedef struct Food
{
	int x;
	int y;
	int weight;
	WCHAR shape;
}Food, *pFood;

//贪吃蛇游戏
typedef struct Snake
{
	pSnakeNode pSnakeHead;//蛇头
	Food Recipe[FOOD_MAX];//食物清单
	enum DIRECTIONS Direction;//运动方向
	enum STATUS Status;//游戏状态
	int Score;//总分数
	int SleepTime;//睡眠时间
	int Attached;//附加分数
}Snake, *pSnake;

//函数定义

//设置光标位置
void SetPos(int x, int y);

//游戏开始
int GameBegin(pSnake ps);
//欢迎界面
int WelComeToGame();
//创建地图26/58
void CreatMap();
//初始化贪吃蛇
void InitSnake(pSnake ps);
//初始化食物
void InitRecipe(pSnake ps);


//游戏运行
void GameRun(pSnake ps, int flag);
//打印提示信息
void PrintHelpInfo();
//打印实时信息
void PrintTimelyInfo(pSnake ps);
//暂停
void Pause(pSnake ps);
//蛇行
void SnakeMove(pSnake ps, int flag);
//是否即将触碰食物
int IsTouchingFood(pSnakeNode pn, pSnake ps);
//没吃到食物
void NoFood(pSnake ps);
//改变某食物坐标
void FoodPosModify(pSnake ps, int pos);
//检测是否撞墙
void TouchingWall(pSnakeNode pn, pSnake ps, int flag);
//检测是否撞到自己
void TouchingSelf(pSnakeNode pn, pSnake ps);


//游戏结束
void GameEnd(pSnake ps);

3.2 Snake.c

#define _CRT_SECURE_NO_WARNINGS
#include "Snake.h"
//设置光标位置
void SetPos(int x, int y)
{
	HANDLE HandOutPut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x, y };
	SetConsoleCursorPosition(HandOutPut, pos);
}

//欢迎界面
int WelComeToGame()
{
	SetPos(45, 14);
	wprintf(L"%ls", L"欢迎来到贪吃蛇小游戏");
	SetPos(45, 16);
	wprintf(L"%ls", L"1.撞墙模式(撞墙会死)");
	SetPos(45, 17);
	wprintf(L"%ls", L"2.循环模式(撞墙不会死)");
	int choice = 0;
	SetPos(43, 16);
	printf(">");
	do
	{
		if (KEY_PRESS(VK_UP))//撞墙模式
		{
			SetPos(43, 16);
			printf(">");
			SetPos(43, 17);
			printf(" ");
			choice = 0;
		}
		else if (KEY_PRESS(VK_DOWN))//循环模式
		{
			SetPos(43, 17);
			printf(">");
			SetPos(43, 16);
			printf(" ");
			choice = 1;
		}
		else if (KEY_PRESS(VK_RETURN))
		{
			break;
		}
	} while (1);

	SetPos(45, 25);
	system("pause");
	system("cls");
	SetPos(37, 14);
	wprintf(L"用上下左右来控制蛇的移动,按F3加速,按F4减速\n");
	SetPos(48, 15);
	wprintf(L"加速能获得更高的分数\n");
	SetPos(48, 17);
	system("pause");
	system("cls");

	return choice;
}

//创建地图26/58
void CreatMap()
{
	int i = 0;
	//上
	for (i = 0; i < 29; i++)
	{
		wprintf(L"%lc", WALL);
	}
	//下
	SetPos(0, 26);
	for (i = 0; i < 29; i++)
	{
		wprintf(L"%lc", WALL);
	}
	//左右
	for (i = 1; i < 26; i++)
	{
		SetPos(0, i);
		wprintf(L"%lc", WALL);
		SetPos(56, i);
		wprintf(L"%lc", WALL);
	}
}

//初始化贪吃蛇
void InitSnake(pSnake ps)
{
	//初始化贪吃蛇属性
	ps->pSnakeHead = NULL;
	ps->Direction = RIGHT;
	ps->Score = 0;
	ps->Status = NORMAL;
	ps->SleepTime = 200;
	ps->Attached = 0;

	//创建蛇
	pSnakeNode cur = NULL;
	for (int i = 0; i < ORIGIN_LEN; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("InitSnake::malloc");
			return;
		}
		cur->next = NULL;
		cur->x = ORIGIN_X + 2 * i;
		cur->y = ORIGIN_Y;
		//头插
		cur->next = ps->pSnakeHead;
		ps->pSnakeHead = cur;
	}
	
	//打印蛇
	cur = ps->pSnakeHead;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BODY);
		cur = cur->next;
	}

}

//获取合法的食物坐标
void GetPos(pSnake ps, int* x, int* y)
{
	again:
	do
	{
		*x = rand() % 54 + 2;
		*y = rand() % 25 + 1;
	} while (*x % 2 != 0);

	pSnakeNode cur = ps->pSnakeHead;
	while (cur)
	{
		if (cur->x == *x && cur->y == *y)
			goto again;
		cur = cur->next;
	}

	for (int i = 0; i < FOOD_MAX; i++)
	{
		if (ps->Recipe[i].x == *x && ps->Recipe[i].y == *y)
			goto again;
	}
}

//初始化食物
void InitRecipe(pSnake ps)
{
	int x = 0;
	int y = 0;
	WCHAR shapes[FOOD_MAX] = FOOD_SHAPES;
	int weights[FOOD_MAX] = FOOD_WEIGHTS;
	for (int i = 0; i < FOOD_MAX; i++)
	{
		GetPos(ps, &x, &y);
		ps->Recipe[i].x = x;
		ps->Recipe[i].y = y;
		ps->Recipe[i].shape = shapes[i];
		ps->Recipe[i].weight = weights[i];

		SetPos(x, y);
		wprintf(L"%lc", ps->Recipe[i].shape);
	}
}

//游戏开始
int GameBegin(pSnake ps)
{
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");

	//欢迎界面
	int flag = WelComeToGame();
	//创建地图27/58
	CreatMap();
	//初始化贪吃蛇
	InitSnake(ps);
	//初始化食物
	InitRecipe(ps);

	return flag;
}


//打印提示信息
void PrintHelpInfo()
{
	SetPos(64, 16);
	wprintf(L"%ls", L"不能咬到自己");
	SetPos(64, 17);
	wprintf(L"%ls", L"用上下左右来控制蛇移动");
	SetPos(64, 18);
	wprintf(L"%ls", L"按F3加速,按F4减速");
	SetPos(64, 19);
	wprintf(L"%ls", L"按ESC退出游戏,按空格暂停游戏");
}

//打印实时信息
void PrintTimelyInfo(pSnake ps)
{
	SetPos(64, 9);
	printf("总分数:%d\n", ps->Score);
	for (int i = 0; i < FOOD_MAX; i++)
	{
		SetPos(64, 11 + i);
		wprintf(L"%lc", ps->Recipe[i].shape);
		printf("的分数为:%d", ps->Recipe[i].weight);
	}
	SetPos(64, 11 + FOOD_MAX);
	printf("附加分数为:%d", ps->Attached);
}

//暂停
void Pause(pSnake ps)
{
	while (1)
	{
		Sleep(200);
		if (KEY_PRESS(VK_SPACE))
		{
			break;
		}
		if (KEY_PRESS(VK_ESCAPE))
		{
			ps->Status = END_NORMAL;
			break;
		}
	}
}

//是否即将触碰食物(是,则返回食物下标;否,则返回-1)
int IsTouchingFood(pSnakeNode pn, pSnake ps)
{
	for (int i = 0; i < FOOD_MAX; i++)
	{
		if (pn->x == ps->Recipe[i].x && pn->y == ps->Recipe[i].y)
			return i;
	}
	return -1;
}

//没吃到食物
void NoFood(pSnake ps)
{
	pSnakeNode cur = ps->pSnakeHead;
	while (cur->next->next)
	{
		cur = cur->next;
	}
	SetPos(cur->next->x, cur->next->y);
	printf("  ");
	free(cur->next);
	cur->next = NULL;
}

//改变某食物坐标
void FoodPosModify(pSnake ps, int pos)
{
	int x = 0;
	int y = 0;
	GetPos(ps, &x, &y);
	ps->Recipe[pos].x = x;
	ps->Recipe[pos].y = y;
	SetPos(x, y);
	wprintf(L"%lc", ps->Recipe[pos].shape);
}

//检测是否撞墙
void TouchingWall(pSnakeNode pn, pSnake ps, int flag)
{
	if (flag == 1)
	{
		if (pn->x == 0)
		{
			pn->x = 54;
		}
		if (pn->x == 56)
		{
			pn->x = 2;
		}
		if (pn->y == 26)
		{
			pn->y = 1;
		}
		if (pn->y == 0)
		{
			pn->y = 25;
		}
	}
	else
	{
		if (pn->x == 0 || pn->x == 56 || pn->y == 26 || pn->y == 0)
		{
			ps->Status = END_WALL;
		}
	}
}

//检测是否撞到自己
void TouchingSelf(pSnakeNode pn, pSnake ps)
{
	pSnakeNode cur = ps->pSnakeHead;
	while (cur)
	{
		if (cur->x == pn->x && cur->y == pn->y)
		{
			ps->Status = END_SELF;
			return;
		}
		cur = cur->next;
	}
}

//蛇行
void SnakeMove(pSnake ps, int flag)
{
	pSnakeNode newhead = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (newhead == NULL)
	{
		perror("SnakeMove::malloc");
		return;
	}

	switch (ps->Direction)
	{
	case UP:
		newhead->x = ps->pSnakeHead->x;
		newhead->y = ps->pSnakeHead->y - 1;
		break;
	case DOWN:
		newhead->x = ps->pSnakeHead->x;
		newhead->y = ps->pSnakeHead->y + 1;
		break;
	case LEFT:
		newhead->x = ps->pSnakeHead->x - 2;
		newhead->y = ps->pSnakeHead->y;
		break;
	case RIGHT:
		newhead->x = ps->pSnakeHead->x + 2;
		newhead->y = ps->pSnakeHead->y;
		break;
	}

	//检测是否撞墙
	TouchingWall(newhead, ps, flag);
	//检测是否撞到自己
	TouchingSelf(newhead, ps);

	newhead->next = ps->pSnakeHead;
	ps->pSnakeHead = newhead;
	SetPos(newhead->x, newhead->y);
	wprintf(L"%lc", BODY);

	//判断是否即将碰到食物
	int judge = IsTouchingFood(newhead, ps);
	if (judge == -1)
	{
		//还没吃到食物,删掉最后一个结点
		NoFood(ps);
	}
	else
	{
		//修改某食物坐标
		FoodPosModify(ps, judge);
		ps->Score += ps->Recipe[judge].weight + ps->Attached;
	}

}

//游戏运行
void GameRun(pSnake ps, int flag)
{
	//打印提示信息
	PrintHelpInfo(ps);
	do
	{
		//打印实时信息
		PrintTimelyInfo(ps);

		//检测按键
		if (KEY_PRESS(VK_UP) && ps->Direction != DOWN)
		{
			ps->Direction = UP;
		}
		else if (KEY_PRESS(VK_DOWN) && ps->Direction != UP)
		{
			ps->Direction = DOWN;
		}
		else if (KEY_PRESS(VK_LEFT) && ps->Direction != RIGHT)
		{
			ps->Direction = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && ps->Direction != LEFT)
		{
			ps->Direction = RIGHT;
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			//暂停
			Pause(ps);
		}
		else if (KEY_PRESS(VK_ESCAPE))
		{
			ps->Status = END_NORMAL;
		}
		else if (KEY_PRESS(VK_F3))
		{
			//加速
			if (ps->SleepTime > 80)
			{
				ps->SleepTime -= 30;
				ps->Attached += 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			//减速
			if (ps->SleepTime < 320)
			{
				ps->SleepTime += 30;
				ps->Attached -= 2;
			}
		}

		SnakeMove(ps, flag);
		Sleep(ps->SleepTime);

	} while (ps->Status == NORMAL);
}
//游戏结束
void GameEnd(pSnake ps)
{
	SetPos(24, 12);
	switch (ps->Status)
	{
	case END_NORMAL:
		printf("退出游戏!\n");
		break;
	case END_WALL:
		printf("撞墙啦牢底!\n");
		break;
	case END_SELF:
		printf("紫砂啦牢底!\n");
		break;
	}
	SetPos(24, 13);

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

3.3 test.c

#define _CRT_SECURE_NO_WARNINGS
#include "Snake.h"

void SnakeGame()
{
	Snake snake = { 0 };
	//光标隐藏
	HANDLE HandOutPut = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(HandOutPut, &CursorInfo);
	CursorInfo.bVisible = false;
	SetConsoleCursorInfo(HandOutPut, &CursorInfo);

	int ch = 0;
	do
	{
		fflush(stdin);
		//游戏开始
		int flag = GameBegin(&snake);
		//游戏运行
		GameRun(&snake, flag);
		//游戏结束
		GameEnd(&snake);
		printf("要再来一次吗(Y/N):");
		ch = getchar();
		while (getchar() != '\n');
		KEY_PRESS(VK_RETURN);
	} while (ch == 'Y' || ch == 'y');
	SetPos(0, 28);
}

int main()
{
	setlocale(LC_ALL, "");
	srand((unsigned int)time(NULL));
	SnakeGame();
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

030——从GUI->Client->Server->driver实现对红外遥控的控制

目录 1、 解决韦东山老师irda模块中断申请失败的bug 2、 client添加处理程序 3、 添加服务器处理程序和驱动处理句柄 4、 处理数据读出不准确问题 5、 修改后的展示 1、 解决韦东山老师irda模块中断申请失败的bug irda需要通过中断来触发读操作&#xff0c;申请中断需要引…

Octopus v2:斯坦福的嵌入设备专用大模型

斯坦福大学推出了 Octopus v2&#xff0c;这是一种突破性的设备上语言模型&#xff0c;旨在解决与现有模型相关的延迟、准确性和隐私问题。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑…

源码篇--Nacos服务--中章(1):Nacos服务端的启动

文章目录 前言一、Nacos Console 启动入口&#xff1a;二、启动过程&#xff1a;2.1 容器启动监听器&#xff1a;2.1.1 调整启动标识为正在启动状态&#xff1a;2.1.2 环境准备阶段&#xff1a;2.1.3 容器环境准备&#xff1a;2.1.4 自定义的环境变量 设置&#xff1a;2.1.5 服…

Spectre-v2 以及 Linux Retpoline技术简介

文章目录 前言一、Executive Summary1.1 Spectre-v2: Branch Predictor Poisoning1.2 Mitigating Spectre-v2 with Retpolines1.3 Retpoline Concept 二、BackgroundExploit Composition 三、(Un-)Directing Speculative Execution四、Construction (x86)4.1 Speculation Barri…

测试人员通常遇到的“坑”

网上看到一个帖子&#xff0c;从事多年的测试从业者&#xff0c;吐槽测试过程中遇到的“坑”&#xff0c;感觉比较有意思&#xff0c;我在工作当中也遇到通常的问题&#xff0c;看得出这位网友比较喜欢总结&#xff0c;帖子地址奉上&#xff0c;有兴趣的可以浏览一下&#xff1…

bug(警告):[vue-router] Duplicate named routes definition: …

查看警告&#xff1a;[vue-router] Duplicate named routes definition——翻译[vue-router]重复命名路由定义 小编劝诫&#xff1a;当我们在开发过程中警告也一定不要忽略&#xff0c;虽然你在本地跑代码时这些警告影响项目的正常运行&#xff0c;但是会让你产生误区&#xff…

大模型日报|今日必读的8篇大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.EdgeFusion&#xff1a;端侧文本到图像生成&#xff0c;只需不到一秒 用于文本到图像生成的稳定扩散&#xff08;SD&#xff09;技术需要大量计算&#xff0c;这对其实际应用构成了重大障碍。为此&#xff0c;最近…

Oracle進階SQLDay03

一、函數進階復習 1、行轉列 select 用水儿量&#xff08;噸&#xff09; 统计项, sum(case when t_account.month01 then USENUM end) 一月, sum(case when t_account.month02 then USENUM end) 二月, sum(case when t_account.month03 then USENUM end) 三月, sum(case when …

STM32学习和实践笔记(15):STM32中断系统

中断概念 CPU执行程序时&#xff0c;由于发生了某种随机的事件(外部或内部)&#xff0c;引起CPU暂 时中断正在运行的程序&#xff0c;转去执行一段特殊的服务程序(中断服务子程序 或中断处理程序)&#xff0c;以处理该事件&#xff0c;该事件处理完后又返回被中断的程序 继…

飞桨Ai(二)paddle使用CPU版本可以正常识别,切换为GPU版本时无法识别结果

一、问题描述&#xff1a; 刚开始用paddle的CPU版本&#xff0c;对训练好的模型进行推理&#xff0c;正常识别出想要的结果后来尝试使用paddle的GPU版本&#xff0c;然后发现识别出来是空的 二、系统思路&#xff1a; 最终系统环境如下&#xff1a; 系统&#xff1a;win10 …

有哪些公认好用且免费的云渲染网渲平台?渲染100邀请码1a12

现在云渲染是越来越火了&#xff0c;无论是在建筑设计、影视动画还是效果图行业都有它的身影&#xff0c;云渲染能缩短制作周期&#xff0c;提高工作效率&#xff0c;那么市面上有哪些公认好用且免费的云渲染平台呢&#xff1f;这次我们来了解下。 首先&#xff0c;我们来看看有…

vulfocus靶场tomcat-cve_2017_12615 文件上传

7.0.0-7.0.81 影响版本 Windows上的Apache Tomcat如果开启PUT方法(默认关闭)&#xff0c;则存在此漏洞&#xff0c;攻击者可以利用该漏洞上传JSP文件&#xff0c;从而导致远程代码执行。 Tomcat 是一个小型的轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多…

「GO基础」在Windows上配置VS Code GO语言开发环境

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

查看linux的主机配置脚本

废话不说 直接上指令 curl -Lso- bench.sh | bash 等待后&#xff0c;结果如图&#xff1a; 使用后没有问题&#xff0c;看情况使用 出事概不负责 介意勿用&#xff01;&#xff01;&#xff01;

LD-Pruner、EdgeFusion(On-Device T2I)、FreeDiff、TextCenGen、MemLLM

本文首发于公众号&#xff1a;机器感知 https://mp.weixin.qq.com/s/KiyNfwYWU-wBiCO-hE9qkA 苏 The devil is in the object boundary: towards annotation-free instance segmentation using Foundation Models Foundation models, pre-trained on a large amount of data…

Windows系统下安装paddle

开始使用_飞桨-源于产业实践的开源深度学习平台 (paddlepaddle.org.cn) 命令行下&#xff1a; python -m pip install --upgrade pip --user python -m pip install paddlepaddle2.6.1 -i https://pypi.tuna.tsinghua.edu.cn/simple 报异常 ERROR: Could not install packa…

Jmeter 测试Dubbo接口-实例

1、Dubbo插件准备 ①把jmeter-plugins-dubbo-2.7.4.1-jar-with-dependencies.jar包放在D:\apache-jmeter-5.5\lib\ext目录 ②重新打开Jmeter客户端 在线程组-添加-取样器-dubbo simple&#xff0c;添加dubbo接口请求 2、Jmeter测试lottery接口 ①配置zookeeper参数 由于dub…

windows和虚拟机互传文件

在虚拟机中设置共享文件夹 操作方法&#xff1a;打开VMware–>虚拟机–>设置–>选项–>共享文件夹&#xff08;见下图&#xff09;&#xff0c;大家在共享文件夹当中就可以把Windows当中的D盘或者其它盘共享到虚拟机中。比如我就是将D盘和E盘共享到了虚拟机中。 共…

【Vue】实现显示输入框字符长度

<div style"float: right; margin-right: 10px"><el-popover placement"top-start" width"200" trigger"hover" :content"当前输入的内容字节长度为&#xff1a; this.byteLength &#xff0c;剩余可输入的字节长度和最…

学校管网的仿写

工字形布局完成 效果 代码部分 在这里插入代码片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport…