【C语言项目】贪吃蛇(下)

个人主页~
源码在Gitee仓库~
上一篇贪吃蛇(上)~
贪吃蛇
- 四、核心的实现
- 游戏测试
- 1、GameStart
- (1)控制台窗口大小和名字设置
- (2)光标隐藏
- (3)打印欢迎界面
- (4)创建地图
- (5)初始化蛇
- (6)创建第一个食物
- 最终的GameStart
- 2、GameRun
- (1)定义一个宏来检测按键状态
- (2)PrintHelpInfo
- (3)SnakeMove
- (4)NextIsFood
- (5)EatFood
- (6)NoFood
- (7)KillBySelf
- (8)KillByWall
- 最终的GameRun
- 3、GameEnd
- 五、源代码拷贝
- Snake.h
- Snake.c
- game.h
- 实际运行
四、核心的实现
游戏测试
#include <locale.h>
void test()
{int ch = 0;srand((unsigned int)time(NULL));//时间戳,用来实现随机数do{Snake snake = { 0 };GameStart(&snake);GameRun(&snake);GameEnd(&snake);SetPos(20, 15);printf("再来⼀局吗?(Y/N):");ch = getchar();getchar();} while (ch == 'Y');SetPos(0, 27);}
int main()
{//修改当前地区为本地模式,为了⽀持中⽂宽字符的打印setlocale(LC_ALL, "");//测试逻辑test();return 0;
}
1、GameStart
(1)控制台窗口大小和名字设置
system("mode con cols=100 lines=30");
system("title 贪吃蛇");
(2)光标隐藏
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(houtput, &CursorInfo);CursorInfo.bVisible = false;SetConsoleCursorInfo(houtput, &CursorInfo);
(3)打印欢迎界面
void WelcomeToGame()
{SetPos(40, 15);printf("欢迎来到贪吃蛇⼩游戏");SetPos(40, 25);// “按任意键继续”的出现的位置system("pause");//可以让页面暂停在这个位置,直到用户按下一个键system("cls");//清除屏幕SetPos(25, 12);printf("⽤ ↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");SetPos(25, 13);printf("加速将能得到更⾼的分数。\n");SetPos(40, 25);// “按任意键继续”的出现的位置,这里可以让文字出现的位置看起来比较美观system("pause");system("cls");
}


(4)创建地图
组成地图的小格子需要用宽字符打印
58行就打印29次
#define WALL L'□'
//在头文件中定义
void CreateMap()
{//上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 <= 25; i++){SetPos(0, i);wprintf(L"%lc", WALL);}//右for (i = 1; i <= 25; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}

(5)初始化蛇
void InitSnake(pSnake ps)
{int i = 0;pSnakeNode cur = NULL;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));//创建蛇身节点if (cur == NULL){perror("malloc fail");exit(1);}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->_dir = RIGHT;//初始蛇的方向ps->_food_weight = 10;//每个食物的分数ps->_sleep_time = 200;//每两次打印蛇身的间隔,也就是蛇身的速度ps->_sorce = 0;//初始总分数ps->_status = OK;//蛇的初始状态
}

