智能三子棋(人机大战)—— 你会是最终赢家吗?万字讲解让你实现与自己对弈
- 魔王的介绍:😶🌫️一名双非本科大一小白。
- 魔王的目标:🤯努力赶上周围卷王的脚步。
- 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥
❤️🔥大魔王与你分享:罗曼罗兰说过:这个世上只有一种真正的英雄主义,那就是认清生活的真相并且任然热爱他。
文章目录
- 一、前言
- 二、文件介绍
- 三、代码实现
- 1.完成test.c文件模板
- 2.创建棋盘并进行初始化
- 3.打印棋盘
- 4.玩家下棋
- 5.电脑下棋
- 6.判断输赢
- 7.判断是否满了
- 8.电脑智能下棋
- 四、对于初学者较陌生的知识
- 1.休眠函数
- 2.清屏函数
- 3.随机数函数
- 五、总代码
- game.h
- 2.game.c
- 3.test.c
- 4.效果展示图
- 六、总结
一、前言
相信大家都玩过三子棋或者五子棋游戏,但你会通过编程完美实现吗,本篇将带领你真正学会三子棋,并与你自己编译出来的程序分出胜负。
二、文件介绍
test.c:测试文件
game.c:源文件,进行函数的定义
game.h:头文件(只进行声明)
我们用测试文件调用game.h声明、game.c文件中实现的函数,这就是三个文件的关系。
为了使三者联系起来,我们需要让两个源文件(.c)文件都包含头文件,这样他们中的函数就可以一起使用了。
三、代码实现
1.完成test.c文件模板
模板介绍:我们在玩游戏时,首先肯定需要看到菜单,然后菜单中有选线供玩家选择,等玩家选择完成后,就要根据玩家的选择展开不同的路线来执行程序。为了使游戏可以重复完,我们还需要让程序能够玩完一次继续玩,直到玩家不想玩选择退出程序,程序再结束。
#include "game.h"void menu()
{printf("********************\n");printf("****** 1.play ******\n");printf("****** 0.exit ******\n");printf("********************\n");
}
void test()
{int input = 0;do{menu();printf("请选择:> ");scanf("%d", &input);switch (input){case 1:printf("开始游戏\n");game();break;default:printf("输入错误,请重新输入\n");break;case 0:printf("退出游戏\n");}} while (input);
}
int main()
{test();return 0;
}
2.创建棋盘并进行初始化
因为我们是要把符号输入到二维数组中,结合我们构造出来的图案形成三子棋的模样,所以我们需要创建一个二维数组并进行初始化(因为棋盘最开始为空白的,所以二维数组初始化的内容为空格)。
我们先在test.c文件中创建一个棋盘然后再调用game.c文件中初始化棋盘的代码。
- 初始化棋盘代码如下:
void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){board[i][j] = ' ';}}
}
3.打印棋盘
我们创建并初始化棋盘后,需要打印出三子棋图供玩家进行观察和下棋,如果玩家想玩不只3*3格的三子棋,或者想把三子棋改为五子棋,也就是说当规模较大时,为了方便玩家,我们给每行每列开头都给定标号,便利玩家。
//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col)
{int k = 0;printf(" ");printf(" ");for (k = 0; k < col; k++){printf(" ");printf("%d", k + 1);printf(" ");printf(" ");}printf("\n");int i = 0;for (i = 0; i < row; i++)//打印row行{int j = 0;printf("%-2d", i + 1);//打印每行开头的行数for (j = 0; j < col; j++)//第一种行中的那一小段(空格、数组、空格){printf(" ");printf("%c", board[i][j]);printf(" ");if (j < col - 1)printf("|");//打印一个|}printf("\n");if (i < row - 1)//第二种行中的那一小段(-、-、-){printf(" ");printf(" ");//对应补齐每行开头的行数(不然棋盘会错一位)for (j = 0; j < col; j++){printf("-");printf("-");printf("-");if (j < col - 1)printf("|");//打印一个|}printf("\n");}}
}
4.玩家下棋
游戏是由程序员编译的,但是玩家可能是个小白,玩家并不知道数组下标是从0开始的,所以我们需要让玩家输入的两个值都减去1才是玩家真实想填入的地方。但是我们在填入时,首先需要判断输入的坐标是否合法,也就是说是否为坐标范围之外的值,如果是,需要重新输入,判断完这个,我们还需要判断这个坐标是否已经被使用,只有这两个条件都满足,我们才可以将棋子落入玩家想下的地方。
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;while (1){printf("玩家下棋,请输入坐标:> ");scanf("%d %d", &i, &j);if ((i > 0 && i <= row) && (j > 0 && j <= col)){if (board[i - 1][j - 1] == ' '){board[i - 1][j - 1] = '*';break;}elseprintf("输入坐标已经使用,请重新输入\n");}elseprintf("输入坐标不在范围内,请重新输入\n");}
}
5.电脑下棋
电脑下棋需要用到随机数rand(),最后会统一讲对初学者比较陌生的库函数。和玩家下棋很相似,不过不用减一了,因为这是电脑操作的。但是还需要判断是否已被占用,若已被占用,就重新给定一组值,直到电脑成功下一个棋。
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{while (1){int i = rand() % row;int j = rand() % col;if (board[i][j] == ' '){board[i][j] = '#';break;}}
}
6.判断输赢
三子棋的胜利分为四种形式,一种是横向三个,一种是纵向三个,一种是右下倾斜(\),一种是左下倾斜(/),这四种方式我们都会采用遍历法实现。
//判断输赢
char JudgeGame(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//横for (i = 0; i < row; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i][j + 1] && board[i][j] == board[i][j + 2] && board[i][j] != ' ')return board[i][j];}}//竖for (j = 0; j < col; j++){for (i = 0; i < row - 2; i++){if (board[i][j] == board[i+1][j] && board[i][j] == board[i+2][j] && board[i][j] != ' ')return board[i][j];}}//右下方向(\)for (i = 0; i < row - 2; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i+1][j + 1] && board[i][j] == board[i+2][j + 2] && board[i][j] != ' '){return board[i][j];}}}//左下方向(/)for (i = 0; i <row; i++){for (j = col - 1; j > 1; j--){if (board[i][j] == board[i+1][j - 1] && board[i][j] == board[i+2][j - 2] && board[i][j] != ' ')return board[i][j];}}return 0;
}
7.判断是否满了
每次判断完是否胜利后,如果没有胜利,我们不能直接让另一个下棋,我们还要判断是否已经满了,如果满了还没分出胜负(因为是先判断输赢,再判断是否满的,所以这一点不用用管就是这样),那就是平局。
//判断是否棋盘已经下满
int is_full(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1;
}
8.电脑智能下棋
我们如果不给电脑赋一点智商,他真的好笨,让他赢都赢不了,难受啊,但又没办法给他说话,那么就让我们的思想赋给电脑,这样就是两个你在对比输赢了,哈哈哈哈。
说实话让电脑智能一点其实自己想的时候没有思路,于是看了安 度 因(点击安度因可以跳转到他的文章)大佬的智能三子棋,但是真的,就瞄一眼思路瞬间就出来了,我们只要想到从获胜那里提取思路,真的一下就出来了,无非就是:那四种情况下有两个棋子,所谓的两个棋子又分为三种情况:比如说###获胜,那么情况就有三个,##空、#空#、空##,都是这三种情况,代码如下:
//电脑智能下棋
int intelligent_move(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//横行拦截/下棋for (i = 0; i < row; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i][j + 1] && board[i][j] != ' ' && board[i][j + 2] == ' '){board[i][j+2] = '#';return 1;}if (board[i][j] == board[i][j + 2] && board[i][j] != ' ' && board[i][j + 1] == ' '){board[i][j+1] = '#';return 1;}if (board[i][j + 1] == board[i][j + 2] && board[i][j + 1] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}//纵行拦截/下棋for (j = 0; j < col; j++){for (i = 0; i < row - 2; i++){if (board[i][j] == board[i+1][j] && board[i][j] != ' ' && board[i+2][j] == ' '){board[i+2][j] = '#';return 1;}if (board[i][j] == board[i+2][j] && board[i][j] != ' ' && board[i+1][j] == ' '){board[i+1][j] = '#';return 1;}if (board[i+1][j] == board[i+2][j] && board[i+1][j] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}//右下方向拦截/下棋for (i = 0; i < row - 2; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ' && board[i + 2][j + 2] == ' '){board[i + 2][j + 2] = '#';return 1;}if (board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ' && board[i + 1][j + 1] == ' '){board[i + 1][j + 1] = '#';return 1;}if (board[i+2][j+2] == board[i + 1][j + 1] && board[i+2][j+2] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}//左下方向拦截/下棋for (i = 0; i < row - 2; i++){for (j = col-1; j > 1; j--){if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ' && board[i + 2][j - 2] == ' '){board[i + 2][j - 2] = '#';return 1;}if (board[i][j] == board[i + 2][j - 2] && board[i][j] != ' ' && board[i + 1][j - 1] == ' '){board[i + 1][j - 1] = '#';return 1;}if (board[i+2][j-2] == board[i + 1][j - 1] && board[i+2][j-2] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}return 0;
}
四、对于初学者较陌生的知识
1.休眠函数
睡眠函数:我们在玩时是不是觉得电脑反应好快,我们明明已经给他赋上智慧了,他却还那么快,这不就比我们都聪明了,为了让他笨一点,我们让他下的时候反应一秒,这就引入了睡眠函数,C语言库里是小写sleep,但是VS必须开头大写,也就是Sleep,我们按小写说,那就是sleep(unsigned int),里面的无符号整型单位是ms毫秒,所以我们写1000,实际就是每次走到这个程序停顿1秒。对应的头文件是<windows.h>
2.清屏函数
清屏函数:每次棋盘被修改,我们都要打印一次,但是这次打印出来上次的不就没用了吗,让他们一直留着好麻烦,所以我们引入一个清屏函数,system(“cls”);对应的头文件是<windows.h>
3.随机数函数
- 随机数函数rand:
-
rand函数原型:
一、#include <stdlib.h>;
二、int rand(void); -
rand函数调用:
一、rand()函数每次调用前会查询是否调用过srand(seed),是否给seed设定了一个值,如果有那么它会自动调用srand(seed)一次来初始化它的起始值。
二、若之前没有调用srand(seed),那么系统会自动给seed赋初始值,即srand(1)自动调用它一次。
- srand函数:
-
一、srand函数是随机数发生器的初始化函数,原型:
void srand(unsigned int seed);
二、这个函数需要提供一个种子,如srand(1),用1来初始化种子。
三、rand函数产生随机数时,如果srand(seed)播下种子之后,一旦种子相同,产生的随机数将是相同的。但是我们很多时候都是要让rand()产生一个随机数,那么这就意味着我们需要让种子值时刻发生变化,所以就可以这样赋值:srand(time(NULL)),那么我们就又引入了时间函数,详细如下
- time函数:
-
我们常常使用系统时间来初始化,使用time函数来获取系统时间,得到的值是一个时间戳,即从1970年1月1日到现在时间的秒数,然后将得到的time_t类型数据转化为(unsigned int)的数,然后再传给srand函数,用法如下:
一、srand(unsigned int)time(NULL);对应的头文件:<time.h>,我们在使用rand和srand时,主要使用的就是这一种初始化方法。
二、如果感觉时间间隔太小,可以让这个整体乘上一个数:srand((unsigned)time(NULL)*10)
三、time的参数传NULL表示不需要经过参数获得的time_t数据。
四、time函数原型如下:
time_t time(time_t * tloc); time_t类型被定义为一个长整型
五、详细的rand讲解可以点击这里进入该文章
五、总代码
game.h
#pragma once#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>#define ROW 3
#define COL 3//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col);//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);//判断输赢
char JudgeGame(char board[ROW][COL], int row, int col);//判断是否棋盘已经下满
int is_full(char board[ROW][COL], int row, int col);//电脑智能下棋
int intelligent_move(char board[ROW][COL], int row, int col);
2.game.c
#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){board[i][j] = ' ';}}
}//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col)
{int k = 0;printf(" ");printf(" ");for (k = 0; k < col; k++){printf(" ");printf("%d", k + 1);printf(" ");printf(" ");}printf("\n");int i = 0;for (i = 0; i < row; i++)//打印row行{int j = 0;printf("%-2d", i + 1);//打印每行开头的行数for (j = 0; j < col; j++)//第一种行中的那一小段(空格、数组、空格){printf(" ");printf("%c", board[i][j]);printf(" ");if (j < col - 1)printf("|");//打印一个|}printf("\n");if (i < row - 1)//第二种行中的那一小段(-、-、-){printf(" ");printf(" ");//对应补齐每行开头的行数(不然棋盘会错一位)for (j = 0; j < col; j++){printf("-");printf("-");printf("-");if (j < col - 1)printf("|");//打印一个|}printf("\n");}}
}//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;while (1){printf("玩家下棋,请输入坐标:> ");scanf("%d %d", &i, &j);if ((i > 0 && i <= row) && (j > 0 && j <= col)){if (board[i - 1][j - 1] == ' '){board[i - 1][j - 1] = '*';break;}elseprintf("输入坐标已经使用,请重新输入\n");}elseprintf("输入坐标不在范围内,请重新输入\n");}
}//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{while (1){int i = rand() % row;int j = rand() % col;if (board[i][j] == ' '){board[i][j] = '#';break;}}
}//判断输赢
char JudgeGame(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//横for (i = 0; i < row; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i][j + 1] && board[i][j] == board[i][j + 2] && board[i][j] != ' ')return board[i][j];}}//竖for (j = 0; j < col; j++){for (i = 0; i < row - 2; i++){if (board[i][j] == board[i+1][j] && board[i][j] == board[i+2][j] && board[i][j] != ' ')return board[i][j];}}//右下方向(\)for (i = 0; i < row - 2; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i+1][j + 1] && board[i][j] == board[i+2][j + 2] && board[i][j] != ' '){return board[i][j];}}}//左下方向(/)for (i = 0; i <row; i++){for (j = col - 1; j > 1; j--){if (board[i][j] == board[i+1][j - 1] && board[i][j] == board[i+2][j - 2] && board[i][j] != ' ')return board[i][j];}}return 0;
}//判断是否棋盘已经下满
int is_full(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){if (board[i][j] == ' ')return 0;}}return 1;
}//电脑智能下棋
int intelligent_move(char board[ROW][COL], int row, int col)
{int i = 0;int j = 0;//横行拦截/下棋for (i = 0; i < row; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i][j + 1] && board[i][j] != ' ' && board[i][j + 2] == ' '){board[i][j+2] = '#';return 1;}if (board[i][j] == board[i][j + 2] && board[i][j] != ' ' && board[i][j + 1] == ' '){board[i][j+1] = '#';return 1;}if (board[i][j + 1] == board[i][j + 2] && board[i][j + 1] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}//纵行拦截/下棋for (j = 0; j < col; j++){for (i = 0; i < row - 2; i++){if (board[i][j] == board[i+1][j] && board[i][j] != ' ' && board[i+2][j] == ' '){board[i+2][j] = '#';return 1;}if (board[i][j] == board[i+2][j] && board[i][j] != ' ' && board[i+1][j] == ' '){board[i+1][j] = '#';return 1;}if (board[i+1][j] == board[i+2][j] && board[i+1][j] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}//右下方向拦截\下棋for (i = 0; i < row - 2; i++){for (j = 0; j < col - 2; j++){if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ' && board[i + 2][j + 2] == ' '){board[i + 2][j + 2] = '#';return 1;}if (board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ' && board[i + 1][j + 1] == ' '){board[i + 1][j + 1] = '#';return 1;}if (board[i+2][j+2] == board[i + 1][j + 1] && board[i+2][j+2] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}//左下方向拦截/下棋for (i = 0; i < row - 2; i++){for (j = col-1; j > 1; j--){if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ' && board[i + 2][j - 2] == ' '){board[i + 2][j - 2] = '#';return 1;}if (board[i][j] == board[i + 2][j - 2] && board[i][j] != ' ' && board[i + 1][j - 1] == ' '){board[i + 1][j - 1] = '#';return 1;}if (board[i+2][j-2] == board[i + 1][j - 1] && board[i+2][j-2] != ' ' && board[i][j] == ' '){board[i][j] = '#';return 1;}}}return 0;
}
3.test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void menu()
{printf("********************\n");printf("****** 1.play ******\n");printf("****** 0.exit ******\n");printf("********************\n");
}void game()
{char board[ROW][COL];//创建棋盘InitBoard(board, ROW, COL);//初始化棋盘PrintBoard(board, ROW, COL);//打印棋盘char ret = 0;while (1){PlayerMove(board, ROW, COL);//玩家下棋,玩家为*system("cls");//清屏PrintBoard(board, ROW, COL);//打印棋盘ret = JudgeGame(board, ROW, COL);//判断输赢if (ret != 0)break;if (ret = is_full(board, ROW, COL) == 1)break;int flag = intelligent_move(board, ROW, COL);//如果这一步电脑智能下棋确实下了,那么flag为1,否则为0if(flag==0)//flag为0,说明没有智能下棋,那么就进行随机下棋ComputerMove(board, ROW, COL);//电脑下棋,电脑为#Sleep(1000);//休眠一秒(让电脑思考一会,哈哈哈哈哈)system("cls");//清屏PrintBoard(board, ROW, COL);//打印棋盘ret = JudgeGame(board, ROW, COL);//判断输赢if (ret != 0)break;if (ret = is_full(board, ROW, COL) == 1)break;}if (ret == '*')printf("恭喜你赢啦!!!\n");else if (ret == '#')printf("好遗憾,你连自己设置的电脑都玩不赢!!!\n");elseprintf("棋盘下满了,未分出胜负,电脑表示不服!!!\n");
}
void test()
{int input = 0;do{menu();printf("请选择:> ");scanf("%d", &input);switch (input){case 1:printf("开始游戏\n");game();break;default:printf("输入错误,请重新输入\n");break;case 0:printf("退出游戏\n");}} while (input);
}int main()
{srand((unsigned int)time(NULL));test();return 0;
}
4.效果展示图
六、总结
💘原创不易,还希望各位佬佬支持一下\textcolor{colourful}{💘原创不易,还希望各位佬佬支持一下}💘原创不易,还希望各位佬佬支持一下
💓点赞,你的认可是我创作的动力!\textcolor{red}{💓点赞,你的认可是我创作的动力!}💓点赞,你的认可是我创作的动力!
💕收藏,你的青睐是我努力的方向!\textcolor{orange}{💕收藏,你的青睐是我努力的方向!}💕收藏,你的青睐是我努力的方向!
💞评论,你的意见是我进步的财富!\textcolor{aqua}{💞评论,你的意见是我进步的财富!}💞评论,你的意见是我进步的财富!
✨请点击下面进入主页关注大魔王
如果感觉对你有用的话,就点我进入主页关注我吧!
相关文章:

