CC++:贪吃蛇小游戏教程
❀创作不易,关注作者不迷路❀😀😀
目录
😀贪吃蛇简介
😃贪吃蛇的实现
🐍生成地图
🐍生成蛇模块
❀定义蛇的结构体
❀初始化蛇的相关信息
❀初始化食物的相关信息
🐍光标定位和隐藏
❀如何隐藏光标
❀如何定位光标
🐍蛇的移动
❀Sleep()函数:一个让程序暂停的函数
❀删除轨迹
🐍控制键盘改变蛇的移动方向
🐍吃食物获得积分
🐍蛇死亡,结束游戏
😀完整代码
😀拓展
😀贪吃蛇简介
贪吃蛇是一款经典的小游戏,通过控制蛇头方向吃食物,使得蛇🐍变长,从而获得积分,通过上下左右键控制蛇的移动方向,寻找吃的东西,每吃到一口就能得到一定的积分,而且蛇的身子会越来越长,难度也越来越大,不能碰墙,也不能咬到自己的身体和尾巴,否则游戏结束,总体来说这款小游戏既简单又耐玩,至今仍是一款风靡全球的小游戏,也是编程入门学习的热门小游戏,今天将带领大家实现这款小游戏
😃贪吃蛇的实现
🐍生成地图
首先生成一张长为60,宽为20的地图
生成地图,只有在边界时输出“+”,其余地方输出“ ”
#define H 20
#define W 60void show_wall()
{for (int i = 0; i <= H; i++){for (int j = 0; j <= W; j++){if (i == H || j == W)printf("+");else printf(" ");}puts("");}}
🐍生成蛇模块
❀定义蛇的结构体
typedef struct body {//记录坐标int x; int y;
}BODY;typedef struct snake {int size;//蛇的长度BODY list[W * H];//蛇的位置,最大可以铺满整个墙 BODY food;//定义BODY类型的food变量,存储食物的位置信息COORD coord;//光标相关的结构体,不需要自己写,是本来就有的int dx;//x轴移动方向 int dy;//y轴移动方向 int score;//分数 BODY tail;//记录尾巴的位置,后续蛇的移动需要
}SNAKE;
❀初始化蛇的相关信息
初始化时蛇的长度为2,并且在地图最中间生成蛇🐍
void init_snake(SNAKE* snake)
{snake->size = 2;//初始化蛇的长度为2,头和尾长度为2//使蛇🐍在地图最中间生成snake->list[0].x = W / 2; snake->list[1].x = W / 2 - 1;snake->list[0].y = H / 2; snake->list[1].y = H / 2;snake->score = 0;//初始分数为0snake->dx = 1; snake->dy = 0;//初始移动方向:向右移动init_food(&(snake->food));//初始化食物
}
❀初始化食物的相关信息
食物在地图内随机生成,因此要调用随机数生成函数rand()
所需头文件
#include<time.h>
void init_food(BODY* food)
{srand(time(NULL));food->x = rand() % W;food->y = rand() % H;while (food->x == 0 || food->y == 0){food->x = rand() % W;food->y = rand() % H;}
}
生成的食物x轴范围在(0,W-1],y轴范围在(0,H-1],但仅仅对W和H取模是有可能生成在边界(x==0或y==0)的食物,因此生成时不满足条件则再次生成食物
🐍光标定位和隐藏
打印地图之后,我们看到光标在“按任意键关闭此窗口...”这里,而且在不停的闪烁,光标在地图中闪烁并不美观,所以我们需要加以隐藏光标,同时,还需要定位光标到指定位置,比如后续的蛇的移动,食物的生成都需要光标定位
❀如何隐藏光标
头文件
#include<Windows.h>
void hide_cur()//隐藏光标,里面是windows自带的函数,不需要刻意去记,也不需要自己去写,拿来就用
{CONSOLE_CURSOR_INFO cci;cci.dwSize = sizeof(cci);cci.bVisible = FALSE;SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
上面的函数是Windows自带的函数,用于隐藏光标,在不同的系统中不一样,Linux系统就跟这个不一样,因此要用的时候查找资料就好
❀如何定位光标
地图已经有了,我们发现打印完地图后,光标位置在地图之外,而蛇的初始位置是在地图中间,那么怎么办?使用光标定位,让光标定位到地图中间,然后打印蛇🐍
void show_ui(SNAKE* snake)
{for (int i = 0; i < snake->size; i++){ //定位光标位置,windows自带函数snake->coord.X = snake->list[i].x; snake->coord.Y = snake->list[i].y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);if (i == 0)printf("@");//蛇头用@表示else printf("*");//蛇的身体用*表示}snake->coord.X = snake->food.x; snake->coord.Y = snake->food.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf("#");//食物用#表示snake->coord.X = snake->tail.x; snake->coord.Y = snake->tail.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf(" ");
}
每一次定位光标都需要写一遍这份代码
snake->coord.X = snake->list[i].x; snake->coord.Y = snake->list[i].y;//光标x,y轴分别指向的位置
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
定位光标还需要用到系统自带结构体
COORD coord;
OK,我们运行调试一下:
成功的使光标定位在想要的位置,显示出食物和蛇🐍,但目前蛇并不能移动,我们需要让蛇🐍动起来,因此我们下一步的目标便是让蛇移动
🐍蛇的移动
对于蛇的移动,我们可以将蛇头往前移一个单位,然后蛇的身体跟着蛇头向前移动
void move_snake(SNAKE* snake)
{snake->tail.x = snake->list[snake->size - 1].x;snake->tail.y = snake->list[snake->size - 1].y;//蛇的移动,倒过来赋值for (int i = snake->size - 1; i > 0; i--){snake->list[i].x = snake->list[i - 1].x;snake->list[i].y = snake->list[i - 1].y;}//蛇头的移动单独赋值snake->list[0].x += snake->dx;snake->list[0].y += snake->dy;
}
这里有一个小技巧,就是赋值的时候要倒着赋值,否则如果正向赋值,即蛇头的位置前进1个单位,这时候在赋值给蛇身体时,只能赋值到蛇头的位置,而其他的位置则被覆盖了,倒过来赋值,则不会出现这样的问题
此时运行结果如图,这里有两个问题,打开控制台就是一连串的*和@,因为程序的运行是很快的,在几毫秒就执行完成了,我们观察不了它如何移动的,其次,一连串的*是由于前面打印出来的*没有删除而残留下来的。接下来我们来解决这两个问题
❀Sleep()函数:一个让程序暂停的函数
程序执行打印*号是很快的,我们不想让它那么快打印,我们应该让它打印一次就停顿一小会,然后继续打印
void start_game(SNAKE* snake)
{while (snake->list[0].x >= 0 && snake->list[0].x <= W - 1 && snake->list[0].y >= 0 && snake->list[0].y <= H - 1){show_ui(snake);control_move(snake);eat_food(snake);move_snake(snake);eat_snake_body(snake);Sleep(200);//让程序暂停200ms后再运行}game_over(snake);
}
运行结果
这一阶段,实现了打印的停顿,有了一个动态的效果,但是每次移动前面的*号没有删除,因此要删除轨迹
❀删除轨迹
如何删除轨迹,可以每一次打印*号后,光标移动到蛇尾,在蛇尾的位置打印空格,用于清除轨迹
snake->coord.X = snake->tail.x; snake->coord.Y = snake->tail.y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);
printf(" ");
运行结果
清除了轨迹之后,蛇的移动效果便制作出来了,目前移动的方向是向右,实际还可以向上下左右移动,下一步我们就开始实现用键盘控制改变移动方向
🐍控制键盘改变蛇的移动方向
通过键盘按键改变移动方向,我们设定w(向上),s(向下),a(向左),d(向右)
void control_move(SNAKE* snake)
{char key = 0;while (_kbhit()){key = _getch();}switch (key){case 'd':snake->dx = 1;snake->dy = 0;break;case 's':snake->dx = 0;snake->dy = 1;break;case 'a':snake->dx = -1;snake->dy = 0;break;case 'w':snake->dx = 0;snake->dy = -1;break;}
}
获取键盘按键有专门的函数_kbhit()和_getch(),当_kbhit()感应到键盘按下时,通过_getch()将获取键盘按下的值传给key
所需头文件
#include<conio.h>
然后根据方向,通过switch,case语句修改dx,dy,从而做到改变方向
🐍吃食物获得积分
吃到食物加10分,身体长度加1,然后通过随机函数再次生成新的食物
void eat_food(SNAKE* snake)
{if (snake->food.x == snake->list[0].x && snake->food.y == snake->list[0].y){snake->size++;snake->score += 10;init_food(&snake->food);}
}
🐍蛇死亡,结束游戏
在本游戏案例中,结束游戏有两种情况:①蛇撞到墙②蛇吃到身体
蛇没撞到墙时,一直在while()循环内,撞到墙则退出循环,游戏结束
void start_game(SNAKE* snake)
{while (snake->list[0].x >= 0 && snake->list[0].x <= W - 1 && snake->list[0].y >= 0 && snake->list[0].y <= H - 1){show_ui(snake);control_move(snake);eat_food(snake);move_snake(snake);eat_snake_body(snake);Sleep(1000);}game_over(snake);//蛇撞到墙,游戏结束
}
蛇吃到自己身体,游戏结束
蛇头的坐标和身体部位的坐标相同时代表吃到身体,通过for循环遍历寻找是否符合吃到身体这一情况
void eat_snake_body(SNAKE* snake)
{for (int i = 1; i < snake->size; i++){if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y){game_over(snake);exit(0);}}
}
😀完整代码
#include<stdio.h>
#include<Windows.h>
#include<string.h>
#include<stdlib.h>
#include<conio.h>
#include<time.h>
#define H 20
#define W 60
typedef struct body {int x; int y;
}BODY;typedef struct snake {int size;//蛇的长度BODY list[W * H];//蛇的位置,最大可以铺满整个墙 BODY food;COORD coord;int dx;//x轴移动方向 int dy;//y轴移动方向 int score;//分数 BODY tail;
}SNAKE;
//展示界面
void show_wall()
{for (int i = 0; i <= H; i++){for (int j = 0; j <= W; j++){if (i == H || j == W)printf("+");else printf(" ");}puts("");}}
void init_food(BODY* food)
{srand(time(NULL));food->x = rand() % W;food->y = rand() % H;while (food->x == 0 || food->y == 0){food->x = rand() % W;food->y = rand() % H;}
}
void init_snake(SNAKE* snake)
{snake->size = 2;snake->list[0].x = W / 2; snake->list[1].x = W / 2 - 1;snake->list[0].y = H / 2; snake->list[1].y = H / 2;snake->score = 0;snake->dx = 1; snake->dy = 0;init_food(&(snake->food));
}
void hide_cur()//隐藏光标,里面是windows特有的函数,不需要刻意去记,拿来就用
{CONSOLE_CURSOR_INFO cci;cci.dwSize = sizeof(cci);cci.bVisible = FALSE;SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}
void show_ui(SNAKE* snake)
{for (int i = 0; i < snake->size; i++){ //定位光标位置,windows自带函数snake->coord.X = snake->list[i].x; snake->coord.Y = snake->list[i].y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);if (i == 0)printf("@");else printf("*");}snake->coord.X = snake->food.x; snake->coord.Y = snake->food.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf("#");snake->coord.X = snake->tail.x; snake->coord.Y = snake->tail.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf(" ");
}
void move_snake(SNAKE* snake)
{snake->tail.x = snake->list[snake->size - 1].x;snake->tail.y = snake->list[snake->size - 1].y;for (int i = snake->size - 1; i > 0; i--){snake->list[i].x = snake->list[i - 1].x;snake->list[i].y = snake->list[i - 1].y;}snake->list[0].x += snake->dx;snake->list[0].y += snake->dy;
}
void control_move(SNAKE* snake)
{char key = 0;while (_kbhit()){key = _getch();}switch (key){case 'd':snake->dx = 1;snake->dy = 0;break;case 's':snake->dx = 0;snake->dy = 1;break;case 'a':snake->dx = -1;snake->dy = 0;break;case 'w':snake->dx = 0;snake->dy = -1;break;}
}
void eat_food(SNAKE* snake)
{if (snake->food.x == snake->list[0].x && snake->food.y == snake->list[0].y){snake->size++;snake->score += 10;init_food(&snake->food);}
}
void game_over(SNAKE* snake)
{snake->coord.X = 30; snake->coord.Y = 25;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf("游戏结束!!! 得分:%d", snake->score);system("pause");
}
void eat_snake_body(SNAKE* snake)
{for (int i = 1; i < snake->size; i++){if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y){game_over(snake);exit(0);}}
}
void start_game(SNAKE* snake)
{while (snake->list[0].x >= 0 && snake->list[0].x <= W - 1 && snake->list[0].y >= 0 && snake->list[0].y <= H - 1){show_ui(snake);control_move(snake);eat_food(snake);move_snake(snake);eat_snake_body(snake);Sleep(300);}game_over(snake);
}int main()
{hide_cur();SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));init_snake(snake);show_wall();show_ui(snake);start_game(snake);free(snake);system("pause");return 0;
}
😀拓展
可以实现障碍物,新增关卡等等,以及图形化界面,提升难度,下列代码展示了增加障碍物
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<Windows.h>
#include<conio.h>/*
注意:
w:上移
s:下移
a:左移
d:右移
不可以用getchar()来进行控制,getchar()之后要有回车才行,而我们只希望通过wsad这些按键进行操作
但有专门的按键操作函数
#include<conio.h>
char key;//key要给初始值,否则key没值,进不了循环,但初始值也不能是wasd等
while(_kbhit())//判断是否按下按键,按下不等于0
{key=_getch();
}
*/char temp;
//1.设置地图边界
#define W 60
#define H 20//2.设置贪吃蛇结构体
typedef struct _body {int x; //坐标xint y; //坐标y
}BODY;typedef struct snake{BODY list[W * H];//贪吃蛇最大占满整个地图int size;//实际身体个数,蛇头(@)和蛇身蛇尾(*)BODY food;//食物,#COORD coord;//(定位光标)的坐标,显示int dx;//移动方向int dy;//移动方向BODY tail;//记录蛇尾,用于清除蛇尾痕迹 int score;//分数BODY disability;
}SNAKE;//3.实现显示地图,初始化蛇函数,初始化食物函数void test_ui()
{for (int i = 0; i < H; i++){for (int j = 0; j < W; j++)printf("=");printf("\n");}
}
void disability_snake(BODY* disability)
{Sleep(5);//设置障碍物坐标disability->x = rand() % W;disability->y = rand() % H;while (disability->x == 0 || disability->x == W - 1 || disability->y == 0 || disability->y == H - 1){disability->x = rand() % W;disability->y = rand() % H;}}
void init_food(BODY* food)
{//设置随机数种子srand(time(NULL));//设置食物坐标food->x = rand()% W;//[0,W-1],注意%的操作很巧妙food->y = rand() % H;//[0,H-1]while(food->x == 0 || food->x == W - 1 || food->y == 0 || food->y == H - 1){food->x = rand() % W;food->y = rand() % H;}}
void init_snake(SNAKE* snake)//初始化
{snake->list[0].x = W / 2;snake->list[0].y = H / 2;snake->list[1].x = W / 2 - 1;snake->list[1].y = H / 2;//这里老师写成H/2-1应该是错的snake->size = 2;//初始时蛇的长度为2,因为有头有尾//设置移动方向snake->dx = 1;//默认移动方向向右snake->dy = 0;//默认移动方向向左snake->score = 0;init_food(&snake->food);disability_snake(&snake->disability);while (snake->food.x == snake->disability.x && snake->food.y == snake->disability.y){init_food(&snake->food);disability_snake(&snake->disability);}
};void show_ui(SNAKE* snake)
{//显示蛇for (int i = 0; i < snake->size; i++){ snake->coord.X = snake->list[i].x;//这个函数是在显示地图后执行的,画完地图后光标是在地图之外的,用这个函数可以重置光标位置,让光标放到我们想要的地方snake->coord.Y = snake->list[i].y;//定位光标位置,windows自带函数SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);if (i == 0) {//显示蛇头printf("@");}else{//显示蛇身和蛇尾printf("*");}}//显示食物snake->coord.X = snake->food.x;snake->coord.Y = snake->food.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf("#");//显示障碍物snake->coord.X = snake->disability.x;snake->coord.Y = snake->disability.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf("?");//清除蛇尾的痕迹,否则一连串的*snake->coord.X = snake->tail.x;snake->coord.Y = snake->tail.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf(" ");
}
void show_wall()//展示墙
{for (int i = 0; i <=H; i++){for (int j = 0; j <=W; j++){if (i == H || j == W)printf("+");else printf(" ");}puts("");}
}void hide_cur()//隐藏光标,里面是windows特有的函数,不需要刻意去记,拿来就用
{CONSOLE_CURSOR_INFO cci;cci.dwSize = sizeof(cci);cci.bVisible = FALSE;SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
}void move_snake(SNAKE* snake)
{ //记录蛇尾,清除痕迹snake->tail = snake->list[snake->size - 1];//蛇身的移动,算法逻辑从后往前赋值//蛇头的移动,单独赋值for (int i = snake->size - 1; i > 0; i--){snake->list[i] = snake->list[i - 1];}snake->list[0].x += snake->dx;snake->list[0].y += snake->dy;
}
void control_snake(SNAKE* snake)
{char key = 0;while (_kbhit())//检测到按下按键{if (temp == 'w' && _kbhit() == 's')key = temp;else if (temp == 's' && _kbhit() == 'w')key = temp;else if (temp == 'a' && _kbhit() == 'd')key = temp;else if (temp == 'd' && _kbhit() == 'a')key = temp;else key = _getch();}//循环之外,抬起按下动作,或没有按下动作//根据按键,修改移动方向temp = key;switch (key){case 'w':snake->dy = -1;snake->dx = 0;break;case 's':snake->dy = 1;snake->dx = 0;break;case 'a':snake->dy = 0;snake->dx = -1;break;case 'd':snake->dy = 0;snake->dx = 1;}}void snake_eat(SNAKE* snake)
{//判断是否吃到食物if (snake->list[0].x == snake->food.x && snake->list[0].y == snake->food.y){//吃到食物,身体加长,食物消失,重新生成新的食物snake->size++;//食物消失也不用重新写,因为一旦生成了食物原来的地方就消失了snake->coord.X = snake->disability.x;snake->coord.Y = snake->disability.y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf(" ");init_food(&(snake->food)); disability_snake(&snake->disability);printf(" ");while (snake->food.x == snake->disability.x && snake->food.y == snake->disability.y){init_food(&snake->food);disability_snake(&snake->disability);}snake->score += 10;}}
void game_over(SNAKE* snake)//游戏结束,指定到具体位置打印游戏结束
{snake->coord.X = 40;snake->coord.Y = 25;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), snake->coord);printf("游戏结束 总分数:%d", snake->score);system("pause");
}
void snake_eat_body(SNAKE* snake)
{for (int i = 1; i < snake->size; i++){if (snake->list[0].x == snake->list[i].x && snake->list[0].y == snake->list[i].y){game_over(snake);//吃到身体;游戏结束exit(0);}}
}
void snake_push_disability(SNAKE* snake)
{if (snake->disability.x == snake->list[0].x && snake->disability.y == snake->list[0].y){game_over(snake);exit(0);}
}
void start_game(SNAKE* snake)
{while (snake->list[0].x >=0 && snake->list[0].x < W &&snake->list[0].y>=0 && snake->list[0].y < H)//在范围内移动{ //显示蛇和食物show_ui(snake);//控制移动方向control_snake(snake);//蛇吃到食物snake_eat(snake);//蛇吃到身体snake_eat_body(snake);//蛇撞到障碍物snake_push_disability(snake);//移动蛇move_snake(snake);//延迟300msSleep(100);}game_over(snake);//碰到墙壁,游戏结束
}int main(int argc,char *argv[])
{hide_cur();//隐藏光标SNAKE* snake = (SNAKE*)malloc(sizeof(SNAKE));//创建空间init_snake(snake);//显示地图边界show_wall();//显示蛇和食物show_ui(snake);//启动游戏start_game(snake);free(snake);//释放空间//while (1);//先不让程序结束,就暂时不显示程序结束的那段字return 0;
}
相关文章:
CC++:贪吃蛇小游戏教程
❀创作不易,关注作者不迷路❀😀😀 目录 😀贪吃蛇简介 😃贪吃蛇的实现 🐍生成地图 🐍生成蛇模块 ❀定义蛇的结构体 ❀初始化蛇的相关信息 ❀初始化食物的相关信息 🐍光标定位和…...
C#中投影运算的深入解析与实例应用
文章目录 1、投影运算的基本语法2、投影运算的高级用法3、投影运算在向量空间中的运用4、投影运算在数据库和XML中的实际应用5、投影运算能用于哪些实际场景?6、结论 在C#编程中,投影运算是一种常用的数据操作技术,它可以将一个数据集合转换成…...
HTML+CSS練習---空隙產生記錄
1.第一層和第二層之間的間隙:以為導航欄超過高度朝下擠下來了 2.第2層兩個div中的空隙 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Document</title><style>font-face {f…...
【leetcode】相同的树、另一棵树的子树、翻转二叉树(利用深度优先遍历)
Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:数据结构、LeetCode专栏 📚本系…...
Linux系统窗口水印难点分析
给应用程序加水印是保护数据的一种方式,window上可以通过给进程通过注入的方法给进程的窗口创建一个同大小的副窗口,在副窗口上绘制水印内容,同时设置副窗口透明同时透传事件,这样就可以达到在源窗口上显示水印的效果且不影响程序…...
LabVIEW与CANopen实现自动化生产线的设备控制与数据采集
在某工厂的自动化生产线上,多个设备通过CANopen网络进行通信和控制。这些设备包括传感器、执行器和PLC,它们共同负责监测和控制生产过程中的关键参数,如温度、压力、速度等。为了实现对整个生产线的集中监控和管理,工厂决定使用La…...
吃惊!这个Windows双系统方法逆天了|UEFI篇
前言 最近小白在折腾别的系统教程,偶然间发现居然有一个很nice的Windows双系统教程。于是于是,果断尝试了一下,发现真的很可行! 这个双系统的办法并不需要使用到WinPE系统,因此并不需要使用到U盘,只需要在…...
【C语言基础】C语言试题复习
1. 执行下面的程序段后,k 的值是_______。 int k1,n325; do { k*n%10;n/10;}while(n); 解析: 给定 n 325 和初始 k 1,代码中的循环将会进行如下操作: 第一次循环:n % 10 得到 5,因此 k * 5,即 k 1 * 5 …...
一拖三无线充底座-带给你极致的便利生活
随着科技的不断进步,无线充电技术已经逐渐渗透到我们日常生活的方方面面,一拖三无线充底座作为其中的佼佼者,以其高效、便捷的特点受到广大用户的青睐。本文将从电磁感应原理、多线圈设计、频率匹配、电能传输、功率分配以及充电管理六个方面…...
探索 Electron:打造深度书籍挖掘机的搜索体验
Electron是一个开源的桌面应用程序开发框架,它允许开发者使用Web技术(如 HTML、CSS 和 JavaScript)构建跨平台的桌面应用程序,它的出现极大地简化了桌面应用程序的开发流程,让更多的开发者能够利用已有的 Web 开发技能…...
tomato靶场
扫描网址端口 访问一下8888 我们用kali扫描一下目录 访问这个目录 产看iofo.php源码,发现里面有文件包含漏洞 访问/etc/passwd/发现确实有文件包含漏洞 远程连接2211端口 利用报错,向日志文件注入木马,利用文件包含漏洞访问日志文件 http:/…...
【Vue】computed计算对象不生效问题?
问题描述 最近使用vuex来管理全局状态,遇到了computed计算state中数据却不生效的问题。 原因分析: 先看vue官网示例: computed接收的是一个getter函数,但是这个getter函数是懒加载并且有缓存的,当计算属性最终计算…...
算法小白的进阶之路(力扣9~12)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…...
DOCKER容器中安装JDK1. 8 详细步骤
1.通过查找JDK8的远程镜像 docker search jdk 2.选择一个远程镜像下载到本地仓库 #拉取镜像 docker pull kdvolder/jdk8#查看镜像 docker images 可以看到REPOSITORY列下面出现了kdvolder/jdk8 3.在docker容器中运行jdk8的镜像 docker run -di --namejdk1.8 kdvolder/jdk…...
计算机毕业设计Python+Tensorflow股票推荐系统 股票预测系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI
1、用pycharm打开项目,一定要打开包含manage.py文件所在文件夹 2、配置解释器:建议使用Anaconda(Python 3.8(base)),低于3.8版本的,页面会不兼容 3、安装依赖库:打开pycharm的终端,输入: pip in…...
深度学习常见的卷积和注意力机制文章集锦(持续更新)
卷积 友好链接1 卷积原理:几种常用的卷积(标准卷积、深度卷积、组卷积、扩展卷积、反卷积) 友好链接2 一文看尽深度学习中的20种卷积(附源码整理和论文解读) 友好链接3 深度学习中组卷积(Group convolution)、深度卷积…...
如何在立创EDA的PCB电路板导入logo图案
1、首先制作好logo图案,一般为公司logo图标,如下图 2、打开立创EDA的PCB文件,如下图 3、将PCB的图层切换到丝印层: 4、然后选择EDA菜单栏的放置---图片: 5、进入后点击选择图片,将logo图片导入,…...
springboot集成canal
目录 一、打开mysql的binlog1.1 打开 MySQL 配置文件 my.cnf(通常位于 /etc/mysql/my.cnf 或 /etc/my.cnf)并添加或修改以下设置:1.2 重启mysql服务1.3 验证是否生效 二、 部署canal 服务端(docker)2.1 下载启动脚本(可…...
leetcode数论(2447. 最大公因数等于 K 的子数组数目)
前言 经过前期的数据结构和算法学习,开始以OD机考题作为练习题,继续加强下熟练程度。 描述 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 nums 的子数组中元素的最大公因数等于 k 的子数组数目。 子数组 是数组中一个连续的非空序列…...
实现数组扁平化的几种方式
目标: 实现数组扁平化[1,[2,[3,4,5]]] > [1,2,3,4,5] 我们有几种方法可以实现,分别为: 1、递归 function flatten(list){return list.reduce((tar, cur) > {if(Array.isArray(cur)){tar tar.concat(flatten(cur));} else {tar.push(cur);}return tar;}, []); } flatt…...
3D打印技术正悄然重塑模具工业格局
虽被誉为“工业之母”的模具在批量生产中仍占据核心地位,但3D打印以其“无模”直接成型的特性,在小批量、非标准化及复杂结构件制造领域展现出独特优势,随着技术和装备的不断发展,目前3D打印正逐渐向批量生产渗透,某品…...
深入解析 KMZ 文件的处理与可视化:从数据提取到地图展示项目实战
文章目录 1. KMZ 文件与 KML 文件简介1.1 KMZ 文件1.2 KML 文件 2. Python 环境配置与依赖安装3. 代码实现详解3.1 查找 KMZ 文件3.2 解压 KMZ 文件3.3 解析 KML 文件3.4 可视化 KMZ 数据 4. 项目实战4.1. 数据采集4.2. 项目完整代码 5. 项目运行与结果展示6. 总结与展望 在处理…...
YOLOv5轻量化改进 | backbone | 结合MobileNetV4(包含多个结构和使用方式)
YOLOv5轻量化改进 | backbone | 结合MobileNetV4(包含多个结构) 本文介绍论文原理介绍网络代码多种yaml设置网络测试及实验结果<!-- 这里放入论文图片 -->  ;本文介绍 本文给大家带来的改进机制是结合MobileNetV4骨干网络,其中来自2024.5月发布的MobileNetV4…...
学习安卓开发遇到的问题
问题1:学习禁用与恢复按钮中: java代码报错:报错代码是 R.id.btn_enable;case R.id.btn_disable;case R.id.btn_test: 代码如下:(实现功能在代码后面) package com.example.apptest;import static java.…...
数学建模--禁忌搜索
目录 算法基本原理 关键要素 应用实例 实现细节 python代码示例 总结 禁忌搜索算法在解决哪些具体类型的组合优化问题中最有效? 禁忌搜索算法的邻域结构设计有哪些最佳实践或案例研究? 如何动态更新禁忌表以提高禁忌搜索算法的效率和性能&#…...
LeetCode 第136场双周赛个人题解
Q1. 求出胜利玩家的数目 原题链接 Q1. 求出胜利玩家的数目 思路分析 直接模拟 时间复杂度:O(N) AC代码 class Solution { public:int winningPlayerCount(int n, vector<vector<int>>& pick) {unordered_map<int, unordered_map<int, …...
The operation was rejected by your operating system. code CERT_HAS_EXPIRED报错解决
各种报错,试了清缓存,使用管理员权限打开命令行工具,更新npm,都不好使 最终解决:删除 c:/user/admin/ .npmrc...
[Git][基本操作]详细讲解
目录 1.创建本地仓库2.配置 Git3.添加文件1.添加文件2.提交文件3.其他 && 说明 4.删除文件5.跟踪修改文件6.版本回退7.撤销修改0.前言1.未add2.已add,未commit3.已add,已commit 1.创建本地仓库 创建⼀个Git本地仓库:git init运行该命…...
springMVC中从Excel文件中导入导出数据
目录 1. 数据库展示2. 导入依赖3. 写方法3.1 导入数据3.2 导出数据 4. 效果5. 不足6. 参考链接 1. 数据库展示 2. 导入依赖 pom.xml <!--文件上传处理--><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId>&…...
C++的STL简介(三)
目录 1.vector的模拟实现 1.1begin() 1.2end() 1.3打印信息 1.4 reserve() 1.5 size() 1.6 capacity() 1.7 push_back() 1.8[ ] 1.9 pop_back() 1.10 insert&…...
搭建网站价格/长春seo公司哪家好
原文:纯代码利用CSS3 圆角边框和盒子阴影 制作 iphone 手机效果大家好,我是小强老师。 今天我们看下CSS3最为简单的两个属性。 css3给我们带来了很多视觉的感受和变化,以前的图片做的事情,很多代码都能实现。 下面给大家简单介绍两种最为…...
新网站怎么做/百度网盘链接
题意:求数字根和。所谓数字根和就是把一个数的各位数字相加,如果得到的和不是个位数,则再把这个和的各位数字相加……直到最后得到一个个位数为止。最和得到的这个数就叫原数的数字根和。 思路:首先模拟。后来知道一个数的数字根…...
wordpress租车主题/苹果要做搜索引擎
在前一篇文章中,小编采用了docker toolbox方法来安装了docker,并使用Java程序来链接docker,今天我将采用标准的VirtualBox来链接docker,学习类容主要是制作认证书和端口暴露。环境配置:虚拟机:VirtualBox5.…...
自助做网站傻瓜式自助建站工具/cps推广接单平台
就业方向:完全面向长三角等发达地区的企业,以零件、模具加工为主要的授课方向,培养符合企业真正需要的专业工程技术人才,学员经过严格的学习、实战、考核后能胜任数控编程及数控机床操作工作,并且具备相当的实战经验。…...
徐州网站建设魔站/吴江网站制作
2011 IT娱乐界回顾1、前端浏览器WIN7迅速普及是好事。至少IE8越来越主流了。这个稍微靠标准的家伙,会不会也像IE6在未来10年不死?不过也无所谓,反正PC和手机以后会一半一半天下。当然,手机iphone\android(三星崛起&…...
广州市网站建设科技/软件推广
文章预览一、Nacos服务配置DEFAULT_GROUPDEV_GROUP二、编写配置客户端2.1、目录结构2.2、pom文件2.3、yml文件2.4、Controller2.5、主启动类三、效果展示四、BUG下图是配置中心Data的命名格式 下面演示在自定义的命名空间下不同组下的配置 一、Nacos服务配置 自定义一个dev的…...