当前位置: 首页 > news >正文

贪吃蛇——c语言版

文章目录

  • 演示效果
  • 实现的基本功能
  • 技术要点
  • 源代码
  • 实现功能
    • GameStart
      • 打印欢迎界面和功能介绍
      • 绘制地图
      • 创建蛇
      • 创建食物
    • GameRun
      • 打印提示信息
      • 蛇每走一步
    • GameEnd
    • 蛇死亡后继续游戏

演示效果

贪吃蛇1.0演示视频


在这里插入图片描述
将终端应用程序改为控制台主机

实现的基本功能

  1. 贪吃蛇地图绘制
  2. 蛇吃食物的功能(上、下、左、右⽅向键控制蛇的动作)
  3. 蛇撞墙死亡
  4. 蛇撞⾃⾝死亡
  5. 计算得分
  6. 蛇⾝加速、减速
  7. 暂停游戏

技术要点

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

源代码

snake.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <locale.h>
#include <stdbool.h>
#include <time.h>
#include <stdbool.h>
#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)
#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'
#define POS_X 24
#define POS_Y 5
enum DIRECTION
{UP = 1,DOWN,LEFT,RIGHT
};
enum CONDITION
{ 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 pSnakebody;//指向蛇头的节点pSnakeNode pFood;//指向食物的节点enum DIRECTION Dir;//方向enum CONDITION Cdt;//状态int Food_Weight;//食物的权重int Socre;//总分数int Sleep_Time;//睡眠时间
}Snake,* pSnake;
//初始化
void GameStart(pSnake ps);
//定位
void SetPos(short x, short y);
//打印欢迎界面和功能介绍
void  Welcome_To_Game();
//绘制地图
void CreateMap();
//创建蛇
void InitSnake(pSnake ps);
//创建食物
void CreateFood(pSnake ps);
//运行游戏
void GameRun(pSnake ps);
//打印提示信息
void PrintHelpInfo();
//蛇走的过程
void SnakeMove(pSnake ps);
//判断下一个节点是不是食物
bool NextIsFood(pSnakeNode pn,pSnake ps);
//如果是食物,就吃掉,然后创建新的食物
void EatFood(pSnakeNode pn,pSnake ps);
//如果不是食物,就把最后一个节点释放
void NotFood(pSnakeNode pn, pSnake ps);
//判断下一步是否撞墙
void KillByWall(pSnake ps);
//判断下一步是否撞到自己
void KillBySelf(pSnake ps);
//善后工作
void GameEnd(pSnake ps);

snake.c