智能三子棋(人机大战)—— 你会是最终赢家吗?万字讲解让你实现与自己对弈
魔王的介绍:😶🌫️一名双非本科大一小白。魔王的目标:🤯努力赶上周围卷王的脚步。魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥 ❤️…...

【自制开发板】自制STM32F407开发板(含TFT 8080串口屏幕接口)
【2023 年 2 月 14 日】 许久没有更新,最近做了个小开发板玩了玩。更新一下吧,作为记录!! 主要是象试一下LVGL在STM32上的应用,所以开发板的大小都是基于屏幕大小来设计的。 分享出来,给大家一个板子结构…...

openvino yolov5/ssd 实时推流目标检测在html上显示
安装ffmepg并添加到环境变量中,流媒体使用m7s 运行效果 SSD:检测在10ms左右,yolov5在100ms左右 app.py #!/usr/local/bin/python3 # encodin: utf-8import subprocess import threading import time import cv2 import osfrom OpenVinoYoloV…...

基于FPGA的 SPI通信 设计(1)
引言 低速通信目前搞过 UART串口通信、IIC通信。其实 SPI 也算是中低速(有时也可以用作高速通信)串行通信的范畴,但是一直还没真正实现过,所以此系列就 SPI的协议以及FPGA设计作几篇博客记录。欢迎订阅关注~ SPI 标准协议 x1模式…...

