贪吃蛇的简单实现(c语言)

前言:学完了C语言的基础语法,和一点数据结构的知识,拿贪吃蛇来练练手,并熟悉以前的知识。写完之后,有一种成就感,为以后的学习饱满激情。

注意这里的讲解是由部分到整体的思路。

目录

控制台不能是终端:

mode和title命令

GetStdHandle函数

隐藏光标函数(HideCurso)的实现:

GetConsoleCursorInfo函数

SetConsoleCursorInfo函数

综上,可以利用以上函数分装成一个函数隐藏光标HideCurso:

在窗口内任意位置打印(SetPos)的函数的实习:

SetCursorPostion函数:

SetPos函数的实现:

实现KEY_PRESS来检测按键被按的情况

按键检测函数GetAsynckeyState

KEY_PRESS的实现:

setlocale函数

游戏实现的大体框架:

游戏开始GameStart实现

1.欢迎界面WelcomeGame的实现

2.创建地图CreateMap的实现

3.CreateSnake创建蛇

3.1蛇身体节点的定义

3.2 蛇的定义

3.3创建蛇CreateSnake的实现

3.4创建食物并打印,CreateFood函数的实现

3.4将上面的函数分装进函数IniteSnake

4.打印蛇,PrintSnake函数的实现

5.最后一步将上述的函数分装进GameStart函数

游戏运行GameRun函数的实现 

GameRun 中需要实现的逻辑

PrintHelpInfo打印帮助信息函数的实现:

PrintScore的实现

SnakeMove的实现

Pause暂停函数的实现:

SnakeNext蛇走一步函数的实现:

接下来说一下NextIsFood函数的实现:

IsKill函数的实现:

游戏结束GameEnd函数的实现:

整个游戏逻辑的运行逻辑的实现:

整个游戏的源码(有感兴趣的可以自取):


这里先放一张最后的成果图和一段视频来展示效果

 

贪吃蛇游戏

这里先讲一些可能需要用到的windows的控制台函数和一些系统操作。

控制台不能是终端:

终端的控制台:

修改过程:

 

mode和title命令

	system("title 贪吃蛇");system("mode con cols=100 lines=30");

mode改变控制台窗口的大小,cols表示行,lines表示列。

title就是改变控制台的名称。

效果展示:

GetStdHandle函数

其返回值类型是HANDLE(是一个指针),获得一个句柄。

//获得一个句柄
HANDLE hOutPut = GetStdHandle(STD_OUTPUT_HANDLE);

CONSOLE_CURSOR_INFO CursorInfo;//CONSOLE_CURSOR_INFO是控制台光标标的结构体类型
//CursorInfo是我们创建的变量

CONSOLE_CURSOR_INFO是一个结构体其中有两个成员,dwSize 和 dVisible ,dwSize 表示光标占一个单位光标高度的百分比,比如下图。

 dVisiable 表示光标是否可见,将光标的信息为不可见:

CursorInfo.bVisible = false;

隐藏光标函数(HideCurso)的实现:

GetConsoleCursorInfo函数

获取控制台的光标信息:

	CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutPut, &CursorInfo);//将光标信息放入CursorInfo这个变量中

SetConsoleCursorInfo函数

设置控制台光标的信息:

将光标的信息设置为不可见。

CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutPut, &CursorInfo);
CursorInfo.bVisible = false;
SetConsoleCursorInfo(hOutPut, &CursorInfo);//将CursorInfo中的数据设置为控制台的光标的信息。

综上,可以利用以上函数分装成一个函数隐藏光标HideCurso:

void HideCursor()
{HANDLE hOutPut = NULL;hOutPut = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutPut, &CursorInfo);CursorInfo.bVisible = false;SetConsoleCursorInfo(hOutPut, &CursorInfo);
}

效果:

上图看不见光标。

在窗口内任意位置打印(SetPos)的函数的实习:

SetCursorPostion函数:

他有两个参数一个是句柄Ll类型为HANDLE,另一个类型为COORD这是一个结构体类型。

typedef sruct COORD
{short x;short y;
}COORD;