#define   _CRT_SECURE_NO_WARNINGS 1
#include "Snake.h"
void CreateFood(pSnake ps)
{int x = 0;int y = 0;//食物的坐标在棋盘内
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//食物不能和蛇身冲突pSnakeNode cur = ps->pSnakebody;while (cur){if (cur->x == x && cur->y == y){goto again;}cur = cur->next;}//创建食物pSnakeNode Food = (pSnakeNode)malloc(sizeof(SnakeNode));if (Food == NULL){perror("malloc fail");return;}Food->next = NULL;Food->x = x;Food->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);ps->pFood = Food;
}
void SetPos(short x, short y)
{HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}
void InitSnake(pSnake ps)
{ps->pSnakebody = NULL;pSnakeNode cur = NULL;for (int i = 0; i < 5; i++){//创建蛇身节点cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("malloc fail");return;}//设置坐标cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;//头插if (ps->pSnakebody == NULL){ps->pSnakebody = cur;}else{cur->next = ps->pSnakebody;ps->pSnakebody = cur;}}//打印身体cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//初始化贪吃蛇的数据ps->Cdt = OK;ps->Dir = RIGHT;ps->Food_Weight = 10;ps->Socre = 0;ps->Sleep_Time = 200;//单位毫秒
}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 Welcome_To_Game()
{SetPos(40, 14);printf("欢迎来到贪食蛇小游戏");SetPos(40, 25);system("pause");system("cls");SetPos(25, 14);printf("用↑ . ↓ . ← . → 分别控制蛇的移动,F1为加速,");SetPos(25, 15);printf("F2为减速,加速将得到更高的分数");SetPos(40, 24);system("pause");system("cls");
}
void GameStart(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定义光标信息结构体CONSOLE_CURSOR_INFO CursorInfo;//获取光标信息GetConsoleCursorInfo(houtput, &CursorInfo);//修改CursorInfo.bVisible = false;//设置SetConsoleCursorInfo(houtput, &CursorInfo);//打印欢迎界面和功能介绍Welcome_To_Game();//绘制地图CreateMap();//创建蛇InitSnake(ps);//创建食物CreateFood(ps);
}
//打印提示信息
void PrintHelpInfo()
{SetPos(60, 15);printf("不能穿墙,不能咬到自己");SetPos(60, 16);printf("用 ↑.↓.←.→ 分别控制蛇的移动,");SetPos(60, 17);printf("F1为加速,F2为减速,加速将得到更高的分数");SetPos(60, 18);printf("ESC:退出游戏,SPACE:暂停游戏");SetPos(60, 20);printf("我爱吃福鼎肉片@版权");
}
//暂停
void pause()
{while (1){Sleep(300);if (KEY_PRESS(VK_SPACE)){break;}}
}
//判断下一个节点是不是食物
bool NextIsFood(pSnakeNode pn, pSnake ps)
{return (pn->x == ps->pFood->x && pn->y == ps->pFood->y);
}
//如果是食物,就吃掉,然后创建新的食物
void EatFood(pSnakeNode pn, pSnake ps)
{//头插ps->pFood->next = ps->pSnakebody;ps->pSnakebody = ps->pFood;//释放下一个位置的节点free(pn);pn = NULL;//打印pSnakeNode cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Socre += ps->Food_Weight;CreateFood(ps);
}
//如果不是食物,就把最后一个节点释放
void NotFood(pSnakeNode pn, pSnake ps)
{//头插pn->next = ps->pSnakebody;ps->pSnakebody = pn;//最后一个节点,要释放pSnakeNode cur = ps->pSnakebody;while (cur->next->next)//打印前n个{SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//释放最后一个SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}
//判断下一步是否撞墙
void KillByWall(pSnake ps)
{if (ps->pSnakebody->x == 56|| ps->pSnakebody->x == 0|| ps->pSnakebody->y == 0|| ps->pSnakebody->y == 26){ps->Cdt = KILL_BY_WALL;}
}
//判断下一步是否撞到自己
void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->pSnakebody->next;while (cur){if (cur->x == ps->pSnakebody->x && cur->y == ps->pSnakebody->y){ps->Cdt = KILL_BY_SELF;}cur = cur->next;}
}
//蛇走的过程
void SnakeMove(pSnake ps)
{//创建下一个节点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("pNextNode malloc fail");return;}switch (ps->Dir){case UP://向上pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y - 1;break;case DOWN://向下pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y + 1;break;case LEFT://向左pNextNode->x = ps->pSnakebody->x - 2;pNextNode->y = ps->pSnakebody->y;break;case RIGHT://向右pNextNode->x = ps->pSnakebody->x + 2;pNextNode->y = ps->pSnakebody->y;break;}//判断下一个节点是不是食物if (NextIsFood(pNextNode, ps)){EatFood(pNextNode, ps);}else{NotFood(pNextNode, ps);}KillByWall(ps);//下一步是墙KillBySelf(ps);//下一步是自己}//运行游戏
void GameRun(pSnake ps)
{PrintHelpInfo();do{SetPos(60, 10);printf("食物分数:%2d", ps->Food_Weight);SetPos(60, 11);printf("总分数:%2d", ps->Socre);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_ESCAPE)){ps->Cdt = END_NORMAL;break;}else if (KEY_PRESS(VK_SPACE)){pause();}else if (KEY_PRESS(VK_F1)){if (ps->Sleep_Time > 80){ps->Sleep_Time -= 30;ps->Food_Weight += 2;}}else if (KEY_PRESS(VK_F2)){if (ps->Sleep_Time < 320){ps->Sleep_Time += 30;ps->Food_Weight -= 2;}}//让蛇走起来SnakeMove(ps);Sleep(ps->Sleep_Time);} while (ps->Cdt == OK);}
//善后工作
void GameEnd(pSnake ps)
{SetPos(20, 12);switch (ps->Cdt){case END_NORMAL:printf("您主动结束了游戏");break;case KILL_BY_WALL:printf("您撞到墙死了");break;case KILL_BY_SELF:printf("您咬到了自己");}//释放蛇身节点pSnakeNode cur = ps->pSnakebody;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

snaketest.c

#define   _CRT_SECURE_NO_WARNINGS 1
#include "Snake.h"void test()
{int ch = 0;do{system("cls");Snake snake;GameStart(&snake);GameRun(&snake);GameEnd(&snake);SetPos(20, 14);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;//初始化游戏//运行游戏//结束游戏
}

实现功能

在地图上我们打印墙体、蛇、食物都是使用宽字符,普通字符只占字节,宽字符占两个
中文也是两个宽字符,所以我们本地化所有类项即可

setlocale(LC_ALL, "");

再实现功能以前,我们可以将要实现的功能分成三大类:
GameStart(初始化游戏)
GameRun(运行游戏)
GameEnd(游戏善后工作)

GameStart

再绘制地图以前,我们需要设置控制台窗口的长宽:100列,30行
顺便设置窗口的名字为贪吃蛇

void GameStart(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");
}

隐藏光标并且获得句柄

void GameStart(pSnake ps)
{system("mode con cols=100 lines=30");system("title 贪吃蛇");//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定义光标信息结构体CONSOLE_CURSOR_INFO CursorInfo;//获取光标信息GetConsoleCursorInfo(houtput, &CursorInfo);//修改CursorInfo.bVisible = false;//设置SetConsoleCursorInfo(houtput, &CursorInfo);
}

修改光标位置

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

打印欢迎界面和功能介绍

前面提到如何定位光标位置,在每一页打印完以后暂停,并且清理该页,才会接着打印下一页

void Welcome_To_Game()
{SetPos(40, 14);printf("欢迎来到贪食蛇小游戏");SetPos(40, 25);system("pause");system("cls");SetPos(25, 14);printf("用↑ . ↓ . ← . → 分别控制蛇的移动,F1为加速,");SetPos(25, 15);printf("F2为减速,加速将得到更高的分数");SetPos(40, 24);system("pause");system("cls");
}

绘制地图

因为在后续功能中经常要用到各种图案,我们就统一在头文件里定义好

#define WALL L'□'
#define BODY L'●'
#define FOOD 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);}}

创建蛇

#define POS_X 24
#define POS_Y 5
void InitSnake(pSnake ps)
{ps->pSnakebody = NULL;pSnakeNode cur = NULL;for (int i = 0; i < 5; i++){//创建蛇身节点cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("malloc fail");return;}//设置坐标cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;//头插if (ps->pSnakebody == NULL){ps->pSnakebody = cur;}else{cur->next = ps->pSnakebody;ps->pSnakebody = cur;}}//打印身体cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//初始化贪吃蛇的数据ps->Cdt = OK;ps->Dir = RIGHT;ps->Food_Weight = 10;ps->Socre = 0;ps->Sleep_Time = 200;//单位毫秒
}

创建食物

棋盘大小:
在这里插入图片描述
要注意食物的范围

void CreateFood(pSnake ps)
{int x = 0;int y = 0;//食物的坐标在棋盘内随机生成
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//食物不能和蛇身冲突pSnakeNode cur = ps->pSnakebody;while (cur){if (cur->x == x && cur->y == y){goto again;}cur = cur->next;}//创建食物pSnakeNode Food = (pSnakeNode)malloc(sizeof(SnakeNode));if (Food == NULL){perror("malloc fail");return;}Food->next = NULL;Food->x = x;Food->y = y;SetPos(x, y);wprintf(L"%lc", FOOD);ps->pFood = Food;
}

GameRun

打印提示信息

在这里插入图片描述

//打印提示信息
void PrintHelpInfo()
{SetPos(60, 15);printf("不能穿墙,不能咬到自己");SetPos(60, 16);printf("用 ↑.↓.←.→ 分别控制蛇的移动,");SetPos(60, 17);printf("F1为加速,F2为减速,加速将得到更高的分数");SetPos(60, 18);printf("ESC:退出游戏,SPACE:暂停游戏");SetPos(60, 20);printf("我爱吃福鼎肉片@版权");
}

蛇每走一步

当蛇正在向某个方向走时,不能操控蛇走相反方向!

#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)
//运行游戏
void GameRun(pSnake ps)
{PrintHelpInfo();do{SetPos(60, 10);printf("食物分数:%2d", ps->Food_Weight);SetPos(60, 11);printf("总分数:%2d", ps->Socre);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_ESCAPE)){ps->Cdt = END_NORMAL;break;}else if (KEY_PRESS(VK_SPACE)){pause();}else if (KEY_PRESS(VK_F1)){if (ps->Sleep_Time > 80){ps->Sleep_Time -= 30;ps->Food_Weight += 2;}}else if (KEY_PRESS(VK_F2)){if (ps->Sleep_Time < 320){ps->Sleep_Time += 30;ps->Food_Weight -= 2;}}//让蛇走起来SnakeMove(ps);Sleep(ps->Sleep_Time);} while (ps->Cdt == OK);//状态为OK才能走}

当蛇走向下一个节点时,要分为两种情况

  1. 下个节点是食物
  2. 下个节点不是食物
//蛇走的过程
void SnakeMove(pSnake ps)
{//创建下一个节点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("pNextNode malloc fail");return;}switch (ps->Dir){case UP://向上pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y - 1;break;case DOWN://向下pNextNode->x = ps->pSnakebody->x;pNextNode->y = ps->pSnakebody->y + 1;break;case LEFT://向左pNextNode->x = ps->pSnakebody->x - 2;pNextNode->y = ps->pSnakebody->y;break;case RIGHT://向右pNextNode->x = ps->pSnakebody->x + 2;pNextNode->y = ps->pSnakebody->y;break;}//判断下一个节点是不是食物if (NextIsFood(pNextNode, ps)){EatFood(pNextNode, ps);}else{NotFood(pNextNode, ps);}KillByWall(ps);//下一步是墙KillBySelf(ps);//下一步是自己}
  1. 下个节点是食物
    先判断一下
//判断下一个节点是不是食物
bool NextIsFood(pSnakeNode pn, pSnake ps)
{return (pn->x == ps->pFood->x && pn->y == ps->pFood->y);
}
//如果是食物,就吃掉,然后创建新的食物
void EatFood(pSnakeNode pn, pSnake ps)
{//头插ps->pFood->next = ps->pSnakebody;ps->pSnakebody = ps->pFood;//释放下一个位置的节点free(pn);pn = NULL;//打印pSnakeNode cur = ps->pSnakebody;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->Socre += ps->Food_Weight;CreateFood(ps);
}

为什么释放下一个位置的节点,有些同学有疑问
因为在CreateFood函数中,已经将ps->Food指向了食物节点,所以下一个位置的节点用不上的,当然要释放掉,因此,使用下一个位置的节点,释放食物节点也是可以的。
2. 下一个节点不是食物
在这里插入图片描述

//如果不是食物,就把最后一个节点释放
void NotFood(pSnakeNode pn, pSnake ps)
{//头插pn->next = ps->pSnakebody;ps->pSnakebody = pn;//最后一个节点,要释放pSnakeNode cur = ps->pSnakebody;while (cur->next->next)//打印前n个{SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//释放最后一个SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}

除了食物,还要判断下一个是否撞墙或者咬到自己

//判断下一步是否撞墙
void KillByWall(pSnake ps)
{if (ps->pSnakebody->x == 56|| ps->pSnakebody->x == 0|| ps->pSnakebody->y == 0|| ps->pSnakebody->y == 26){ps->Cdt = KILL_BY_WALL;}
}
//判断下一步是否撞到自己
void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->pSnakebody->next;while (cur){if (cur->x == ps->pSnakebody->x && cur->y == ps->pSnakebody->y){ps->Cdt = KILL_BY_SELF;}cur = cur->next;}
}

GameEnd

在这里插入图片描述

//善后工作
void GameEnd(pSnake ps)
{SetPos(20, 12);switch (ps->Cdt){case END_NORMAL:printf("您主动结束了游戏");break;case KILL_BY_WALL:printf("您撞到墙死了");break;case KILL_BY_SELF:printf("您咬到了自己");}//释放蛇身节点pSnakeNode cur = ps->pSnakebody;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

蛇死亡后继续游戏

到此还没有结束,如果玩家还想在玩一把呢,总不能关闭应用再重新点开吧

void test()
{int ch = 0;do{system("cls");Snake snake;GameStart(&snake);GameRun(&snake);GameEnd(&snake);SetPos(20, 14);printf("再来一局吗?(Y/N):");ch = getchar();while (getchar() != '\n');//如果输入yyyy一样可以读取} while (ch == 'Y' || ch == 'y');SetPos(0, 27);
}

在这里插入图片描述
希望这篇博客对你有所帮助!!!如果有不懂或者有错的地方欢迎私信探讨!

相关文章:

贪吃蛇——c语言版

文章目录 演示效果实现的基本功能技术要点源代码实现功能GameStart打印欢迎界面和功能介绍绘制地图创建蛇创建食物 GameRun打印提示信息蛇每走一步 GameEnd蛇死亡后继续游戏 演示效果 贪吃蛇1.0演示视频 将终端应用程序改为控制台主机 实现的基本功能 贪吃蛇地图绘制蛇吃食物的…...

ctr/cvr预估之WideDeep模型

ctr/cvr预估之Wide&Deep模型 在探索点击率&#xff08;CTR&#xff09;和转化率&#xff08;CVR&#xff09;预估的领域中&#xff0c;我们始终追求的是一种既能捕获数据中的线性关系&#xff0c;又能发现复杂模式的模型。因子分解机&#xff08;Factorization Machines, …...

快速生成基于vue-element的后台管理框架,实现短时间二次开发

你是否遇到过当你想要独立开发一个项目时对反复造轮子的烦扰&#xff1f; 这种流水线的操作实在让人受不了 而vue-element-template很好的帮你解决了这个烦恼 只需克隆下来&#xff0c;改改图标&#xff0c;模块名&#xff0c;甚至样式&#xff0c;就会变成一个全新的自己的项目…...

PCIe 7.0 要来了,一文看懂PCIe发展和技术

PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;&#xff0c;即外围组件高速串行扩展总线标准&#xff0c;自其诞生以来&#xff0c;已成为计算机硬件中不可或缺的一部分。它以其高速串行通信能力和不断演进的技术规范&#xff0c;满足了日益增长的数据…...

API-事件类型

学习目标&#xff1a; 掌握事件类型 学习内容&#xff1a; 事件类型鼠标事件焦点事件键盘事件文本事件focus选择器案例 事件类型&#xff1a; 鼠标事件&#xff1a; <title>事件类型-鼠标事件</title><style>div {width: 200px;height: 200px;background-c…...

解决poweroff时需要等待其他服务关闭问题

当我们在执行poweroff或者reboot时会出现某个服务需要等待才能关闭系统,这个时候就可以在服务中添加如下: After=shutdown.target Conflicts=reboot.target halt.target poweroff.target Before=shutdown.target reboot.target halt.target poweroff.target具体实例: [Uni…...

ThinkPHP-导入Excel表格(通用版)

一、版本说明 1.PHP8.2、MySQL8.0、ThinkPHP8.0 2.使用前安装phpspreadsheet composer require phpoffice/phpspreadsheet 二、技术说明 因本人采用前后端分离&#xff0c;因此上传文件以及导入表格为分离开发&#xff0c;如无需分离开发则自行合并开发即可。 1.第一步&a…...

毕昇jdk教程

毕昇jdk教程指南链接&#xff1a;Wiki - Gitee.com...

【R语言】地理探测器模拟及分析(Geographical detector)

地理探测器模拟及分析 1. 写在前面2. R语言实现2.1 数据导入2.2 确定数据离散化的最优方法与最优分类2.3 分异及因子探测器&#xff08;factor detector&#xff09;2.4 生态探测器&#xff08;ecological detector&#xff09;2.5 交互因子探测器&#xff08;interaction dete…...

深入理解Qt属性系统[Q_PROPERTY]

Qt 属性系统是 Qt 框架中一个非常核心和强大的部分&#xff0c;它提供了一种标准化的方法来访问对象的属性。这一系统不仅使得开发者能够以一致的方式处理各种数据类型&#xff0c;还为动态属性的管理提供了支持&#xff0c;并与 Qt 的元对象系统紧密集成。在这篇文章中&#x…...

【C语言课程设计】员工信息管理系统

员工信息管理系统 在日常的企业管理中&#xff0c;员工信息的管理显得尤为重要。为了提高员工信息管理的效率&#xff0c;我们设计并实现了一个简单的员工信息管理系统。该系统主要使用C语言编写&#xff0c;具备输入、显示、查询、更新&#xff08;增加、删除、修改&#xff…...

「动态规划」如何求最长递增子序列的长度?

300. 最长递增子序列https://leetcode.cn/problems/longest-increasing-subsequence/description/ 给你一个整数数组nums&#xff0c;找到其中最长严格递增子序列的长度。子序列是由数组派生而来的序列&#xff0c;删除&#xff08;或不删除&#xff09;数组中的元素而不改变其…...

深度神经网络DNN概念科普

深度神经网络DNN概念科普 深度神经网络&#xff08;Deep Neural Network, DNN&#xff09;是机器学习领域中一类具有多层结构的神经网络模型&#xff0c;它能够通过学习数据中的复杂模式来解决非线性问题。下面是对深度神经网络的详细解析&#xff1a; 基本组成部分 输入层&…...

Tomcat WEB站点部署

目录 1、使用war包部署web站点 2、自定义默认网站目录 3、部署开源站点&#xff08;jspgou商城&#xff09; 对主机192.168.226.22操作 对主机192.168.226.20操作 上线的代码有两种方式&#xff1a; 第一种方式是直接将程序目录放在webapps目录下面&#xff0c;这种方式…...

IPv6 中 MAC 33:33 的由来

一、33:33 由来 1. RFC9542 - 2024-05-02 Note IANA allocates addresses under the IANA OUI (00-00-5E) as explained in [RFC9542]. Unicast addresses under the IANA OUI start with 00-00-5E, while multicast addresses under the IANA OUI start with 01-00-5E. In t…...

告别手动邮件处理:使用imbox库轻松管理你的收件箱

imbox库简介&#xff1a; imbox是一个强大的Python库,专为与IMAP服务器交互而设计.IMAP&#xff08;Internet Message Access Protocol&#xff09;是一种用于电子邮件的标准协议,允许用户在远程服务器上管理邮件.imbox库通过IMAP协议与邮件服务器通信,帮助用户轻松地读取、搜索…...

Ubuntu 18.04 安装 PCL 1.14.1

在进行科研项目时&#xff0c;我们常常需要将 C 和 Python 结合起来编程。然而&#xff0c;每次将 PCL&#xff08;Point Cloud Library&#xff09;的内容添加到 CMakeLists.txt 文件中时都会报错。在深入分析后&#xff0c;我们推测可能是当前使用的 PCL 1.8 版本与现有程序不…...

公司logo设计大全怎么找?直接帮你设计logo

公司logo设计大全怎么找&#xff1f;在品牌塑造的过程中&#xff0c;Logo无疑是至关重要的一环。一个优秀的Logo不仅能够有效传达公司的核心理念和品牌形象&#xff0c;还能在消费者心中留下深刻的印象。然而&#xff0c;对于许多初创公司或小型企业来说&#xff0c;制作出适合…...

如何调整C#中数组的大小

前言 数组存储多个相同类型的一种非常常用的数据结构。它长度是固定&#xff0c;也就是数组一旦创建大小就固定了。C# 数组不支持动态长度。那在C#中是否有方法可以调整数组大小呢&#xff1f;本文将通过示例介绍一种调整一维数组大小的方法。 方法 数组实例是从 System.Arr…...

通过言语和非言语检索线索描绘睡眠中的记忆再激活茗创科技茗创科技

摘要 睡眠通过重新激活新形成的记忆痕迹来巩固记忆。研究睡眠中记忆再激活的一种方法是让睡眠中的大脑再次暴露于听觉检索线索(定向记忆再激活范式)。然而&#xff0c;记忆线索的声学特性在多大程度上影响定向记忆再激活的有效性&#xff0c;目前还没有得到充分探索。本研究通…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

关于easyexcel动态下拉选问题处理

前些日子突然碰到一个问题&#xff0c;说是客户的导入文件模版想支持部分导入内容的下拉选&#xff0c;于是我就找了easyexcel官网寻找解决方案&#xff0c;并没有找到合适的方案&#xff0c;没办法只能自己动手并分享出来&#xff0c;针对Java生成Excel下拉菜单时因选项过多导…...

DBLP数据库是什么?

DBLP&#xff08;Digital Bibliography & Library Project&#xff09;Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高&#xff0c;数据库文献更新速度很快&#xff0c;很好地反映了国际计算机科学学术研…...

ubuntu22.04 安装docker 和docker-compose

首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...