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

news2025/6/7 15:37:20

文章目录

  • 一、游戏背景及其功能
  • 二、Win32 API介绍
    • 1、Win32 API
    • 2、控制台程序
    • 3、定位坐标(COORD)
    • 4、获得句柄(GetStdHandle)
    • 5、获得光标属性(GetConsoleCursorInfo)
      • 1)描述光标属性(CONSOLE_CURSOR_INFO)
    • 6、设置光标属性(SetConsoleCursorInfo)
    • 7、设置光标位置(SetConsoleCursorPosition )
      • 1)封装函数SetPos
    • 8、检测按键状态(GetAsyncKeyState)
  • 三、贪吃蛇游戏设计与分析
    • 1、地图
      • 1)<locale.h>本地化
      • 2)类项
      • 3)setlocale函数
      • 4)宽字符的打印
      • 5)地图坐标
    • 2、蛇⾝和⻝物
    • 3、数据结构设计
    • 4、游戏流程设计

一、游戏背景及其功能

贪吃蛇是久负盛名的游戏,它也和俄罗斯⽅块,扫雷等游戏位列经典游戏的⾏列。

在这里我们将使⽤C语⾔在Windows环境的控制台中模拟实现经典⼩游戏贪吃蛇。

实现基本的功能:

  • 贪吃蛇地图绘制
  • 蛇吃⻝物的功能(上、下、左、右⽅向键控制蛇的动作)
  • 蛇撞墙死亡
  • 蛇撞⾃⾝死亡
  • 计算得分
  • 蛇⾝加速、减速
  • 暂停游戏

在编写这个游戏之前,需要我们掌握C语⾔函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等相关知识,在我的博客中除了Win32 API以外其余知识都有详细的讲解,在这里我们将来学习Win32 API的知识。

二、Win32 API介绍

Win32 API对我们来说是一个全新的内容,因此将在这里对其进行全面讲解。

1、Win32 API

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

2、控制台程序

平常我们运⾏起来的⿊框程序其实就是控制台程序。

  • 我们可以输入cmd命令来设置控制台窗⼝的⻓和宽。

例如:将控制台窗口的⼤⼩设置为30⾏,100列。

mode con cols=100 lines=30

参考:mode命令

  • 也可以通过cmd命令来设置控制台窗⼝的名字。
title 贪吃蛇

如图:
在这里插入图片描述

参考:title命令

  • 这些能在控制台窗⼝执⾏的命令,也可以调⽤C语⾔函数system来执⾏。

例如:

#include<stdio.h>
int main()
{
	//设置控制台的长宽
	system("mode con cols=30 lines=30");
	//设置控制台名称
	system("title 贪吃蛇");
	return 0;
}

运行结果:

3、定位坐标(COORD)

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

如图:
在这里插入图片描述
注意: 使用Windows API 中的内容时需要包含头文件#include<windows.h>

COORD类型的声明:

typedef struct _COORD
{
	SHORT X;
	SHORT Y;
}COORD, * PCOORD;
  • 使用COORD来表示一个字符在控制台上的坐标。
COORD pos = { 10, 15 };

4、获得句柄(GetStdHandle)

GetStdHandle是⼀个Windows API函数。它⽤于从⼀个特定的标准设备(标准输⼊、标准输出或标准错误)中取得⼀个句柄,使⽤这个句柄可以操作设备。

函数原型:

HANDLE GetStdHandle(DWORD nStdHandle);

举例:获得输出句柄。

int main()
{
	//获得输出句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	return 0;
}

5、获得光标属性(GetConsoleCursorInfo)

GetConsoleCursorInfo也是一个Windows API 函数,用来获取控制台光标的属性(光标大小、可见性等等)。

函数原型:

BOOL WINAPI GetConsoleCursorInfo(
	HANDLE hConsoleOutput,
	PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);

注:
PCONSOLE_CURSOR_INFO 是指向CONSOLE_CURSOR_INFO 结构的指针,该结构接收有关光标的信息。

函数的使用:

int main()
{
	//获得输出句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//获取光标信息 
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(hOutput, &CursorInfo);

	return 0;
}

1)描述光标属性(CONSOLE_CURSOR_INFO)

CONSOLE_CURSOR_INFO是 Windows API 中的一个结构体,用于描述控制台光标的属性。

结构体的声明:

typedef struct _CONSOLE_CURSOR_INFO {
	DWORD dwSize;
	BOOL bVisible;
} CONSOLE_CURSOR_INFO, * PCONSOLE_CURSOR_INFO;
  • dwSize:光标在屏幕上的大小。此值介于1到100之间,是光标高度占字符单元格高度的百分比。
  • bVisible:光标的可见性。如果光标可⻅为TRUE,不可见为FALSE。
CursorInfo.bVisible = FALSE; //隐藏控制台光标 

6、设置光标属性(SetConsoleCursorInfo)

SetConsoleCursorInfo 是 Windows API 中的一个函数,用于设置控制台光标的属性(大小和可见性)。它一般与 GetConsoleCursorInfo 配合使用。

函数原型:

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

函数的使用:

int main()
{
	//获得输出句柄
	HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	
	//获取光标信息 
	CONSOLE_CURSOR_INFO CursorInfo;
	GetConsoleCursorInfo(hOutput, &CursorInfo);
	
	//设置光标状态 
	CursorInfo.bVisible = FALSE; //隐藏控制台光标 
	SetConsoleCursorInfo(hOutput, &CursorInfo);
}

运行结果:

可以看到此时光标已经被隐藏了。

7、设置光标位置(SetConsoleCursorPosition )

SetConsoleCursorPosition 是 Windows API 中的一个函数,用于设置控制台屏幕缓冲区中光标的位置。

函数原型:

BOOL WINAPI SetConsoleCursorPosition(
	HANDLE hConsoleOutput,
	COORD pos
);

函数的使用:

int main()
{
	//坐标
	COORD pos = { 10, 5 };

	//获得输出句柄
	HANDLE hOutput = NULL;	
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	//设置光标的位置为坐标pos 
	SetConsoleCursorPosition(hOutput, pos);

	return 0;
}

运行结果:

可以看到此时光标的位置已经被设置到(10,5)这个坐标了。

1)封装函数SetPos

  • 如果想要让光标出现在指定的坐标位置,那么我们就可以将上述代码封装为一个函数SetPos
void SetPos(short x, short y)
{ 
    //取得坐标
	COORD pos = { x, y };
	//获得输出句柄
	HANDLE hOutput = NULL;
	hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
	//设置光标位置
	SetConsoleCursorPosition(hOutput, pos);
}

8、检测按键状态(GetAsyncKeyState)

GetAsyncKeyState 是 Windows API 中的一个函数,用于检测某个按键或鼠标按钮的当前状态。

函数原型:

SHORT GetAsyncKeyState(int vKey);

将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。
GetAsyncKeyState 的返回值是short类型,在调⽤ GetAsyncKeyState 函数后,如果返回的16位short数据中,如果最低位被置为1则说明,该按键被按过,否则为0。

  • 因此如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState函数的返回值最低位是否为1。将其定义为一个宏。
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

参考:虚拟键码

实例: 检测数字键

#include <stdio.h>
#include <windows.h>

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

int main()
{
	while (1)
	{
		if (KEY_PRESS(0x30))
		{
			printf("0\n");
		}
		else if (KEY_PRESS(0x31))
		{
			printf("1\n");
		}
		else if (KEY_PRESS(0x32))
		{
			printf("2\n");
		}
		else if (KEY_PRESS(0x33))
		{
			printf("3\n");
		}
		else if (KEY_PRESS(0x34))
		{
			printf("4\n");
		}
		else if (KEY_PRESS(0x35))
		{
			printf("5\n");
		}
		else if (KEY_PRESS(0x36))
		{
			printf("6\n");
		}
		else if (KEY_PRESS(0x37))
		{
			printf("7\n");
		}
		else if (KEY_PRESS(0x38))
		{
			printf("8\n");
		}
		else if (KEY_PRESS(0x39))
		{
			printf("9\n");
		}
	}
	return 0;
}

