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

HTML5 游戏开发实战 | 五子棋

01、五子棋游戏设计的思路

在下棋过程中,为了保存下过的棋子的信息,使用数组 chessData。chessData[x][y]存储棋盘(x,y)处棋子信息,1 代表黑子,2 代表白子,0 为无棋子。

整个游戏运行时,在鼠标单击事件中判断单击位置是否合法,既不能在已有棋的位置单击,也不能超出游戏棋盘边界,如果合法则将此位置信息加入 chessData,同时调用 judge(x,y,chess)判断游戏的输赢。

02、关键技术

判断输赢的算法

本游戏关键技术是判断输赢的算法。对于算法具体实现大致如下:

判断 X=Y 轴上是否形成五子连珠;

判断 X=-Y 轴上是否形成五子连珠;

判断 X 轴上是否形成五子连珠;

判断 Y 轴上是否形成五子连珠。

以上 4 种情况只要任何一种成立,那么就可以判断输赢。

判断输赢实际上不用扫描整个棋盘,如果能得到刚下的棋子位置(x,y),仅在此棋子附近横竖斜方向均判断一遍即可。

judge(x,y,chess)判断这个棋子是否和其他的棋子连成五子,即输赢判断。它是以(x,y)为中心,横向、纵向、斜方向判断并统计相同个数来实现的。

以水平方向(横向)判断为例,以(x,y)为中心计算水平方向棋子数量时,首先向左统计,相同则 count1 加 1;然后向右统计,相同则 count1 加 1。统计完成后,如果 count1>=5 则说明水平方向连成五子,其他方向同理。