定位光标的位置,说到位置这里就不得不聊聊控制台的坐标系的定义

这里注意:一个单位的x不等于一个的单位的y,两个单位的x才等于一个单位的y。

SetPos函数的实现:

void SetPos(short x, short y)
{HANDLE hOutPut = NULL;hOutPut = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x,y };SetConsoleCursorPosition(hOutPut, pos);
}

调用函数SetPos可以直接将光标定位到你给的坐标处。

实现KEY_PRESS来检测按键被按的情况

按键检测函数GetAsynckeyState

short GetAsyncKeyState(int vKey);


他的返回值是short,如果按下了一个间他会返回一个二进制形势下最低位为1的数,否则为0。

 虚拟键码:这里会用到的比如,

上:VK_UP

下:VK_DOWN

左:VK_LEFT

右:VK_RIGHT

f3(加速):VK_F3

f4(减速):VK_F4

空格暂停:SPACE

esc退出:ESCAE

KEY_PRESS的实现:

#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)

如果vk这个虚拟键位代表的按键被按过,则返回1,否则返回0。

setlocale函数

setlocale(LC_ALL, "");//可以将模式改为当前所在地区的模式,可以打印一些特殊的字符
int main()
{char* ret =  setlocale(LC_ALL, "");printf("%s\n", ret);return 0;
}

宽字符:

一个宽字符是两个字符的大小。

	setlocale(LC_ALL, "");printf("ab\n");wprintf(L"%lc", L'我');

将C改为当前地区的模式时,可以打印宽字符。

宽字符打印与普通字符打印的区别

宽字符普通字符
使用函数wprintfprintf
换位符%lc  %ls%c %s
使用

wprintf(L"%ls",L"helloworld");

wprintf(L"%lc",L'a');

printf("%s","helloworld");

printf("%c",'a');

游戏实现的大体框架:

 游戏大揽

 


游戏开始GameStart实现

1.欢迎界面WelcomeGame的实现

void WelcomeGame()
{system("mode con cols=100 lines=30");system("title 贪吃蛇");HideCursor();SetPos(35, 15);wprintf(L"%ls", L"欢迎来到贪吃蛇小游戏");SetPos(36, 22);system("pause");system("cls");SetPos(30, 12);wprintf(L"%ls", L"你可以用↑.↓.←.→来控制蛇的移动");SetPos(30, 13);wprintf(L"%ls", L"F3加速,F4减速");SetPos(36, 22);system("pause");system("cls");
}

这里实现的结果就是大揽里的前两周照片,SetPos,HideCurso两个函数再前面已经实现完了这里就不讲了。

2.创建地图CreateMap的实现