运行结果:

当我们按下数字键后就会在控制台上面显示出来,而按到其他键时则不会显示。

三、贪吃蛇游戏设计与分析

1、地图

我们最终的贪吃蛇界面应该实现下面的效果,那我们的地图该如何布置呢?
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

如果想在控制台窗⼝中的指定位置输出信息,我们得知道
该位置的坐标。

控制台窗⼝的坐标如下所⽰,横向的是X轴,纵向是Y轴。
在这里插入图片描述

在游戏地图上,我们打印墙体使⽤宽字符:□,打印蛇使⽤宽字符●,打印⻝物使⽤宽字符★。

普通的字符是只占1个字节,而上述这类宽字符需要占2个字节。

这⾥再简单的讲⼀下C语⾔的国际化特性相关的知识,过去C语⾔并不适合⾮英语国家(地区)使⽤。
C语⾔最初假定字符都是单字节的。但是这些假定并不是在世界的任何地⽅都适⽤。
后来为了使C语⾔适应国际化,C语⾔的标准中不断加⼊了国际化的⽀持。⽐如:加⼊了宽字符的类型wchar_t宽字符的输⼊和输出函数,加⼊了<locale.h>头⽂件,其中提供了允许程序员针对特定地区(通常是国家或者说某种特定语⾔的地理区域)调整程序⾏为的函数。

1)<locale.h>本地化

<locale.h>提供的函数⽤于控制C标准库中对于不同的地区会产⽣不⼀样⾏为的部分。
在标准中,依赖地区的部分有以下⼏项:

  • 数字量的格式
  • 货币量的格式
  • 字符集
  • ⽇期和时间的表⽰形式

2)类项

通过修改地区,程序可以改变它的⾏为来适应世界的不同区域。但地区的改变可能会影响库的许多部分,其中⼀部分可能是我们不希望修改的。所以C语⾔⽀持针对不同的类项进⾏修改,下⾯不同的宏指定不同的类项:

  • LC_COLLATE:影响字符串⽐较函数 strcoll()strxfrm()
  • LC_CTYPE:影响字符处理函数的⾏为。
  • LC_MONETARY:影响货币格式。
  • LC_NUMERIC:影响 printf() 的数字格式。
  • LC_TIME:影响时间格式 strftime()wcsftime()
  • LC_ALL:针对所有类项修改,将以上所有类别设置为给定的语⾔环境。

每个类项的详细说明,请点击参考

3)setlocale函数

函数原型:

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

setlocale 函数⽤于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。

setlocale 函数的第⼀个参数可以是前⾯说明的类项中的⼀个,那么每次只会影响⼀个类项,如果第⼀个参数是LC_ALL,就会影响所有的类项。
C标准给第⼆个参数仅定义了2种可能取值:"C"(正常模式)和" "(本地模式)。
在任意程序执⾏开始,都会隐藏式执⾏调⽤:

setlocale(LC_ALL, "C");

当地区设置为"C"时,库函数按正常⽅式执⾏,⼩数点是⼀个点。
当程序运⾏起来后想改变地区,就只能显⽰调⽤setlocale函数。⽤" "作为第2个参数,调⽤setlocale函数就可以切换到本地模式,这种模式下程序会适应本地环境。

⽐如:切换到我们的本地模式后就⽀持宽字符(汉字)的输出等。

setlocale(LC_ALL, " ");

4)宽字符的打印

那如果想在屏幕上打印宽字符,怎么打印呢?
宽字符的字⾯量必须加上前缀“L”,否则C语⾔会把字⾯量当作窄字符类型处理。
前缀“L”在单引号前⾯,表⽰宽字符,对应 wprintf() 的占位符为 %lc
在双引号前⾯,表⽰宽字符串,对应wprintf() 的占位符为 %ls

#include <stdio.h>
#include<locale.h>