function judge(x,y, chess)
//判断该局的输赢
//保存当前共有多少相同的黑色棋子相连var count1 =0;var count2 = 0;var count3 = 0;var count4 = 0://左右判断,横向的判断//判断横向是否有 5个棋子相连,特点是纵坐标相同,即 chessData[x][y]中y值是相同的//向左统计for(var i=x;i>=0;i--)[if(chessData[i][y] != chess){break;
count1++;
for(var i=x+1;<15; i++)!if(chessData[il[y] != chess) {break;
//向右统计
count1++
//上下判断,纵向的判断
for(var i=y;i>=0;i--)(if(chessData[x][i] != chess)break;
count2++;
for(var i=y+1;i<15;i++) /if(chessData[x][i] != chess)[break;
c懵ou对nt2++;
//左上右下判断for(var i=x,j=y;i>=0,j>=0;i--,j-- ){if(chessDatalilli] != chess)
break;count3++;
for(var i=x+1,j=y+1; < 15,j< 15; i++,j++) (if(chessData[i][j] != chess){break;
count3++:
//右上左下判断
for(var i=x,j=y;i>=0,j<15;i--,j++){if(chessDatalili] != chess)!
break;
count4++;
for(var i=x+1,j=y-1; i< 15,j>=0; i++,j-- ) {if(chessData[][j] != chess){break;
count4++;
count3
if(count1>=5count2 >
count4
if(chess == 1)
alert("白棋赢了");
else
alert("黑棋赢了");
isWell= true;//设置该局已经赢了,不可以再下棋

程序中 judge(x,y,chess)函数判断 4 种情况下是否连成五子从而判断出输赢。本程序中每下一步棋子,调用 judge(x,y,chess) 函数判断是否已经连成五子,如果已经连成五子,则弹出显示输赢结果对话框。

图形上色

如果想要给图形上色,有两个重要的属性可以做到:fillStyle 和 strokeStyle。

fillStyle = color
strokeStyle = color

strokeStyle 是用于设置图形轮廓的颜色,而 fillStyle 用于设置填充颜色。color 可以是表示 CSS 颜色值的字符串、渐变对象或者图案对象。默认情况下,线条和填充颜色都是黑色(CSS 颜色值 #000000)。

下面的例子都表示同一种颜色。

//这些 fillStyle 的值均为,橙色
ctx.fillStyle="orange";
ctx.fillStyle="#FFA500";
ctx.fillStyle="rgb(255,165,0)";
ctx.fillStyle ="rgba(255,165,0,1)";

本游戏中棋盘的背景色即是采用“orange”。

context.fillStyle="orange";
context.fillRect(0,0,640,640);

03、五子棋游戏设计的步骤

游戏页面 five.html

游戏页面很简单,就是页面加载调用 drawRect()函数绘制棋盘,从而开始游戏。

/head >
<body onload ="drawRect()">
<div>
< canvas width= "640”id = "canvas"onmousedown = "play(event)" height = "640"> </canvas >
</div>
</body>
</htmI>

设计脚本(Main.js)

1. 初始化棋盘数组

定义两个棋子图片对象 img_b 和 img_w,初始化棋盘数组 chessData,其值 0 为没有走过的,1 为白棋走的,2 为黑棋走的;所以最初值都是 0。

"text/javascript">script type =c
var canvas ;
var context;
var isWhite = false;
//设置是否该轮到白棋
var isWell = false;
var img b =new Image();
img b.src="images/w.png";
//设置该局棋盘是否赢了,如果赢了就不能再走了
//白棋图片
var img w =new Image();img w.src ="images/b.png";//这个为棋盘的二维数组,用来保存棋盘信息var chessData = new Arrav(15)://初始化 0 为没有走过的,1 为白棋走的,2 为黑棋走的for(var x=0;x<15; x++)chessData[x]= new Array(15);for (var y=0;y<15; y++)chessData[x][y] = 0;
//黑棋图片

2. 绘制棋盘

页面加载完毕时调用 drawRect()函数,在页面上绘制 15×15 五子棋棋盘。

function drawRect() 
//页面加载完毕调用函数,页面上绘制五子棋棋盘canvas = document.getElementById("canvas");context = canvas.getContext("2d");
context.fillStyle="orange";
context.fillRect(0,0,640,640):
context.fillStyle="#000000":
//绘制棋盘的线for(var i=0;i<=640;i+=40)[
context.beginPath();
context.moveTo(0,i);
context.lineTo(640,i);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(i,0);
context.lineTo(i,640);
context.closePath();
context.stroke();

3. 走棋函数

鼠标单击事件中判断单击位置是否合法,既不能在已有棋的位置单击,也不能超出游戏棋盘边界,如果合法则将此位置信息记录到 chessData(数组)中,最后是本游戏关键输赢判断。程序中调用 judge(x,y,chess)函数判断输赢。判断 4 种情况下是否连成五子,得出谁赢。

function play(e)[
//鼠标单击时发生
//从像素坐标换算成棋盘坐标
//计算鼠标单击的位置,如果单击(65,65)位置,那么就是棋盘(1,1)的位置var x = parseInt((e.clientX - 20)/40);
var y= parseInt((e.clientY - 20)/ 40);
//判断该位置是否被下过了
if(chessData[x][y] != 0)[
alert("你不能在这个位置下棋");
return;
if(isWhite)(
//是否是白棋
isWhite= false;
drawChess(1,x,y);
else(
isWhite = true;
drawChess(2,x,y);
//换下一方走棋//绘制白棋
//换下一方走棋
//绘制黑棋

4. 画棋子函数

drawChess(chess,x,y)函数中参数 chess 为棋(1 为白棋,2 为黑棋),(x,y)为棋盘即数组位置。

function drawChess(chess,x,y )//参数 chess 为棋(1 为白棋,2 为黑棋),,为数组位置
function drawChess(chess,x,y)if(isWell== true)
{alert("已经结束了,如果想要重新玩,请刷新”);
return;
}
if(x>=0&& x<15 && y>=0&& y<15){if(chess==1){context.drawImage(img_w,x * 40+20,y * 40+20);//绘制白棋
chessData[x][y] = 1;
else!context.drawImage(img b,x * 40+20,y * 40+20);//绘制黑棋
chessData[x][y] = 2;
judge(x,Y,chess);
}
}

04、人机五子棋游戏的开发

前面开发的五子棋游戏仅仅能够实现两个人轮流下棋,如果改进成人机五子棋对弈则比较具有挑战性。人机五子棋对弈需要人工智能技术,棋类游戏实现人工智能的算法通常有以下 3 种。

(1) 遍历式算法。

这种算法的原理是:按照游戏规则,遍历当前棋盘布局中所有可以下棋的位置,然后假设在第一个位置下棋,得到新的棋盘布局,再进一步遍历新的棋盘布局。如果遍历到最后也不能战胜对手,则退回到最初的棋盘布局,重新假设在第二个位置下棋,继续遍历新的棋盘布局,这样反复地遍历,直到找到能最终战胜对手的位置。这种算法可使电脑棋艺非常高,每一步都能找出最关键的位置。然而这种算法的计算量非常大,对 CPU 的要求很高。

(2) 思考式算法。

这种算法的原理是:事先设计一系列的判断条件,根据这些判断条件遍历棋盘,选择最佳的下棋位置。这种算法的程序往往比较复杂而且只有本身棋艺很高的程序员才能制作出“高智商的电脑”。

(3) 棋谱式算法。

这种算法的原理是:事先将常见的棋盘局部布局存储成棋谱,然后在走棋之前只对棋盘进行一次遍历,依照棋谱选择关键的位置。这种算法的程序思路清晰,计算量相对较小,而且只要棋谱足够多,也可以使电脑的棋艺达到一定的高度。

本实例采用棋谱式算法,实现人工智能。为此设计 Computer 类,实现电脑(白方)落子位置的计算。

首先,使用数组 Chess 存储棋谱,形式如下:黑棋(B),白棋(W),无棋(N),需要下棋位置(S)。

image.png


数组中行数越高,表明该行棋谱中 S 位置越重要,电脑走最重要的位置。

例如,棋谱[N,S,B,B,B ]表示玩家(人)的黑棋(B)已有三子连线了,电脑必须在此附近下棋,其中 S 为需要电脑下子的位置,N 为空位置。棋谱[S,B,B,B,B ]表示玩家(人)的黑棋(B)已有四子连线了。当然棋谱[S,B,B,B,B ]级别高于棋谱[N,S,B,B,B ]。

然后,有了棋谱后就是遍历棋盘的信息是否符合某个棋谱,判断时从级别高的棋谱判断到级别低的棋谱(即从数组中行数最高 Chess.length-1 开始判断)。如果符合某个棋谱,则按棋谱指定的位置存储到(m_nCurRow,m_nCurCol),如果所有棋谱都不符合,则随便找一个空位置。

实现人工智能的算法的 coputer.js 脚本如下:

var KONG = 0;
var BLACK = 2;
var WHITE = 1;
var N= 0;
var B= 2;
var W= 1;
//空位置 KONG
//黑色棋子//白色棋子//空位置//有黑色棋子(人的棋)
//有白色棋子(电脑的棋)

image.png

image.png

this.x = x;
this.y= y;
//获取电脑下子位置
function GetComputerPos()
//返回Point
return new Point(m nCurCol,m nCurRow):
//电脑根据输入参数 grid(棋盘),计算出落子位置(m_nCurRow,m_nCurCol)//grid 是 Arrayfunction Input(qrid)var rowSel,colSel,nLevel;
var index,nLevel;
var j;
m nCurCol=-1;
m nCurRow = -1;
nLevel= -1;
var bFind;
for(var row =0; row < 15; row ++)
{//遍历棋盘的所有行
//存储临时的选择位置
//存储临时选择的棋谱级别//是否符合棋谱的标志
for(var col= 0;col < 15; col ++)
(//遍历棋盘的所有列
for(var i= Chess.length- 1;i>= 0;i-- )//遍历所有级别的棋谱//查看从当前棋子开始的横向五个棋子是否符合该级别的棋谱if(col+4<15)rowSel= -1;colSel= -1;bFind =使炽鼓 true;for(j=0;j< 5;j++)
index = grid[col + j][row]if( index == KONG)[//如果该位置没有棋子,对应的棋谱位置上只能是 S或 Nif(Chess[i][j]== S){//如果是 S,则保存位置rowSel= row;colSel= col+j;
else if(Chess[i][j] != N)
[//不是 S也不是 n,则不符合这个棋谱,结束循环
bFind = false;
break;
if(index == BLACK && Chess i != B){//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环bFind = false;break;
if(index == WHITE && Chess il  != W)[//如果是白色棋,对应的棋谱位置上应是 ,否则结束循环bFind = false;
break;
if(bFind && i> nLevel)
{//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高
nLevel= i;
m nCurCol=colSel;
//保存级别
//保存位置
m nCurRow = rowSel;
break;
//遍历其他级别的棋谱
//查看从当前棋子开始的纵向五个棋子是否符合该级别的棋谱if(row+4<15)
rowSel= -1;colSel= -1;bFind = true;for(j=0;j<5;j++)index = grid[ col][ row + j];if(index == KONG){//如果该位置没有棋子,对应的棋谱位置上只能是 S 或Nif(Chess[illil== S){//如果是 S,则保存位置rowSel= row + i;colSel = col;else if(Chess[illil != N)
{//不是 S 也不是 n,则不符合这个棋谱,结束循环bFind = false:break;if(index == BLACK)[//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环if(Chess[il[i] != B)bFind = false;
break;
if(index == WHITE && Chess[illi] != W){//如果是白色棋,对应的棋谱位置上应是 ,否则结束循环bFind = false;break;
if(bFind && i> nLevel){//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高nLevel= i;m nCurCol=colSel;m nCurRow = rowSel;
//保存级别
//保存位置
break;
//遍历其他级别的棋谱
}
}
//查看从当前棋子开始的斜 45°向下的五个棋子是否符合该级别的棋谱if(col-4>=0&& rw+4<15)
rowSel= -1;colSel = -1;bFind = true;for(j=0;j< 5;j++)
index = grid[col - j][ row + jl;if(index == KONG)[//如果该位置没有棋子,对应的棋谱位置上只能是 S 或 Nif(Chess[i][j]== S)[//如果是 S,则保存位置rowSel = row + j;colSel= col-j;else if(Chess[il[i] != N){//不是 S 也不是 n,则不符合这个棋谱,结束循环bFind = false;break;
if(index == BLACK && Chess[i][j] != B)
[//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环bFind = false;
break;
if(index == WHITE && Chess   != W){//如果是白色棋,对应的棋谱位置上应是 ,否则结束循环bFind = false;
break;
if(bFind && i> nLevel){//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高
//保存级别
nLevel =i;
//保存位置m nCurCol= colSel;
m nCurRow = rowSel;
break;
//遍历其他级别的棋谱
//斜 135度的五个棋子
if(col+4<15 && row+4<15)
{//查看从当前棋子开始的斜 135向下的五个棋子是否符合该级别棋谱rowSel= -1;
colSel= -1;bFind = true;for(j=0;j<5;j++)
index = grid[col + j][row + jl;if(index == KONG)[//如果该位置没有棋子,对应的棋谱位置上只能是 S或Nif(Chess[il[jl== S){//如果是 S,则保存位置rowSel = row + j;
colSel= col+j;
else if(Chess[illi  != N){//不是 S 也不是 n,则不符合这个棋谱,结束循环bFind = false;
break;
if(index == BLACK && Chessil] != B)[//如果是黑色棋,对应的棋谱位置上应是 B,否则结束循环bFind = false;
break;if(index == WHITE && Chess[ill] = W)[//如果是白色棋,对应的棋谱位置上应是 w,否则结束循环bFind = false;
break;if(bFind && i> nLevel)
[//如果符合此棋谱,且该棋谱比上次找到的棋谱的级别高nLevel=i;m nCurCol= colSel;//保存位置
//保存级别
m nCurRow = rowSel;
break;
//遍历其他级别的棋谱
if(m nCurRow != -1)
[//如果选择了一个最佳位置
grid[m nCurCol][m nCurRow] = WHITE;return true;
//如果所有棋谱都不符合,则随便找一个空位置while(true
var col;
var row;
col = int(Math.random()*15);row = int(Math.random()*15)if(grid[ col][row]== KONG)
//随便找一个位置
grid[col][row]= WHITE;
m nCurCol = col;
m nCurRow = row;return true;
return false;

在游戏页面 five.html 中,由于使用上面 coputer.js 脚本,所以需要在中添加:

由于只有玩家(黑棋)需要单击棋盘落子,不再轮流下子,所以对单击事件响应函数 play(e)进行修改,玩家(黑棋)落子后,判断此时玩家(黑棋)是否赢了。如果赢了则游戏结束,否则直接电脑(白方)自动计算落子,电脑(白方)自动落子是调用 Input(chessData)函数实现计算白子位置,GetComputerPos()函数获取电脑落子位置 P,获取电脑落子位置后,在位置 P 显示白子并判断此时电脑是否赢了。

function play(e){var x = parseInt((e.clientX- 20) / 40);var y= parseInt((e.clientY- 20) / 40);if(chessDatalx][y] != 0) [
//鼠标单击时发生
//计算鼠标单击的区城
//判断该位置是否被下过了
alert("你不能在这个位置下棋");
return;
drawChess(2,x,y);//轮到电脑(白方)走Input(chessData);var p = GetComputerPos();drawChess(1,p.x,p.y);
//获取电脑落子位置 P
}

本文实现经典的五子棋游戏的基本功能,并且能够判断输赢,并把系统改进成人机对战版,使得游戏更具挑战性,从而更吸引玩家。

相关文章:

HTML5 游戏开发实战 | 五子棋

01、五子棋游戏设计的思路 在下棋过程中&#xff0c;为了保存下过的棋子的信息&#xff0c;使用数组 chessData。chessData&#xff3b;x&#xff3d;&#xff3b;y&#xff3d;存储棋盘(x&#xff0c;y)处棋子信息&#xff0c;1 代表黑子&#xff0c;2 代表白子&#xff0c;0…...

rust学习-json的序列化和反序列化

由于 serde 库默认使用 JSON 格式进行序列化和反序列化 因此程序将使用 JSON 格式对数据进行序列化和反序列化 社区为 Serde 实现的部分数据格式列表: JSON:广泛使用的 JavaScript 对象符号,用于许多 HTTP APIPostcard:no_std 和嵌入式系统友好的紧凑二进制格式。CBOR:用…...

基于MapReduce的Hive数据倾斜场景以及调优方案

文章目录 1 Hive数据倾斜的现象1.1 Hive数据倾斜的场景1.2 解决数据倾斜问题的优化思路 2 解决Hive数据倾斜问题的方法2.1 开启负载均衡2.2 引入随机性2.3 使用MapJoin或Broadcast Join2.4 调整数据存储格式2.5 分桶表、分区表2.6 使用抽样数据进行优化2.7 过滤倾斜join单独进行…...

mysql 02 数据库的约束

为防止错误的数据被插入到数据表&#xff0c;MySQL中定义了一些维护数据库完整性的规则&#xff1b;这些规则常称为表的约束。常见约束如下&#xff1a; 主键约束 主键约束即primary key用于唯一的标识表中的每一行。被标识为主键的数据在表中是唯一的且其值不能为空。这点类似…...

Quivr 基于GPT和开源LLMs构建本地知识库 (更新篇)

一、前言 自从大模型被炒的越来越火之后&#xff0c;似乎国内涌现出很多希望基于大模型构建本地知识库的需求&#xff0c;大概在5月底的时候&#xff0c;当时Quivr发布了第一个0.0.1版本&#xff0c;第一个版本仅仅只是使用LangChain技术结合OpenAI的GPT模型实现了一个最基本的…...

Unity如何制作声音控制条(控制音量大小)

一&#xff1a;UGUI制作 1. 首先在【层级】下面创建UI里面的Slider组件。设置好它对应的宽度和高度。 2.调整Slider滑动条的填充颜色。一般声音颜色我黄色&#xff0c;所以我们也调成黄色。 我们尝试滑动Slider里面的value。 a.滑动前。 b.滑动一半。 c.滑动完。 从以上滑动va…...

非计算机科班如何顺利转行计算机领域?

文章目录 每日一句正能量前言如何规划才能实现转计算机&#xff1f;计算机岗位发展前景&#xff1f;现阶段转计算机的建议后记 每日一句正能量 改变思路&#xff0c;改变习惯&#xff0c;改变一种活的方式&#xff0c;往往会创造无限&#xff0c;风景无限&#xff01; 前言 近年…...

Android音视频剪辑器自定义View实战!

Android音视频剪辑器自定义View实战&#xff01; - 掘金 /*** Created by zhouxuming on 2023/3/30** descr 音视频剪辑器*/ public class AudioViewEditor extends View {//进度文本显示格式-数字格式public static final int HINT_FORMAT_NUMBER 0;//进度文本显示格式-时间…...

stm32_ADC电源、通道、工作模式

0、ADC功能框图 1、ADC的电源 1.1、工作电源 VSSAVSS&#xff0c;VDDAVDD&#xff0c;简单来说&#xff0c;通常stm32是3.3V&#xff0c;ADC的工作电源也是3.3V&#xff1b; 1.2、参考电压 VREF和VREF-并不一定引出&#xff0c;取决于封装&#xff0c;如果没有引出则VREF连接到…...

Vue编程式路由导航

目录 一、使用 一、使用 不使用<router-link>标签&#xff0c;利用$router中的api实现跳转&#xff0c;更灵活 <template><div><ul><li v-for"m in messageList" :key"m.id"><!-- 跳转路由并携带params参数&#xff0c…...

LVS-DR模式

目录 1、概述 2、LVS-DR模式的工作原理&#xff1a; 3、在LVS-DR模式下&#xff0c;数据包的流向分析如下&#xff1a; 4、LVS-DR是一种用于构建高可用性负载均衡集群的技术模式。LVS-DR模式具有以下特点&#xff1a; 5、LVS-DR中的ARP问题 6、配置LVS-DR需要以下几个关键…...

详细介绍生成对抗网络 (GAN) 的原理和基于Pytorch源码的实现

介绍 GAN 是一种使用 CNN(卷积神经网络)等深度学习方法进行生成建模的方法。生成建模是一种无监督学习方法,涉及自动发现和学习输入数据中的模式,以便该模型可用于从原始数据集中生成新示例。 GAN 是一种通过将问题构建为具有两个子模型的监督学习问题来训练生成模型的方…...

高性能数据处理选型

1、Redis(高性能) 2、Elasticsearch/HBase( 大数据 ) 3、MongoDB(海量数据)...

【深入理解C语言】-- 关键字2

&#x1f407; &#x1f525;博客主页&#xff1a; 云曦 &#x1f4cb;系列专栏&#xff1a;深入理解C语言 &#x1f4a8;吾生也有涯&#xff0c;而知也无涯 &#x1f49b; 感谢大家&#x1f44d;点赞 &#x1f60b;关注&#x1f4dd;评论 文章目录 前言一、关键字 - static&…...

Java进阶(3)——手动实现ArrayList 源码的初步理解分析 数组插入数据和删除数据的问题

目录 引出手动实现ArrayList定义接口MyList<T>写ArrayList的实现类增加元素删除元素 写测试类进行测试数组插入数据? 总结 引出 1.ArrayList的结构分析&#xff0c;可迭代接口&#xff0c;是List的实现&#xff1b; 2.数组增加元素和删除元素的分析&#xff0c;何时扩容…...

若依前端npm run dev启动时报错

本文主要解决问题:若依前端npm run dev启动时报错,解决办法。 目录 1、第1种解决方案(亲测有效) 2、第2种解决方案(亲测有效) Error: error:0308010C:digital envelope routines::unsupportedat new Hash (node:internal/crypto/hash:67:19)at Object.createHash (node…...

实战项目:基于主从Reactor模型实现高并发服务器

项目完整代码仿mudou库one thread one loop式并发服务器实现: 仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff1a;通过模拟实现的⾼并发服务器组件&#xff0c;可以简洁快速的完成⼀个⾼性能的服务器搭建。并且&#xff0c;通过组件内提供的不同应⽤层…...

iTOP-RK3568开发板ubuntu环境下安装Eclipse

eclipse 是使用 Java 语言开发的&#xff0c;一个 Java 应用程序&#xff0c;这意味着 eclipse 只能运行在 Java虚拟机上。倘若没有安装 JDK&#xff08;Java Development Kit&#xff09;&#xff0c;即使在 ubuntu 上安装了 eclipse&#xff0c;也不能运行&#xff0c;所以要…...

大气热力学

大气稳定度 大气稳定度又称为大气层结稳定度(贺德馨,2006)。大气层结指的是大气温度和湿度在垂直方向上的分布&#xff0c;对大气中污染物的扩散起着重要的作用。在静止大气中&#xff0c;假定气团受到垂直方向的扰动后&#xff0c;有一个向上的微小位移&#xff0c;如果大气层…...

【RabbitMQ】消息队列-RabbitMQ篇章

文章目录 1、RabbitMQ是什么2、Dokcer安装RabbitMQ2.1安装Dokcer2.2安装rabbitmq 3、RabbitMQ入门案例 - Simple 简单模式4、RabbitMQ的核心组成部分4.1 RabbitMQ整体架构4.2RabbitMQ的运行流程 5、RabbitMQ的模式5.1 发布订阅模式--fanout 1、RabbitMQ是什么 RabbitMQ是一个开…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

基于Docker Compose部署Java微服务项目

一. 创建根项目 根项目&#xff08;父项目&#xff09;主要用于依赖管理 一些需要注意的点&#xff1a; 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件&#xff0c;否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...