为什么西门子、美的等企业这样进行架构升级,看看改造效果就知道了
在工业领域, 生产、测试、运行阶段都可能会产生大量带有时间戳的传感器数据,这都属于典型的时序数据。时序数据主要由各类型实时监测、检查与分析设备所采集或产生,涉及制造、电力、化工、工程作业等多个行业,具备写多读少、量非常…...

open3d点云配准函数registration_icp
文章目录基本原理open3d调用绘图基本原理 ICP, 即Iterative Closest Point, 迭代点算法。 ICP算法有多种形式,其中最简单的思路就是比较点与点之间的距离,对于点云P{pi},Q{qi}P\{p_i\}, Q\{q_i\}P{pi},Q{qi}而言,如果二者是同一目标&am…...

HTML编码规范
本篇文章是基于王叨叨大佬师父维护的文档梳理的,有兴趣可以去看一下原文HTML编码规范。 1. 缩进与换行 【建议】 使用 2 个空格作为一个缩进层级,不允许使用tab字符 解释: 具体项目,可以使用2个空格,也可以使用…...

PDF SDK for Linux 8.4.2 Crack
PDF SDK for Linux 是适用于任何 Linux 企业或云应用程序的强大解决方案,非常适合需要完全可定制的 PDF 查看器或后端流程的任何 Linux 开发人员。 将 Foxit PDF SDK 嵌入到基于 Linux 的应用程序中非常容易。只需打开您最喜欢的 Linux IDE,复制您需要的…...