(6)创建第一个食物
void CreateFood(pSnake ps)
{int x = 0;int y = 0;
again: do{x = rand() % 53 + 2;//我们要的x坐标值介于2~54间,任意数%53得到的值介于0~52,加上2就在2~56范围y = rand() % 25 + 1;//我们要的y坐标值介于1~25间,任意数%25得到的值介于0~24,加上1就在1~25范围//随机数时间戳,根据时间计算的数据,由于时间是不可修改切没有相同时候的,所以它产生的数字被认为是随机数} while (x % 2 != 0);pSnakeNode cur = ps->_pSnake;//记录蛇头结点while (cur){if (x == cur->x && y == cur->y){goto again;}cur = cur->next;}//如果食物与蛇身上某一节点重合了,则回到again处重新生成pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));//不重合就生成食物if (pFood == NULL){perror("malloc fail");exit(2);}pFood->x = x;pFood->y = y;pFood->next = NULL;SetPos(x, y);wprintf(L"%lc", FOOD);//在对应位置处打印食物ps->_pFood = pFood;
}

最终的GameStart
void GameStart(pSnake ps)
{//设置控制台窗⼝的⼤⼩,30⾏,100列//mode 为DOS命令system("mode con cols=100 lines=30");//设置cmd窗⼝名称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);
}
2、GameRun
(1)定义一个宏来检测按键状态
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)&0x1) ? 1 : 0)
在上一篇博文中我们介绍了GetAsyncKeyState函数,我们封装一个宏可以判断某个键是否被按下
(2)PrintHelpInfo
void PrintHelpInfo()
{SetPos(64, 14);wprintf(L"%ls", L"不能穿墙,不能咬到自己");SetPos(64, 16);wprintf(L"%ls", L"用 ↑. ↓ . ← . → 来控制蛇的移动");SetPos(64, 18);wprintf(L"%ls", L"按F3加速,F4减速");SetPos(64, 20);wprintf(L"%ls", L"按ESC退出游戏,按空格暂停游戏");SetPos(64, 24);wprintf(L"%ls", L"s_little_monster_倾情制作");
}

(3)SnakeMove
void SnakeMove(pSnake ps)
{pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));//开辟预测的下一个节点if (pNextNode == NULL){perror("malloc fail");exit(3);}switch (ps->_dir)//用switch语句判断此时蛇的走向{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;//注意左右移动是加减2pNextNode->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);}//判断下一个位置是否为食物,是则进入EatFood,不是则进入NoFoodKillBySelf(ps);KillByWall(ps);//检查是否撞到自己或墙而死亡
}
(4)NextIsFood
int NextIsFood(pSnakeNode pn,pSnake ps)
{return (ps->_pFood->x == pn->x && ps->_pFood->y == pn->y);//如果当前位置是食物则返回非0值,不是返回0
}
(5)EatFood
void EatFood(pSnakeNode pn, pSnake ps)
{ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;//吃掉食物,让食物成为蛇的头节点free(pn);//因为节点pn与节点_pFood是一个节点,所以free掉其中的一个pn = NULL;pSnakeNode cur = ps->_pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//打印蛇身ps->_sorce += ps->_food_weight;//加分CreateFood(ps);//重新制造食物
}
(6)NoFood
void NoFood(pSnakeNode pn, pSnake ps)
{pn->next = ps->_pSnake;ps->_pSnake = pn;//同EatFood,将下一节点成为头结点pSnakeNode cur = ps->_pSnake;while (cur->next->next != NULL){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//将除了尾节点以外的节点打印SetPos(cur->next->x, cur->next->y);printf(" ");//将尾节点打印为空格free(cur->next);//free掉尾节点cur->next = NULL;
}
(7)KillBySelf
void KillBySelf(pSnake ps)
{pSnakeNode pur = ps->_pSnake->next;while (pur){//当此时的蛇头位置与蛇身某一节点重合时if (pur->x == ps->_pSnake->x && pur->y == ps->_pSnake->y){ps->_status = KILL_BY_SELF;//修改状态为 KILL_BY_SELFbreak;}pur = pur->next;}
}

(8)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;//修改状态为 KILL_BY_WALL}
}