#define WALL L'□'
void CreateMap()
{for (int i = 1; i <= 29; i++){wprintf(L"%lc", WALL);}SetPos(0, 26);for (int i = 1; i <= 29; i++){wprintf(L"%lc", WALL);}for (int i = 1; i <= 26; i++){SetPos(0, i);wprintf(L"%lc", WALL);}for (int i = 1; i <= 26; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}

注意:system("mode con cols=100 lines=30");这是已开设我们设置的窗口大小,这里我们的地图大小为 (58,27)坐标从零开始并且2x=y并且宽字符的宽度为两个x,所以一行打印29个墙就可以了。

还有一点需要注意,以上代码打印出的墙的x坐标的值都为偶数,所以在后面代码中蛇的节点的坐标和食物的坐标的x值也应为偶数,若为偶数,那么蛇再装到上面墙的是时候总是撞在墙与墙之间的空隙中,影响也不大,但必须保证蛇的x坐标与食物的x坐标都为奇数或都为偶数,否则吃不到食物。

表示墙的这个字符可以再输入法中找到, 

3.CreateSnake创建蛇

蛇的身体是用链表的一个一个的节点组成的来的。

3.1蛇身体节点的定义

typedef struct SnakeNode
{short x;short y;struct SnakeNode* next;
}SnakeNode,* pSnakeNode;

其中的x,y表示这个节点在控制台中的坐标。

这里食物的定义与蛇的节点的定义一样。

3.2 蛇的定义

enum DIRECTION
{UP = 1,//上DOWN,//下RIGHT,//左LEFT//右
};
enum STATUS
{OK = 1,//状态正常KILL_BY_WALL,//撞墙死亡KILL_BY_SELF,//自己要到自己死亡END_NORMAL//按esc退出
};
typedef struct Snake
{pSnakeNode _psnake;//指向蛇的头节点的指针int sleep_time;//Sleep(sleep_time)来控制蛇的速度enum DIRECTION dir;//蛇的方向pSnakeNode _pfood;//一个指向食物的指针int food_score;//一个食物的分数int score;//总分enum STATUS status;//蛇当前的装态
}Snake,* pSnake;

3.3创建蛇CreateSnake的实现

void CreateSnake(pSnake ps)
{ps->_psnake = NULL;for (int i = 0; i < 5; i++){pSnakeNode tmp = (pSnakeNode)malloc(sizeof(SnakeNode));if (tmp == NULL){perror("CreateSnake():malloc:");return;}tmp->next = NULL;if (ps->_psnake == NULL){tmp->x = 10;tmp->y = 4;ps->_psnake = tmp;}else{tmp->x = 10 + 2 * i;tmp->y = 4;tmp->next = ps->_psnake;ps->_psnake = tmp;}}
}

运用for循环创建5个节点作为蛇的身体,注意这五个节点每两个节点的坐标应该相邻,确保蛇的身体是连续的。还有蛇的节点坐标别等于墙的坐标。

注意:这里生成的蛇的节点的坐标都是偶数,那么食物的x坐标必须为偶数,否则蛇的头一半吃到食物另一半吃不到食物,就等于永远吃不到食物,就是一个bug了。

3.4创建食物并打印,CreateFood函数的实现

//注意rand的使用需要有srand((unsigned)time(NULL))这一句,这里没有是因为在源码的main函数中
void RandPos(pSnakeNode* tmp)
{int x1 = 0;int y1 = 0;do{x1 = rand() % 53 + 2;y1 = rand() % 25 + 1;} while (x1%2);//保证食物的x坐标为偶数tmp->x = x1;tmp->y = y1;
}
#define FOOD L'★'
void CreateFood(pSnake ps)
{pSnakeNode tmp = (pSnakeNode)malloc(sizeof(SnakeNode));if (tmp == NULL){perror("CreateFood():malloc:");return;}again:RandPos(tmp);pSnakeNode cur = ps->_psnake;//生成的食物的坐标不能与蛇的节点的坐标一样while (cur){if (tmp->x == cur->x && tmp->y == cur->y)goto again;cur = cur->next;}ps->_pfood = tmp;SetPos(tmp->x, tmp->y);//打印食物wprintf(L"%lc", FOOD);return;
}

RandPos函数是随机生成一个坐标,这里需要注意的是生成的坐标的范围,因为我想要的地图的大小为58(x)*27(y)去除墙的所以x的范围为[2,54],y的范围为[1,25],注意这里生成的食物x坐标的奇偶性要与蛇的节点的x保持一致。

注意:生成的食物的坐标不能与蛇的节点的坐标一样。

3.4将上面的函数分装进函数IniteSnake

void IniteSnake(pSnake ps)
{CreateSnake(ps);CreateFood(ps);//以下的为其他初始化蛇的信息ps->dir = RIGHT;ps->status = OK;ps->sleep_time = 200;ps->food_score = 10;ps->score = 0;
}

4.打印蛇,PrintSnake函数的实现

上面已经初始化完了蛇的节点,那么就可以着手打印了。

void PrintSnake(pSnake ps)
{pSnakeNode cur = ps->_psnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}
}

 初始化完了节点,打印就很简单了,定位光标位置直接按链表的顺序直接打印就完了。

5.最后一步将上述的函数分装进GameStart函数