vb 模块和作用域的关系
模块在VB中有三种类型的模块,分别是窗体模块、标准模块和类模块。窗体模块窗体模块中包含了窗体以及窗体中所有控件的事件过程,文件扩展名为(*.frm),窗体文件中不仅包含窗体对象的外观设计,也包含窗体模块(…...

Redis分布式锁
一、背景 与分布式锁相对应的是「单机锁」,我们在写多线程程序时,避免同时操作一个共享变量产生数据问题,通常会使用一把锁来「互斥」,以保证共享变量的正确性,其使用范围是在「同一个进程」中。单机环境下࿰…...
京东前端经典面试题整理
img的srcset属性的作⽤? 响应式页面中经常用到根据屏幕密度设置不同的图片。这时就用到了 img 标签的srcset属性。srcset属性用于设置不同屏幕密度下,img 会自动加载不同的图片。用法如下: <img src"image-128.png" srcset&qu…...

django+mysql实现一个简单的web登录页面
目录 一、使用pyacharm创建一个django项目 二、启动django项目验证 三、配置mysql数据库 1、本地安装mysql数据库 1)安装mysql数据库 2)自己创建一个数据库 2、安装 pymysql 3、配置mysql数据库 1)在项目同名包下的_init_.py里面添加…...

python cartopy手动导入地图数据绘制底图/python地图上绘制散点图:Downloading:warnings/散点图添加图里标签
……开学回所,打开电脑spyder一看一脸懵逼,简直不敢相信这些都是我自己用过的代码,想把以前的自己喊过来科研了() 废话少说,最近写小综述论文,需要绘制一个地图底图+散点图ÿ…...
JavaScript中常用的数组方法
在日常开发中,我们会接触到js中数组的一些方法,这些方法对我们来说,可以很便利的达到我们想要的结果,但是因为方法比较多,有些方法也不常用,可能会过一段时间就会忘记,那么在这里我整理了一些数…...