最终的GameRun
void GameRun(pSnake ps)
{PrintHelpInfo();//游戏玩法帮助打印do{SetPos(64, 10);printf("总分数:%d\n", ps->_sorce);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();//暂停,等待再按下空格继续}else if (KEY_PRESS(VK_ESCAPE)){ps->_status = END_NORMAL;}else if (KEY_PRESS(VK_F3))//F3为加速,休眠时间变少也就是蛇的速度变快,每个食物分数增加2{if(ps->_sleep_time > 80)//速度不能太快{ps->_sleep_time -= 30;ps->_food_weight += 2;}}else if (KEY_PRESS(VK_F4))//F4为减速,休眠时间变多也就是蛇的速度变慢,每个食物分数减少2{if(ps->_food_weight > 2)//食物分数要在2分以上{ps->_sleep_time += 30;ps->_food_weight -= 2;}}SnakeMove(ps);//蛇每走一步要进行的活动Sleep(ps->_sleep_time);//走一步休眠的时间,也就是蛇的速度} while (ps->_status == OK);//当游戏状态为OK时循环继续
}
3、GameEnd
当游戏状态不为OK时,告知游戏结束的原因并释放蛇身
void GameEnd(pSnake ps)
{SetPos(24, 12);switch (ps->_status){case END_NORMAL:wprintf(L"主动结束游戏");break;case KILL_BY_SELF:wprintf(L"撞到自己了,游戏结束");break;case KILL_BY_WALL:wprintf(L"撞到墙了,游戏结束");break;}pSnakeNode pur = ps->_pSnake;while (pur){pSnakeNode del = pur;pur = pur->next;free(del);}
}
五、源代码拷贝
Snake.h
#pragma once#include <stdio.h>
#include <windows.h>
#include <stdbool.h>
#include <stdlib.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,DOWN,LEFT,RIGHT
};enum GAME_STATUS
{OK,KILL_BY_WALL,KILL_BY_SELF,END_NORMAL
};typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode, *pSnakeNode;typedef struct Snake
{pSnakeNode _pSnake;pSnakeNode _pFood;enum DRECTION _dir;enum GAME_STATUS _status;int _food_weight;int _sorce;int _sleep_time;
}Snake,*pSnake;void SetPos(short x, short y);void GameStart(pSnake ps);void CreateMap();void WelcomeToGame();void InitSnake(pSnake ps);void CreateFood(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
#include "snake.h"void SetPos(short x, short y)
{HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}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 CreateMap()
{//上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 <= 25; i++){SetPos(0, i);wprintf(L"%lc", WALL);}//右for (i = 1; i <= 25; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}
void InitSnake(pSnake ps)
{int i = 0;pSnakeNode cur = NULL;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));//创建蛇身节点if (cur == NULL){perror("malloc fail");exit(1);}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->_dir = RIGHT;//初始蛇的方向ps->_food_weight = 10;//每个食物的分数ps->_sleep_time = 200;//每两次打印蛇身的间隔,也就是蛇身的速度ps->_sorce = 0;//初始总分数ps->_status = OK;//蛇的初始状态
}void CreateFood(pSnake ps)
{int x = 0;int y = 0;
again: do{x = rand() % 53 + 2;//我们要的x坐标值介于2~54间,任意数%53得到的值介于0~52,加上2就在2~56范围y = rand() % 25 + 1;//我们要的y坐标值介于1~25间,任意数%25得到的值介于0~24,加上1就在1~25范围//随机数时间戳,根据时间计算的数据,由于时间是不可修改切没有相同时候的,所以它产生的数字被认为是随机数} while (x % 2 != 0);pSnakeNode cur = ps->_pSnake;//记录蛇头结点while (cur){if (x == cur->x && y == cur->y){goto again;}cur = cur->next;}//如果食物与蛇身上某一节点重合了,则回到again处重新生成pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));//不重合就生成食物if (pFood == NULL){perror("malloc fail");exit(2);}pFood->x = x;pFood->y = y;pFood->next = NULL;SetPos(x, y);wprintf(L"%lc", FOOD);//在对应位置处打印食物ps->_pFood = pFood;
}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);}void PrintHelpInfo()
{SetPos(64, 14);wprintf(L"%ls", L"不能穿墙,不能咬到自己");SetPos(64, 16);wprintf(L"%ls", L"用 ↑. ↓ . ← . → 来控制蛇的移动");SetPos(64, 18);wprintf(L"%ls", L"按F3加速,F4减速");SetPos(64, 20);wprintf(L"%ls", L"按ESC退出游戏,按空格暂停游戏");SetPos(64, 24);wprintf(L"%ls", L"s_little_monster_倾情制作");
}#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE)){break;}}
}int NextIsFood(pSnakeNode pn,pSnake ps)
{return (ps->_pFood->x == pn->x && ps->_pFood->y == pn->y);//如果当前位置是食物则返回非0值,不是返回0
}void EatFood(pSnakeNode pn, pSnake ps)
{ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;//吃掉食物,让食物成为蛇的头节点free(pn);//因为节点pn与节点_pFood是一个节点,所以free掉其中的一个pn = NULL;pSnakeNode cur = ps->_pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//打印蛇身ps->_sorce += ps->_food_weight;//加分CreateFood(ps);//重新制造食物
}void NoFood(pSnakeNode pn, pSnake ps)
{pn->next = ps->_pSnake;ps->_pSnake = pn;//同EatFood,将下一节点成为头结点pSnakeNode cur = ps->_pSnake;while (cur->next->next != NULL){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//将除了尾节点以外的节点打印SetPos(cur->next->x, cur->next->y);printf(" ");//将尾节点打印为空格free(cur->next);//free掉尾节点cur->next = NULL;
}void KillBySelf(pSnake ps)
{pSnakeNode pur = ps->_pSnake->next;while (pur){//当此时的蛇头位置与蛇身某一节点重合时if (pur->x == ps->_pSnake->x && pur->y == ps->_pSnake->y){ps->_status = KILL_BY_SELF;//修改状态为 KILL_BY_SELFbreak;}pur = pur->next;}
}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;//修改状态为 KILL_BY_WALL}
}void SnakeMove(pSnake ps)
{pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));//开辟预测的下一个节点if (pNextNode == NULL){perror("malloc fail");exit(3);}switch (ps->_dir)//用switch语句判断此时蛇的走向{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;//注意左右移动是加减2pNextNode->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);}//判断下一个位置是否为食物,是则进入EatFood,不是则进入NoFoodKillBySelf(ps);KillByWall(ps);//检查是否撞到自己或墙而死亡
}void GameRun(pSnake ps)
{PrintHelpInfo();//游戏玩法帮助打印do{SetPos(64, 10);printf("总分数:%d\n", ps->_sorce);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();//暂停,等待再按下空格继续}else if (KEY_PRESS(VK_ESCAPE)){ps->_status = END_NORMAL;}else if (KEY_PRESS(VK_F3))//F3为加速,休眠时间变少也就是蛇的速度变快,每个食物分数增加2{if(ps->_sleep_time > 80)//速度不能太快{ps->_sleep_time -= 30;ps->_food_weight += 2;}}else if (KEY_PRESS(VK_F4))//F4为减速,休眠时间变多也就是蛇的速度变慢,每个食物分数减少2{if(ps->_food_weight > 2)//食物分数要在2分以上{ps->_sleep_time += 30;ps->_food_weight -= 2;}}SnakeMove(ps);//蛇每走一步要进行的活动Sleep(ps->_sleep_time);//走一步休眠的时间,也就是蛇的速度} while (ps->_status == OK);//当游戏状态为OK时循环继续
}void GameEnd(pSnake ps)
{SetPos(24, 12);switch (ps->_status){case END_NORMAL:wprintf(L"主动结束游戏");break;case KILL_BY_SELF:wprintf(L"撞到自己了,游戏结束");break;case KILL_BY_WALL:wprintf(L"撞到墙了,游戏结束");break;}pSnakeNode pur = ps->_pSnake;while (pur){pSnakeNode del = pur;pur = pur->next;free(del);}
}
game.h
#include "snake.h"
#include <locale.h>
void test()
{int c = 0;do{system("cls");Snake snake = { 0 };GameStart(&snake);GameRun(&snake);GameEnd(&snake);SetPos(20, 15);printf("再来一局吗?(Y/N):");c = getchar();while (getchar() != '\n');} while (c == 'Y');SetPos(0, 27);
}int main()
{setlocale(LC_ALL, "");//本地化srand((unsigned int)time(NULL));//时间戳随机数test();return 0;
}
实际运行
贪吃蛇的实际运行
今日分享就到这里了~