int main()
{
	setlocale(LC_ALL, "");
	wchar_t ch1 = L'●';
	wchar_t ch2 = L'□';
	wchar_t ch3 = L'张';
	wprintf(L"%lc\n", ch1);
	wprintf(L"%lc\n", ch2);
	wprintf(L"%lc\n", ch3);

	printf("%c%c\n", 'a', 'b');
	return 0;
}

注: 我们需要以管理员的身份打开VS再运行代码才可以观察得更明显。

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

从输出的结果来看,我们发现一个普通字符占1个字符的位置,但是⼀个宽字符会占⽤2个字符的位置,因此如果我们要在贪吃蛇中使⽤宽字符,就得处理好地图上坐标的计算。
普通字符和宽字符打印出宽度的展⽰如下:
在这里插入图片描述

5)地图坐标

我们假设实现⼀个棋盘27⾏,58列的棋盘,再围绕地图画出墙,
如下:
在这里插入图片描述

2、蛇⾝和⻝物

初始化状态,假设蛇的⻓度是5,蛇⾝的每个节点是●,在固定的⼀个坐标处,⽐如(24,5)处开始出现蛇,连续5个节点。

  • 注意: 蛇的每个节点的x坐标必须是2的倍数,否则可能会出现蛇的⼀个节点有⼀半⼉出现在墙体中,另外⼀般在墙外的现象,坐标不好对⻬。

关于⻝物,就是在墙体内随机⽣成⼀个坐标(x坐标必须是2的倍数),坐标不能和蛇的⾝体重合,然后打印★。
在这里插入图片描述

3、数据结构设计

在游戏运⾏的过程中,蛇每次吃⼀个⻝物,蛇的⾝体就会变⻓⼀节,如果我们使⽤链表存储蛇的信息,那么蛇的每⼀节其实就是链表的每个节点。每个节点只要记录好蛇⾝节点在地图上的坐标就⾏,所以蛇身的节点结构如下:

typedef struct SnakeNode
{
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode, * pSnakeNode;
  • pSnakeNode是结构体指针,等价于
typedef struct SnakeNode* pSnakeNode;

要管理整条贪吃蛇,我们再封装⼀个Snake的结构来维护整条贪吃蛇:

typedef struct Snake
{
	pSnakeNode _pSnake;//指向蛇头的指针
	pSnakeNode _pFood;//指向食物节点的指针
	enum DIRECTION _dir;//蛇的方向
	enum GAME_STATUS _status;//游戏的状态
	int _food_weight;//一个食物的分数
	int _score;//总成绩
	int _sleep_time;//休息时间,时间越短,速度越快
}Snake, * pSnake;
  • 蛇的⽅向,可以⼀⼀列举,使⽤枚举:
enum DIRECTION
{
	UP = 1,//上
	DOWN,//下
	LEFT,//左
	RIGHT//右
};
  • 游戏状态,可以⼀⼀列举,使⽤枚举:
enum GAME_STATUS
{
	OK,//正常运行
	KILL_BY_WALL,//撞墙
	KILL_BY_SELF,//咬到自己
	END_NOMAL//正常结束
};

4、游戏流程设计

在这里插入图片描述

现在我们已经把贪吃蛇大致的步骤梳理了一遍,了解完上述知识后,接着在下篇文章就开始编写方法来实现整个游戏。

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

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

相关文章

vue2中使用jspdf插件实现页面自定义块pdf下载

pdf下载 实现pdf下载的环境安装jspdf插件在项目中使用 实现pdf下载的环境 项目需求案例背景&#xff0c;点击【pdf下载】按钮&#xff0c;弹出pdf下载弹窗&#xff0c;显示需要下载四个模块的下载进度&#xff0c;下载完成后&#xff0c;关闭弹窗即可&#xff01; 项目使用的是…

如何防止服务器被用于僵尸网络(Botnet)攻击 ?

防止服务器被用于僵尸网络&#xff08;Botnet&#xff09;攻击是关键的网络安全措施之一。僵尸网络是黑客利用大量被感染的计算机、服务器或物联网设备来发起攻击的网络。以下是关于如何防止服务器被用于僵尸网络攻击的技术文章&#xff1a; 防止服务器被用于僵尸网络&#xff…

基于cornerstone3D的dicom影像浏览器 第二十九章 自定义菜单组件

文章目录 前言一、程序结构1. 菜单数据结构2. XMenu.vue3. XSubMenu.vue4. XSubMenuSlot.vue5. XMenuItem.vue 二、调用流程总结 前言 菜单用于组织程序功能&#xff0c;为用户提供导航。是用户与程序交互非常重要的接口。 开源组件库像Element Plus和Ant Design中都提供了功能…

【Block总结】DBlock,结合膨胀空间注意模块(Di-SpAM)和频域模块Gated-FFN|即插即用|CVPR2025

论文信息 标题: DarkIR: Robust Low-Light Image Restoration 作者: Daniel Feijoo, Juan C. Benito, Alvaro Garcia, Marcos Conde 论文链接&#xff1a;https://arxiv.org/pdf/2412.13443 GitHub链接&#xff1a;https://github.com/cidautai/DarkIR 创新点 DarkIR提出了…

口罩佩戴检测算法AI智能分析网关V4工厂/工业等多场景守护公共卫生安全

一、引言​ 在公共卫生安全日益受到重视的当下&#xff0c;口罩佩戴成为预防病毒传播、保障人员健康的重要措施。为了高效、精准地实现对人员口罩佩戴情况的监测&#xff0c;AI智能分析网关V4口罩检测方案应运而生。该方案依托先进的人工智能技术与强大的硬件性能&#xff0c;…

Double/Debiased Machine Learning

独立同步分布的观测数据 { W i ( Y i , D i , X i ) ∣ i ∈ { 1 , . . . , n } } \{W_i(Y_i,D_i,X_i)| i\in \{1,...,n\}\} {Wi​(Yi​,Di​,Xi​)∣i∈{1,...,n}}&#xff0c;其中 Y i Y_i Yi​表示结果变量&#xff0c; D i D_i Di​表示因变量&#xff0c; X i X_i Xi​表…

HarmonyOS Next 弹窗系列教程(4)

HarmonyOS Next 弹窗系列教程&#xff08;4&#xff09; 介绍 本章主要介绍和用户点击关联更加密切的菜单控制&#xff08;Menu&#xff09; 和 气泡提示&#xff08;Popup&#xff09; 它们出现显示弹窗出现的位置都是在用户点击屏幕的位置相关 菜单控制&#xff08;Menu&…

【C】-递归

1、递归概念 递归&#xff08;Recursion&#xff09;是编程中一种重要的解决问题的方法&#xff0c;其核心思想是函数通过调用自身来解决规模更小的子问题&#xff0c;直到达到最小的、可以直接解决的基准情形&#xff08;Base Case&#xff09;。 核心&#xff1a;自己调用…

飞马LiDAR500雷达数据预处理

0 引言 在使用飞马D2000无人机搭载LiDAR500进行作业完成后&#xff0c;需要对数据进行预处理&#xff0c;方便给内业人员开展点云分类等工作。在开始操作前&#xff0c;先了解一下使用的软硬件及整体流程。 0.1 外业测量设备 无人机&#xff1a;飞马D2000S激光模块&#xff…

嵌入式鸿蒙开发环境搭建操作方法与实现

Linux环境搭建镜像下载链接: 链接:https://pan.baidu.com/s/1F2f8ED5V1KwLjyYzKVx2yQ 提取码:Leun vscode和Linux系统连接的详细过程1.下载Visual Studio Code

QT常用控件(1)

控件是构成QT的基础元素&#xff0c;例如Qwidget也是一个控件&#xff0c;提供了一个‘空’的矩形&#xff0c;我们可以往里面添加内容和处理用户输入&#xff0c;例如&#xff1a;按钮&#xff08;QpushButton&#xff09;&#xff0c;基础显示控件&#xff08;Lable&#xff…

明基编程显示器终于有优惠了,程序员快来,错过等一年!

最近618的活动已经陆续开始了&#xff0c;好多人说这是买数码产品的好时候&#xff0c;作为一名资深程序员&#xff0c;我做了不少功课&#xff0c;决定给自己升级办公设备&#xff0c;入手明基 RD 系列的显示器&#xff0c;这是市面上首家专注于我们程序员痛点和需求的产品&am…

【计算机网络】非阻塞IO——select实现多路转接

&#x1f525;个人主页&#x1f525;&#xff1a;孤寂大仙V &#x1f308;收录专栏&#x1f308;&#xff1a;计算机网络 &#x1f339;往期回顾&#x1f339;&#xff1a;【计算机网络】NAT、代理服务器、内网穿透、内网打洞、局域网中交换机 &#x1f516;流水不争&#xff0…

LeetCode--23.合并k个升序链表

解题思路&#xff1a; 1.获取信息&#xff1a; 给出了多个升序链表&#xff0c;要求合并成一个升序链表&#xff0c;返回首元结点 2.分析题目&#xff1a; 外面在21题的时候&#xff0c;讲了怎样合并两个升序链表为一个升序链表&#xff0c;不了解的&#xff0c;建议去看一下21…

【推荐算法】NeuralCF:深度学习重构协同过滤的革命性突破

NeuralCF&#xff1a;深度学习重构协同过滤的革命性突破 一、算法背景知识&#xff1a;协同过滤的演进与局限1.1 协同过滤的发展历程1.2 传统矩阵分解的缺陷 二、算法理论/结构&#xff1a;NeuralCF架构设计2.1 基础NeuralCF结构2.2 双塔模型进阶结构2.3 模型实现流程对比 三、…

负载均衡相关基本概念

负载均衡在系统架构设计中至关重要&#xff0c;其核心目标是合理分配负载&#xff0c;提升系统整体性能和可靠性。本文简要介绍了负载均衡的基本概念&#xff0c;包括四层和七层负载均衡、负载均衡的使用场景和实现方式、负载均衡的常用算法以及一些配置相关知识。 1、负载均衡…

集成电路设计:从概念到实现的完整解析优雅草卓伊凡

集成电路设计&#xff1a;从概念到实现的完整解析优雅草卓伊凡 一、集成电路设计&#xff1a;芯片制造的”灵魂蓝图” 1.1 什么是集成电路设计&#xff1f; 集成电路&#xff08;IC&#xff09;设计是指通过电子设计自动化&#xff08;EDA&#xff09;工具&#xff0c;将数百…

动态规划之网格图模型(二)

文章目录 动态规划之网格图模型&#xff08;二&#xff09;LeetCode 931. 下降路径最小和思路Golang 代码 LeetCode 2684. 矩阵中移动的最大次数思路Golang 代码 LeetCode 2304. 网格中的最小路径代价思路Golang 代码 LeetCode 1289. 下降路径最小和 II思路Golang 代码 LeetCod…

robot_lab——rsl_rl的train.py整体逻辑

文章目录 Go2机器人训练流程详细分析概述1. 训练启动流程1.1 命令行参数解析RSL-RL相关参数组Isaac Sim应用启动参数组 1.2 RL配置1.3 Isaac Sim启动 2. 环境配置加载2.1 Hydra配置系统 3. 环境创建与初始化3.1 Gym环境创建3.2 Manager系统初始化3.2.1 ObservationManager3.2.2…

.NET 原生驾驭 AI 新基建实战系列(三):Chroma ── 轻松构建智能应用的向量数据库

在人工智能AI和机器学习ML迅猛发展的今天&#xff0c;数据的存储和检索需求发生了巨大变化。传统的数据库擅长处理结构化数据&#xff0c;但在面对高维向量数据时往往力不从心。向量数据库作为一种新兴技术&#xff0c;专为AI应用设计&#xff0c;能够高效地存储和查询高维向量…