磁疗为什么“没效果”?原来真相是这样!
很多人磁疗之后, 总爱迫不及待问一个问题: “这个多长时间见效啊?” …… 还有些人几天没有效果, 就果断下结论: “这东西没用!” …… 有不少人错误地把磁疗等同于“药品”一样看待,总觉得…...
【直击招聘C++】5.1函数模板
5.1函数模板一、要点归纳1.定义函数模板2.实例化函数模板3.重载模板函数4.函数调用的匹配顺序一、要点归纳 1.定义函数模板 定义函数模板的一般格式如下: template<类型形参表> 返回类型 函数名(形参表) {函数体; }例如以…...

谈谈Java多线程离不开的AQS
如果你想深入研究Java并发的话,那么AQS一定是绕不开的一块知识点,Java并发包很多的同步工具类底层都是基于AQS来实现的,比如我们工作中经常用的Lock工具ReentrantLock、栅栏CountDownLatch、信号量Semaphore等,而且关于AQS的知识点…...

国际化语言,多语言三种方式
可以用透传的方式,自己写local的json文件,不需要配置什么,直接传,自己写方法i18n nextjsi18n umi4一、透传的方式 export const AppContext React.createContext<any>({})app.tsx 用context包裹import type { AppProps } f…...

C++——哈希3|位图
目录 常见哈希函数 位图 位图扩展题 位图的应用 常见哈希函数 1. 直接定址法--(常用) 这种方法不存在哈希冲突 取关键字的某个线性函数为散列地址:Hash(Key) A*Key B 优点:简单、均匀 缺点:需要事先知道关键字的…...
75 error
全部 答对 答错 选择题 3. 某公司非常倚重预测型方法交付项目,而其招聘的新项目经理却习惯于运用混合型方法。项目范围包含很多不清晰的需求。项目经理应该如何规划项目的交付? A company that is heavily focused on delivering projects using predi…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...

工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...