void GameStart(pSnake ps)
{WelcomeGame();CreateMap();IniteSnake(ps);PrintSnake(ps);//getchar();可以用getchar函数来观察打印的效果}

辛苦了这么久看一下打印效果:

游戏运行GameRun函数的实现 

这里采用总分的方式来挨个实现:

GameRun 中需要实现的逻辑

void GameRun(pSnake ps)
{PrintHelpInfo();//打印游戏提示信息do{PrintScore(ps);//打印游戏分数SnakeMove(ps);//蛇的移动IsKill(ps);//判断蛇的状态并修改蛇的状态Sleep(ps->sleep_time);} while (ps->status==OK);//蛇为其他状态时,跳出循环return;
}

简单的一句话总结就是,蛇每走一步判断一下状态并更新一下分数。

PrintHelpInfo打印帮助信息函数的实现:

void PrintHelpInfo()
{SetPos(60, 20);wprintf(L"%ls", L"你可以用↑.↓.←.→来控制蛇的移动");SetPos(60, 21);wprintf(L"%ls", L"F3加速,得分增加;F4减速,得分减少");SetPos(60, 22);wprintf(L"%ls", L"空格是暂停");SetPos(60, 23);wprintf(L"%ls", L"ESC是退出游戏");
}

这里比较简单,需要注意的就是找个合适的位置打印。

PrintScore的实现

void PrintScore(pSnake ps)
{SetPos(60, 5);printf("食物分数:%2d 总分数:%d", ps->food_score, ps->score);
}

每次打印时都会覆盖上次打印的数据。

SnakeMove的实现

这里比较重要,也比较难一些。

void SnakeMove(pSnake ps)
{//以下的判断按键按的情况,并做出相应的反应//蛇现在的运动方向为下,那么我们知道,按上时不改变蛇的方向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_F3)){//f3是加速,将系统休眠时间改小就可以了,别忘了每个食物的加分,并限制一下,不能一直加速if (ps->sleep_time > 100){ps->sleep_time -= 20;ps->food_score += 2;}}else if (KEY_PRESS(VK_F4)){//f4跟f3一样if (ps->sleep_time < 300&&ps->food_score>10){ps->sleep_time += 20;ps->food_score -= 2;}}else if (KEY_PRESS(VK_SPACE)){Pause();//这个函数实现暂停}else if (KEY_PRESS(VK_ESCAPE)){//只需要改变蛇状态就可以了ps->status = END_NORMAL;}SnakeNext(ps);//蛇走下一步
}

注意: 蛇现在的运动方向为下,那么我们根据以前玩贪吃蛇的知识知道,按上时不改变蛇的方向

Pause暂停函数的实现:

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

实现思路:让系统一致Sleep就可以了,当再次检测到你按下空格时,则跳出循环。

SnakeNext蛇走一步函数的实现:

void SnakeNext(pSnake ps)
{//创建一个新节点,这个新节点可以理解为新的蛇头pSnakeNode movenext = (pSnakeNode)malloc(sizeof(SnakeNode));if (movenext == NULL){perror("SnakeNext():malloc:");return;}//基于蛇头的坐标和蛇移动的方向,确定新节点的坐标if (ps->dir == UP){movenext->x = ps->_psnake->x;movenext->y = ps->_psnake->y-1;}else if (ps->dir == DOWN){movenext->x = ps->_psnake->x;movenext->y = ps->_psnake->y + 1;}else if (ps->dir == LEFT){movenext->x = ps->_psnake->x-2;movenext->y = ps->_psnake->y;}else if (ps->dir == RIGHT){movenext->x = ps->_psnake->x+2;movenext->y = ps->_psnake->y;}//判断蛇的下一步是否是食物,如果是食物那么,就将食物的这个节点改为新的蛇头,并释放掉movenextif (NextIsFood(ps, movenext)){SetPos(ps->_pfood->x, ps->_pfood->y);//将食物的位置覆盖式打印为蛇的身体,表示被吃掉wprintf(L"%lc", BODY);ps->_pfood->next = ps->_psnake;ps->_psnake = ps->_pfood;//总分增加ps->score += ps->food_score;free(movenext);//食物被吃掉,这在重新创建一个新的食物。CreateFood(ps);}else{   //下一步没有吃到食物,则将movenext节点头插到蛇的链表中movenext->next = ps->_psnake;ps->_psnake = movenext;pSnakeNode cur = ps->_psnake;//循环打印蛇身,注意跳出循环的条件,当cur指向倒数第二个节点时跳出while (cur->next->next != NULL){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//打印倒数第二个节点SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);//将原来最后一节身体被覆盖打印成空格,因为这里是没有吃到食物身体没有变长SetPos(cur->next->x, cur->next->y);wprintf(L"  ");//一定要释放最后一个节点,因为加上了一个节点movenextfree(cur->next);//现在cur指向尾结点,将尾结点的next置为NULLcur->next = NULL;}
}

思路:根据创建一个新的节点,这个节点是由蛇的方向和头结点的坐标确定的;然后,如果movenext的坐标与食物一样,表示吃到食物,直接将食物的节点头插进蛇的链表;如果movenext与食物的坐标没重合,那么就将movenext头插进链表,并将原链表的尾结点释放。

接下来说一下NextIsFood函数的实现:
int NextIsFood(pSnake ps, pSnakeNode movenext)
{if (ps->_pfood->x == movenext->x && ps->_pfood->y == movenext->y)return 1;elsereturn 0;
}

如果与食物坐标重合就返回1,否则返回0.不用怕,这个函数就是很简单。

IsKill函数的实现:

void IsKill(pSnake ps)
{    //判断蛇头的坐标是否与坐标重合,如果重合那么就改变蛇的状态if (ps->_psnake->x == 0 || ps->_psnake->x == 56 ||ps->_psnake->y == 0 || ps->_psnake->y == 26){ps->status = KILL_BY_WALL;return;}//判断是否要到自己else{//要从蛇头的下一个节点开始,遍历链表pSnakeNode cur = ps->_psnake->next;while (cur){if (ps->_psnake->x == cur->x && ps->_psnake->y == cur->y){ps->status = KILL_BY_SELF;return;}cur = cur->next;}}return;
}

思路:判断是否撞墙,是否要咬自己,如果为真则改变蛇的相应状态,并跳出函数。

这里说一些为什么在判断是否咬到自己这种情况时,不能从蛇头开始遍历,如果是这样,则cur和ps->_psnake都指向蛇头,坐标重合,状态被修改,结果就是一进游戏你就咬到自己,所从蛇头的下一个节点开始遍历。


游戏结束GameEnd函数的实现:

这里实现逻辑比较简单,直接上代码:

void GameEnd(pSnake ps)
{SetPos(30, 14);//根据蛇的状态打印信息if (ps->status== END_NORMAL){printf("正常退出\n");}else if (ps->status == KILL_BY_SELF){printf("咬到自己,死亡\n");}else if (ps->status == KILL_BY_WALL){printf("撞到了墙,死亡\n");}//将开辟的空间释放pSnakeNode cur = ps->_psnake;pSnakeNode prev = cur;while (cur){prev = cur;cur = cur->next;free(prev);}free(ps->_pfood);
}

注意:释放链表的方式,使用的是前后指针的方法,如果不太懂可以看我双链表的博客。


整个游戏逻辑的运行逻辑的实现:

void test()
{char op;do{Snake s;GameStart(&s);GameRun(&s);GameEnd(&s);SetPos(30, 15);wprintf(L"%ls",L"是否再来一局?(Y/N):");scanf(" %c", &op);} while (op == 'y' || op == 'Y');
}
int main()
{setlocale(LC_ALL, "");test();return 0;
}

这里就不多说了哈,主要一点就是加入了,游戏结束你是否还要再来一局。

整个游戏的源码(有感兴趣的可以自取):

    里面也有单向链表,和双向链表的源码。

     这里是我的gitee仓库的链接,项目的名称为Snake追风逐梦又一天/newer_C - 码云 - 开源中国 (gitee.com)icon-default.png?t=N7T8https://gitee.com/small-bit-big-dream/newer_-c

到这里就结束了,拜拜!

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

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

相关文章

ubuntu环境下使用g++把c++编译成汇编语言(暂时)

1. 引言 为了深入理解c&#xff0c;决定学习一些简单的汇编语言。使用ubuntu系统下g很容易将一个c的文件编译成汇编语言。本文使用此方法&#xff0c;对一个简单的c文件编译成汇编语言进行理解。 2.示例 文件名&#xff1a;reorder_demo.cpp #include<stdio.h>typede…

逻辑回归+分类的评估方式

一&#xff1a;什么是逻辑回归 解决二分类问题 二&#xff1a;损失及优化 三&#xff1a;逻辑回归API 四&#xff1a;案例 五&#xff1a;分类的评估方式 评估公式 分类评估API ROC与AUC&#xff08;介绍API&#xff09;衡量不平衡样本 ROC曲线的绘制 分类中解决类别不平衡

HackmyVM-----Boxing靶机

文章目录 正常打靶流程1.获取靶机IP地址2.获取靶机端口服务3.访问网页4.添加域名WindowsLinux 5.访问域名6.nc反弹shell 7.结束 正常打靶流程 1.获取靶机IP地址 ┌──(root㉿kali)-[/home/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:10:3c:9b, …

Drive Scope for Mac:硬盘健康监测分析工具

Drive Scope for Mac是一款专为Mac用户设计的硬盘健康监测与分析工具&#xff0c;致力于保障用户的数据安全。这款软件功能强大且操作简便&#xff0c;能够实时检测硬盘的各项指标&#xff0c;帮助用户及时发现并解决潜在问题。 Drive Scope for Mac 1.2.23注册激活版下载 Driv…

linux 驱动-匹配2 (amba_bustype)

目录 1.实例分析 a. 设备树实例 b. 驱动实例 2. amba匹配流程 a. 创建amba_device b. 确定总线以及总线的匹配函数 c. 分析总线的匹配函数 1.实例分析 a. 设备树实例 serial7e201000 { compatible "brcm,bcm2835-pl011\0arm,pl011\0arm,primecell"; //创建am…

用Python自动化操作PPT,看完这篇文章就够了!

1.PPT自动化能干什么&#xff1f;有什么优势&#xff1f; 它可以代替你自动制作PPT它可以减少你调整用于调整PPT格式的时间它可以让数据报告风格一致总之就是&#xff1a;它能提高你的工作效率&#xff01;让你有更多时间去做其他事情&#xff01; 2.使用win32com操作ppt 官…

【探索Linux】P.32(自定义协议)

阅读导航 引言一、自定义协议概念二、自定义协议需要注意的事项三、自定义协议示例(跨网络计算器协议)✅协议代码&#xff08;Protocol.hpp&#xff09;1. 计算器协议简单介绍2. 序列化部分3. 反序列化部分4. 请求和响应数据结构5. 使用自定义协议 四、总结温馨提示 引言 在上…

Rust Tracing 入门

Tracing 是一个强大的工具&#xff0c;开发人员可以使用它来了解代码的行为、识别性能瓶颈和调试问题。 Rust 是一种以其性能和安全保证而闻名的语言&#xff0c;在它的世界中&#xff0c;跟踪在确保应用程序平稳高效运行方面发挥着至关重要的作用。 在本文中探讨Tracing 的概…

C++ 初识模板

目录 0.前言 1.泛型编程 2.函数模板 2.1概念 2.2格式 2.3原理 2.4函数模板的实例化 2.4.1隐式实例化 2.4.2显式实例化 2.5模板参数的匹配原则 3.类模板 3.1类模板的定义格式 3.2类模板的实例化 4.结语 &#xff08;图像由AI生成&#xff09; 0.前言 在 C 中&a…

Unity3D 爆火的休闲益智游戏工程源码/3D资源 大合集

Unity3D休闲益智游戏工程源码大合集 一、关卡类游戏工程源码二、跑酷类游戏工程源码三、消除合成类游戏工程源码四、棋牌类游戏工程源码五、RPG(角色扮演)类游戏工程源码六、FPS&#xff08;射击&#xff09;类游戏工程源码十、Unity3D工艺仿真六、Unity游戏资源1、Unity3D 吃鸡…

Redis数据类型——String

Redis官网指令文档&#xff1a;Commands | Docs 前言 此处的String类型是针对Redis的Value的&#xff0c;因为Key的形式都是String&#xff0c;而Value则有哈性、列表、集合等形式。 众所周知&#xff0c;由于不同编码&#xff0c;经常会出现乱码的问题&#xff0c;但在Redi…

打造稳定安全的亚马逊测评环境:关键步骤与要点一览

亚马逊测评环境的搭建是一项既复杂又需要深入细致考虑的工作&#xff0c;它涉及多方面的技术配置和资源准备。以下是一些关键步骤和要点&#xff0c;帮助您更高效地构建测评环境。 一、资源筹备 1. 养号系统&#xff1a;选择稳定、高效的养号系统&#xff0c;确保能够模拟真实…

Linux系统-进程和计划任务管理

一.程序和进程 1.程序 保持在硬盘、光盘等介质中的可执行代码和数据文件中静态保存的代码 2.进程 在CPU及内存中运行的程序代码动态执行的代码父、子进程每个程序可以创建一个或多个进程 3.进程特征 动态性&#xff1a;进程是程序的一次执行过程&#xff0c;是临时的&…

决策树分类任务实战(python 代码详解)

目录 一、导入库、数据集、并划分训练集和测试集 二、参数调优 (一)第一种调参方法&#xff1a;for循环 (1)单参数优化 ①单参数优化(无K折交叉验证) ②单参数K折交叉验证 优化 (2)多参数优化 ①多参数优化(无K折交叉验证) 参数介绍&#xff1a; ②多参数K折交叉验证…

vulfocus靶场名称: apache-cve_2021_41773/apache-cve_2021_42013

Apache HTTP Server 2.4.49、2.4.50版本对路径规范化所做的更改中存在一个路径穿越漏洞&#xff0c;攻击者可利用该漏洞读取到Web目录外的其他文件&#xff0c;如系统配置文件、网站源码等&#xff0c;甚至在特定情况下&#xff0c;攻击者可构造恶意请求执行命令&#xff0c;控…

记录一下hive启动metestore服务时报错

【背景说明】 之前hadoop有问题&#xff0c;把hadoop和MySQL删了重装&#xff0c;hive没有动&#xff0c;然后启hive的metastore服务的时候&#xff0c;显示找不到metastore数据库 【报错】 Caused by: java.lang.reflect.InvocationTargetExceptionat sun.reflect.Generated…

【Java框架】SpringMVC(一)——基本的环境搭建及基本结构体系

目录 MVC模式视图(View)控制器(Controller)模型(Model)JSP Model1JSP Model2MVC的优点MVC的缺点 Spring MVC架构介绍特点 SpringMVC环境搭建(在前面Spring整合Mybatis的基础上)1.创建控制器Controller2.创建springmvc配置文件&#xff0c;并添加Controller的Bean3.web.xml中配置…

# 从浅入深 学习 SpringCloud 微服务架构(二)模拟微服务环境(1)

从浅入深 学习 SpringCloud 微服务架构&#xff08;二&#xff09;模拟微服务环境&#xff08;1&#xff09; 段子手168 1、打开 idea 创建父工程 创建 artifactId 名为 spring_cloud_demo 的 maven 工程。 --> idea --> File --> New --> Project --> Ma…

2024 CKA 最新 | 基础操作教程(十七)

题目内容 设置配置环境&#xff1a; [candidatenode-1] $ kubectl config use-context ek8s Task 将名为 node02 的 node 设置为不可用&#xff0c;并重新调度该 node 上所有运行的 pods。 考点相关内容分析 node 在 Kubernetes&#xff08;K8s&#xff09;中&#xff0c…

VASA-1:一键生成高质量视频,颠覆你的想象!

VASA-1&#xff1a;语音生成AI视频 前言 最近&#xff0c;微软公司公布了一项图生视频的 VASA-1 框架&#xff0c;该 AI 框架只需使用一张真人肖像照片和一段个人语音音频&#xff0c;就能够生成精确逼真的相对应文本的视频&#xff0c;而且可以使表情和面部动作表现的十分自然…