相关文章:
【C语言项目】贪吃蛇(下)
个人主页~ 源码在Gitee仓库~ 上一篇贪吃蛇(上)~ 贪吃蛇 四、核心的实现游戏测试1、GameStart(1)控制台窗口大小和名字设置(2)光标隐藏(3)打印欢迎界面(4)创建…...
【Unity实战|热更】Addressable读取SO文件报错解决
情景再现 假定你有一个Unity工程,使用了HybridCLR和Addressable,SO文件存放在Addressable中。热更加载后进入游戏场景出现了SO文件读取报错: UnityEngine.AddressableAssets.InvalidKeyException: Exception of type UnityEngine.Addressab…...
Web自动化 - selenium
文章目录 一、selenium的使用selenium的安装 二、元素1. 定位选择元素1.id 定位2. class_name 定位find_element 和 find_elements的区别3. TAG_NAME 定位4. 超链接 定位 2. 操控元素1. 查询内容2. 获取元素文本内容3. 获取元素属性 3. 浏览器常用操作API4. 鼠标操作 - perform…...
基于select for update 实现数据库分布式锁
1、select for update 的基本语法 SELECT * FROM table_name WHERE condition FOR UPDATE;2、select for update 的定义及作用 2.1 、select for update的含义是在查询数据的同时对所选的数据行进行锁定,以保证数据的一致性和并发控制。在并发环境下,多…...
Java后端实现对象与文件接收数据(minio测试)
实现思路: 1. 两个接口实现,一个接对象数据(file),一个接文件数据(json)。 2. json对象(base64String) 实体类信息 ,请求体统一接收 3. file, String name ,String password ,String name , Controller层接收 统一…...
考研踩坑经验分享
文章目录 写在前面自身情况简介自身学习路线优点坑点 学习路线建议1、2和3月份3、4和5月份6、7和8月份9、10月份11、12月份 一些私货建议结尾 写在前面 考研是一件非常有盼头的事,但绝对不是一件容易的事。 如果你不能做好来年三月份出成绩时,坦然接受…...
Android Compose 一:基础控件
Flutter 与 Compose 组件辣么像,难道是同一个google团队整的;也未深究,只是猜测。 创建项目 需要使用新版本Android studio,忽略步骤… 项目目录 MainActivity说明 1 系统默认页面 Preview 修饰的方法,只用来供开发…...
python3.12.0 在Linux 制作镜像包 部署到docker 全过程
项目结构: 比如,在pycharm里需要运行 themain.py 1、上传Linux的目录结构: Dockerfile 文件需要制作: 这里是关键: #基于的基础镜像 FROM python:3.12.0 #代码添加到code文件夹 ADD ./EF_NFCS /code #设置code文…...
STM32理论 —— μCOS-Ⅲ(新)
文章目录 1. 任务调度器1.1 抢占式调度 μCos-Ⅲ全称是Micro C OS Ⅲ,由Micriμm 公司发布的一个基于C 语言编写的第三代小型实时操作系统(RTOS); RTOS 与裸机相比最大的优势在于多任务管理与实时性,它提供了多任务管理和任务间通信的功能&a…...
衢州知识付费系统报价,教师如何做精品课程?怎么创造精品课程?
精品课程对于学生的意义来说是不同的,越是精品让学习的人就越觉得值得,所以,做为教师来说,做出精品课程不仅仅是对学生负责,也是对自己负责,那如何做精品课程?相信很多教师们也想知道。 如何创造精品课程?…...
在Vue中,可以通过使用<slot>元素和name属性来创建具名插槽。这样您就可以为一个组件的不同部分定义不同的内容。 以下是一个简单的示例:
在Vue中,可以通过使用元素和name属性来创建具名插槽。这样您就可以为一个组件的不同部分定义不同的内容。 以下是一个简单的示例: <template><div><header><slot name"header"></slot></header><mai…...
C++笔试强训day19
目录 1.小易的升级之路 2.礼物的最大价值 3.对称之美 1.小易的升级之路 链接 模拟就行,唯一可能是难点得就是gcd(最大公约数) #include <iostream> using namespace std; #define int long long const int N 1e5 10; int arr[N];…...
MySQL软件安装基于压缩包
打开mysql官网网址 MySQL :: Download MySQL Community Server 本次针对版本8的安装包方式进行安装,下载成功后接下来对MySQL进行安装 下载后有一个以zip后缀结尾的压缩包文件 对于安装包方式安装,比起可视化安装省去了许多安装步骤,这里直接…...
04 贝尔曼最优公式
贝尔曼最优公式 前言1、Motivating examples2、Definition of optimal policy3、Bellman optimality equation(BOE):Introduction4、 BOE:Maximization on the right-hand side5、BOE:Rewrite as v f(v)6、Contraction mapping theorem7、BO…...
印象笔记使用技巧
印象笔记(Evernote)是一款广泛使用的笔记应用,它帮助用户整理个人信息、文件和备忘录。以下是一些提高在印象笔记中效率的使用技巧: ### 1. 使用标签和笔记本组织笔记 - **建立笔记本**:为不同的项目或类别创建笔记本…...
产品设计中的“注册”说明
在使用网站或应用的时候必不可少的就是账号系统,账号系统有些人可能觉得简单,无非就是账号密码。真的是这样吗? 一个完整的账号系统通常大家会分成四部分: 1.注册(手机号、邮箱、用户名/密码限制/验证码)…...
【linux学习】多线程(1)
文章目录 线程的概念线程与进程 线程的用法线程的创建多线程 线程的等待线程锁死锁 线程的概念 在Linux中,线程(Thread)是程序执行流的最小单位,是进程中的一个实体,负责在程序中执行代码。线程本身不拥有系统资源&…...
Leetcode 3149. Find the Minimum Cost Array Permutation
Leetcode 3149. Find the Minimum Cost Array Permutation 1. 解题思路2. 代码实现 题目链接:3149. Find the Minimum Cost Array Permutation 1. 解题思路 这一题的话就是一个动态规划的问题,不过他这个错位着实是把题目变得复杂了不少,唉…...
Python | 为列表中的元素分配唯一值
我们可以给列表中的所有数字分配一个唯一的值,重复时它会保留给它的值。这是一个非常常见的问题,在Web开发中,处理物品id时会遇到。让我们讨论一下解决这个问题的一些方法。 1. 使用enumerate() 列表解析 # initializing list test_list …...
HTML炫酷的相册
目录 写在前面 HTML简介 完整代码 代码分析 系列推荐 写在最后 写在前面 本期小编给大家带来一个炫酷的旋转相册,快来解锁属于你的独家记忆吧! HTML简介 HTML(全称为超文本标记语言)是一种用于创建网页结构和内容的标记语…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
React核心概念:State是什么?如何用useState管理组件自己的数据?
系列回顾: 在上一篇《React入门第一步》中,我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目,并修改了App.jsx组件,让页面显示出我们想要的文字。但是,那个页面是“死”的,它只是静态…...
React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?
系列回顾: 在上一篇《React核心概念:State是什么?》中,我们学习了如何使用useState让一个组件拥有自己的内部数据(State),并通过一个计数器案例,实现了组件的自我更新。这很棒&#…...
