【標準項目】在線五子棋對決(下)

在線五子棋對決

  • 一. 項目介紹及鏈接
  • 二. 項目結構設計
    • 項目模塊劃分
    • 業務處理模塊的子模塊劃分
    • 項目流程圖
      • 玩家流程圖
      • 服務器流程圖
  • 三. 數據管理模塊
    • 數據庫設計
    • 創建 user_table 類
  • 四. 在線用戶管理模塊
  • 五. 游戲房間管理模塊
    • 游戲房間類實現
    • 游戲房間管理類實現
  • 六. Session 管理模塊
    • Session 類實現
    • Session 管理類實現
  • 七. 五子棋對戰玩家匹配管理模塊
    • 匹配隊列類實現
    • 匹配隊列管理類實現
  • 八. 整合封裝服務器模塊
    • 通信接口設計 (Restful風格)
      • 靜態資源請求
      • 注冊用戶請求
      • 用戶登錄請求
      • 獲取用戶信息請求
      • 切換 WebSocket 通信協議請求 (進入游戲大廳)
      • 對戰匹配請求
      • 停止對戰匹配請求
      • 切換 WebSocket 通信協議請求 (進入游戲房間)
      • 下棋請求
      • 聊天請求
    • 服務器類實現
  • 九. 客戶端開發
    • 注冊頁面:register.html
    • 登入頁面:login.html
    • 游戲大廳頁面:game_hall.html
    • 游戲房間頁面:game_room.html

一. 項目介紹及鏈接

本項目主要實現一個網頁版的五子棋對戰游戲,其主要支持以下核心功能:

  • 用戶管理:實現用戶注冊,用戶登錄、獲取用戶信息、用戶天梯分數記錄、用戶比賽場次記錄等。
  • 匹配對戰:實現兩個玩家在網頁端根據天梯分數匹配游戲對手,并進行五子棋游戲對戰的功能。
  • 聊天功能:實現兩個玩家在下棋的同時可以進行實時聊天的功能。

二. 項目結構設計

項目模塊劃分

項目模塊劃分三個大模塊來進行:

  • 數據管理模塊:基于 MySQL 數據庫進行用戶數據的管理。
  • 前端界面模塊:基于 JS 實現前端頁面 (注冊,登錄,游戲大廳,游戲房間) 的動態控制以及與服務器的通信。
  • 業務處理模塊:搭建 WebSocket 服務器與客戶端進行通信,接收請求并進行業務處理。

項目要實現的是一個在線五子棋對戰服務器,提供用戶通過瀏覽器進行用戶注冊,登錄,以及實時匹配,對戰,聊天等功能。而如果要實現這些功能,那么就需要對業務處理模塊再次進行細分為多個模塊來實現各個功能。

在這里插入圖片描述

業務處理模塊的子模塊劃分

  • 網絡通信模塊:基于 websocketpp 庫實現 HTTP 和 WebSocket 服務器的搭建,提供網絡通信功能。
  • 會話管理模塊:對客戶端的連接進行 Cookie 和 Session管理,實現 HTTP 短連接時客戶端身份識別功能。
  • 在線管理模塊:對進入游戲大廳與游戲房間中用戶進行管理,提供用戶是否在線以及獲取用戶連接的功能。
  • 房間管理模塊:為匹配成功的用戶創建對戰房間,提供實時的五子棋對戰與聊天業務功能。
  • 用戶匹配模塊:根據天梯分數不同進行不同層次的玩家匹配,為匹配成功的玩家創建房間并加入房間。

項目流程圖

玩家流程圖

在這里插入圖片描述

服務器流程圖

在這里插入圖片描述

三. 數據管理模塊

數據管理模塊主要負責對于數據庫中數據進行統一的增刪改查管理,其他模塊要對數據操作都必須通過數據管理模塊完成。

數據庫設計

創建 user 表,用來表示用戶信息及積分信息。

  • 用戶信息:實現登錄、注冊、游戲對戰數據管理等功能 (用戶 id,用戶名,密碼,總場數,勝場數)
  • 積分信息:實現匹配功能 (游戲分數)
drop database if exists gobang;
create database if not exists gobang;
use gobang;
create table if not exists user(id int primary key auto_increment,username varchar(32) unique key not null,password varchar(128) not null,score int,total_count int,win_count int
);

驗證數據庫是否創建成功:
在這里插入圖片描述
在這里插入圖片描述

創建 user_table 類

數據庫中有可能存在很多張表,每張表中管理的數據又有不同,要進行的數據操作也各不相同,因此我們可以為每一張表中的數據操作都設計一個類,通過類實例化的對象來訪問這張數據庫表中的數據,這樣的話當我們要訪問哪張表的時候,使用哪個類實例化的對象即可。

創建 user_table 類,該類的作用是負責通過 MySQL 接口管理用戶數據,主要提供了四個方法:

  • select_by_name:根據用戶名查找用戶信息,用于實現登錄功能。
  • insert:新增用戶,用戶實現注冊功能。
  • login:登錄驗證,并獲取完整的用戶信息。
  • win:用于給獲勝玩家修改分數。
  • lose:用戶給失敗玩家修改分數。

位于 db.hpp 文件

存在密碼不滿足要求,也就是密碼太簡單了,需要設置密碼等級,如下:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

四. 在線用戶管理模塊

  • 管理的兩類用戶:是對于 “進入游戲大廳” 和 “進入游戲房間” 的用戶。
  • 原因:進入游戲大廳和進入游戲房間的用戶才會建立 WebSocket 長連接。
  • 管理:將用戶 id 和對應的客戶端 WebSocket 長鏈接關聯起來。
  • 作用:當一個用戶發送了消息 (實時聊天/下棋消息),可以找房間中的其它用戶,在在線用戶管理模塊中,找到這個用戶對應的 WebSocket 長連接,然后將消息發送給指定的用戶,模塊的兩個功能如下:
    • 通過用戶 id 找到用戶的 WebSocket 連接進而實現向指定用戶的客戶端推送消息,WebSocket 連接關閉時,會自動在在線用戶管理模塊中刪除自己的信息。
    • 可以通過在線用戶管理模塊判斷一個用戶是否在線,或者判斷用戶是否已經掉線。

位于 online.hpp 文件

五. 游戲房間管理模塊

游戲房間類實現

  • 對匹配成功的玩家創建房間,建立起一個小范圍的玩家之間的關聯關系,房間里的一個玩家產生的動作會廣播給房間里的其它用戶。
  • 因為房間有可能會有很多,因此需要將這些房間管理起來以便于對于房間生命周期的控制。
  • 房間中產生的動作:下棋和聊天都要廣播給房間里的其它用戶。
  • 實現的兩個部分:房間的設計、房間管理的設計。
    • 房間的設計:房間的ID、房間的狀態 (正在游戲/游戲結束,決定玩家退出時誰勝利)、房間中用戶的數量 (決定了房間什么時候銷毀)、白棋玩家ID、黑棋玩家ID、用戶信息表的句柄 (當玩家勝利/失敗時更新用戶數據)、棋盤信息 (二維數組)、在線用戶的管理句柄 (廣播數據時需要)

位于 room.hpp 文件

游戲房間管理類實現

需要管理的數據:

  • 數據管理模塊句柄。
  • 在線用戶管理模塊句柄。
  • 房間 ID 分配計數器。
  • 用戶 ID 映射房間 ID 的哈希表。
  • 房間 ID 映射房間信息的哈希表。
  • 互斥鎖。

功能:

  • 創建房間:兩個玩家對戰匹配完成了,為他們創建一個房間,需要傳入兩個玩家的用戶 ID
  • 查找房間:通過房間 ID 查找房間信息,通過用戶 ID 查找所在房間信息。
  • 銷毀房間:通過房間 ID 銷毀,房間中所有用戶都退出了,銷毀房間。

位于 room.hpp 文件

六. Session 管理模塊

在 Web 開發中,HTTP 協議是一種無狀態短鏈接的協議,這就導致一個客戶端連接到服務器上之后,服務器不知道當前的連接對應的是哪個用戶,也不知道客戶端是否登錄成功,這時候為客戶端提供所有服務是不合理的。第一次HTTP請求登入使用的是密碼,接下來的HTTP請求,由于無狀態短鏈接不知道用戶是誰,需要重新登入,這是不合理的。

因此,服務器為每個用戶瀏覽器創建一個會話對象 (Session 對象),注意:一個瀏覽器獨占一個 Session 對象 (默認情況下)。因此,在需要保存用戶數據時,服務器程序可以把用戶數據寫到用戶瀏覽器獨占的 Session 中,當用戶使用瀏覽器訪問其它程序時,其它程序可以從用戶的 Session 中取出該用戶的數據,識別該連接對應的用戶,并為用戶提供服務。

Session 工作原理:

在這里插入圖片描述

使用 Cookie 和 Session 進行 HTTP 在短連接通信的情況下進行用戶狀態管理,但是這個服務器上管理的 Session 都會有過期時間,超過時間就會將對應的 Session 刪除,每次客戶端與服務器的通信都需要延長 Session 的過期時間。

Session 類實現

簡單設計 session 類,但是 session 對象不能一直存在,這是一種資源泄漏,因此需要使用定時器對每個創建的 session 對象進行定時銷毀 (一個客戶端連接斷開后,一段時間內都沒有重新連接則銷毀 session),成員對象如下:

  • ssid:會話id
  • uid:用戶id
  • status:用戶狀態 (登入/未登入)
  • timer_ptr:保存當前 session 對應的定時銷毀任務。

位于 session.hpp 文件

Session 管理類實現

session 管理:

  • 創建一個新的 session
  • 通過 ssid 獲取 session
  • 通過 ssid 判斷 session 是否存在。
  • 銷毀 session
  • 為 session 設置過期時間,過期后 session 被銷毀。

位于 session.hpp 文件

七. 五子棋對戰玩家匹配管理模塊

匹配隊列類實現

五子棋對戰的玩家匹配是根據自己的天梯分數進行匹配,而服務器中將玩家天梯分數分為三個檔次:

  • 青銅:天梯分數小于 2000 分。
  • 白銀:天梯分數介于 2000~3000 分之間。
  • 黃金:天梯分數大于 3000 分。

實現玩家匹配的思想非常簡單,為不同的檔次設計各自的匹配隊列,當一個隊列中的玩家數量大于等于2的時候,則意味著同一檔次中,有2個及以上的人要進行實戰匹配,則出隊隊列中的前兩個用戶,相當于隊首2個玩家匹配成功,這時候為其創建房間,并將兩個用戶信息加入房間中。

位于 matcher.hpp 文件

匹配隊列管理類實現

匹配管理:

  • 三個不同玩家水平的隊列。
  • 三個線程分別對三個隊列中的玩家進行匹配。
  • 房間管理模塊的句柄:為匹配成功的玩家創建房間。
  • 在線用戶管理模塊句柄:為匹配成功的玩家添加到在線用戶管理中。
  • 數據庫管理模塊用戶表句柄:通過玩家 id 查看玩家的天梯分數,進行玩家匹配。

功能接口:

  • 添加用戶到匹配隊列。
  • 從匹配隊列移除玩家。
  • 線程入口函數:判斷指定隊列人數是否大于2,出隊兩個玩家,創建房間,將兩個玩家添加到房間中,向兩個玩家發送對戰匹配成功的消息。

位于 matcher.hpp 文件

八. 整合封裝服務器模塊

通信接口設計 (Restful風格)

靜態資源請求

  • 靜態資源頁面:在后臺服務器上就是個 html/css/js 文件。
    • 注冊頁面請求。
    • 登入頁面請求。
    • 游戲大廳頁面請求。
    • 游戲房間頁面請求。
  • 靜態資源請求的處理:就是將文件中的內容發送給客戶端。
# 注冊頁面請求
請求:GET /register.html HTTP/1.1
響應:
HTTP/1.1 200 OK
Content-Length: xxx
Content-Type: text/htmlregister.html文件內容數據# 登錄頁面請求
請求:GET /login.html HTTP/1.1
# 大廳頁面請求
請求:GET /game_hall.html HTTP/1.1
# 房間頁面請求
請求:GET /game_room.html HTTP/1.1

注冊用戶請求

// 請求
POST /reg HTTP/1.1
Content-Type: application/json{"username":"zhangsan", "password":"123456"}// 成功時的響應
HTTP/1.1 200 OK
Content-Type: application/json{"result":true, "reason": "注冊用戶成功"}// 失敗時的響應 
HTTP/1.1 400 Bad Request
Content-Type: application/json{"result":false, "reason": "用戶名已經被占用"}

用戶登錄請求

// 請求
POST /login HTTP/1.1
Content-Type: application/json{"username":"zhangsan", "password":"123456"}// 成功時的響應
HTTP/1.1 200 OK
Content-Type: application/json
Set-Cookie: 123456{"result":true, "reason": "登入成功"}// 失敗時的響應 
HTTP/1.1 400 Bad Request
Content-Type: application/json{"result":false, "reason": "用戶名/密碼錯誤"}

獲取用戶信息請求

// 請求
POST /info HTTP/1.1
Content-Type: application/json// 成功時的響應
HTTP/1.1 200 OK
Content-Type: application/json{"username":"xzy", "score":1000, "total_count":4, "win_count":2}// 失敗時的響應 
HTTP/1.1 400 Bad Request
Content-Type: application/json{"result":false, "reason": "找不到用戶信息信息, 請重新登入"}

切換 WebSocket 通信協議請求 (進入游戲大廳)

// 成功響應
{"optype": "hall_ready","result": true;
}
// 失敗響應
{"optype": "hall_ready","reason": "玩家重復登入""result": false;
}

對戰匹配請求

// 客戶端:開始匹配玩家的信息
{"optype": "match_start","uid": 1
}// 服務器:開始匹配玩家正確的信息
{"optype": "match_start","result": true
}
// 服務器:開始匹配玩家錯誤的信息
{"optype": "match_start","result": false,"reason": "具體原因...."
}// 服務器:匹配玩家成功的信息
{"optype": "match_success","result": true
}

停止對戰匹配請求

// 客戶端:停止匹配玩家的信息
{"optype": "match_stop""uid": 1
}// 服務器:停止匹配玩家正確的信息
{"optype": "match_stop","result": true
}
// 服務器:停止匹配玩家錯誤的信息
{"optype": "match_stop","result": false,"reason": "具體原因...."
}

切換 WebSocket 通信協議請求 (進入游戲房間)

// 成功響應
{"optype": "room_ready","room_id": 222,"uid": 1,"white_id": 1,"black_id": 2,"result": true;
}
// 失敗響應
{"optype": "room_ready","reason": "玩家重復登入""result": false;
}

下棋請求

// 請求
{"optype": "put_chess","room_id": 222,"uid": 1, // 下棋用戶的id"row": 3,"col": 2
}// 失敗響應
{"optype": "put_chess","result": false"reason": "走棋失敗具體原因...."
}
// 成功響應
{"optype": "put_chess","room_id": 222,"uid": 1, // 下棋用戶的id"row": 3,"col": 2,"result": true,"reason": "五星連珠,戰無敵","winner": 0 // 0 代表沒有分出勝負,具體的數字代表獲勝用戶的id
}

聊天請求

// 請求
{"optype": "chat","room_id": 222,"uid": 1,"message": "快點吧,等的花都謝了"
}// 失敗響應
{"optype": "chat","result": false"reason": "消息中包含敏感詞匯,無法發送"
}
// 成功響應
{"optype": "chat","result": true,"room_id": 222,"uid": 1,"message": "快點吧,等的花都謝了"
}

服務器類實現

服務器模塊:對當前所實現的所有模塊的一個整合,并進行服務器搭建的一個模塊,最終封裝實現出一個 gobang_server 的服務器模塊類,向外提供搭建五子棋對戰服務器的接口,通過實例化的對象可以簡便的完成服務器的搭建。

服務器的整合實現:

  • 網絡通信接口的設計:
    • 收到一個什么格式的數據,代表了什么樣的請求,應該給與什么樣的業務處理以及響應。
  • 開始搭建服務器:
    • 搭建 websocket 服務器,實現網絡通信。
    • 針對各種不同的請求進行不同的業務處理。

客戶端所存在的請求:

  • 客戶端從服務器獲取一個 “注冊” 頁面。
  • 客戶端給服務器發送一個 “注冊” 請求 (提交用戶名和密碼)
  • 客戶端從服務器獲取一個 “登入” 頁面。
  • 客戶端給服務器發送一個 “登入” 請求 (提交用戶名和密碼)
  • 客戶端從服務器獲取一個 “游戲大廳” 頁面。
  • 客戶端給服務器發送一個 “獲取個人信息” 請求 (展示個人信息)
  • 客戶端給服務器發送一個 “切換 WebSocket 通信協議” 的請求 (建立游戲大廳長連接)
  • 客戶端給服務器發送一個 “對戰匹配” 的請求 (匹配玩家)
  • 客戶端給服務器發送一個 “停止對戰匹配” 的請求 (停止匹配玩家)
  • 客戶端從服務器獲取一個 “游戲房間” 頁面。
  • 客戶端給服務器發送一個 “切換 WebSocket 通信協議” 的請求 (建立游戲房間長連接)
  • 客戶端給服務器發送一個 “下棋” 的請求 (下棋)
  • 客戶端給服務器發送一個 “聊天” 的請求 (聊天)
  • 客戶端從服務器獲取一個 “游戲大廳” 頁面 (游戲結束返回游戲大廳)

九. 客戶端開發

注冊頁面:register.html

通過 43.143.27.66:8080/register.html 訪問該網頁時,返回給客戶端一個注冊界面,用戶輸入用戶名密碼后點擊按鈕,自動通過 ajax 向后臺發送用戶注冊請求,并將用戶名和密碼存儲到數據庫中,最后直接跳轉到登入頁面。

在這里插入圖片描述

登入頁面:login.html

通過 43.143.27.66:8080/login.html 訪問該網頁時,返回給客戶端一個登入界面,用戶輸入用戶名密碼后點擊按鈕,自動通過 ajax 向后臺發送用戶登入請求,并直接跳轉到游戲大廳頁面。

在這里插入圖片描述

游戲大廳頁面:game_hall.html

進入游戲大廳 websocket 長連接頁面后,通過點擊開始匹配按鈕,網頁向服務器發送對戰匹配請求,再次點擊按鈕,網頁向服務器發送取消對戰匹配請求,當存在兩個人匹配對戰的話,則玩家匹配成功,直接跳轉到游戲房間頁面。

在這里插入圖片描述

游戲房間頁面:game_room.html

進入游戲房間 websocket 長連接頁面后,就可以開始實時下棋和聊天了。

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97977.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97977.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97977.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

重構導航之核:高德地圖的深度學習架構解析 導論:從數字化世界到可計算世界

導論:從數字化世界到可計算世界 數字地圖的演進,本質上是一場關于“世界可計算性”的持續探索。第一代地圖的核心任務是數字化轉錄(Digital Transcription),它成功地將物理世界的靜態元素——道路、建筑、興趣點&#…

邏輯回歸(sigmoid函數、混淆矩陣、精確率召回率F1)

目錄 一、概述 1、邏輯回歸 2、激活函數 sigmoid函數 3、最大似然估計 二、邏輯回歸 1、原理 2、損失函數 3、代碼 三、混淆矩陣 1、定義 2、舉例 3、代碼 四、分類評估方法 1、精確率(Precision) 2、召回率(Recall) 3、F1&#…

Redis底層實現原理之五大基礎結構

文章目錄1. 基礎結構和編碼類型2. 編碼類型和數據結構實現2.1 字符串(String)2.2 壓縮列表(listpack)2.3 哈希表(hashtable)2.4 快速列表(quicklist)2.5 整數集合(intset…

火山引擎數據智能體DataAgent總結分享

數據的冰山:看得見的資產與看不見的鴻溝 這張圖片用“冰山”類比的方式展示了數據資產管理中的可見與不可見問題,并突出了數據利用的核心挑戰與潛在陷阱。 1. 冰山之上的“看得見的資產” 內容:數據庫、報表、指標等結構化、顯性的數據資源。 核心挑戰: 需要從“采集存儲”…

100種高級數據結構 (速查表)

一、 基礎結構的擴展與組合 (Advanced Linear Structures) 這些結構在數組、鏈表、隊列、棧等基礎結構上增加了特定功能或約束。雙端隊列 (Deque - Double-Ended Queue) 介紹:允許在隊列的前后兩端都進行插入和刪除操作的線性結構。應用場景:工作竊取算法…

一個開源的企業官網簡介

簡介一個完美的企業官網系統,支持手機端和電腦端展示企業風采,還可以展示企業產品/企業新聞資訊等等.普通用戶PC端展示普通用戶手機端展示管理后臺

TCP實現線程池競爭任務

服務端&#xff1a;#include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netinet/ip.h> #include<strings.h> #include<unistd.h> #include<ctype.h> #include<arpa/inet.h&…

Redis C++ 實現筆記(F篇)

Implementing Redis in C : F Redis C 實現筆記&#xff08;F篇&#xff09; 前言 本章代碼及思路均來自Build Your Own Redis with C/C 本文章只闡述我的理解想法&#xff0c;以及需要注意的地方。 本文章為續<<Implementing Redis in C : E>>所以本文章不再…

finally 與 return的執行順序

一、第一次試驗public static void main(String[] args) throws InterruptedException {System.out.println(aaa(null));}private static StringBuilder aaa(Integer i) throws InterruptedException {StringBuilder sb new StringBuilder();try {i.toString();return sb;} ca…

Git安裝教程

簡介 Git 是目前全球最流行的分布式版本控制系統&#xff08;Distributed Version Control System, DVCS&#xff09;&#xff0c;核心作用是追蹤文件修改歷史、支持多人協同開發&#xff0c;并能高效管理代碼&#xff08;或任何文本類文件&#xff09;的版本迭代。它由 Linux…

Linux安裝RTL8821CE無線網卡驅動

1. 查看網卡芯片$ lspci | grep Net 01:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8821CE 802.11ac PCIe Wireless Network Adapter2. 預備配套sudo apt install -y dkms git3. 下載驅動并安裝git clone https://github.com/tomaspinho/rtl8821ce.git cd r…

vue3存儲/獲取本地或會話存儲,封裝存儲工具,結合pina使用存儲

目錄 一、基本用法&#xff08;原生 API&#xff09; 1. 存儲數據 2. 獲取數據 3. 刪除數據 二、Vue3 中封裝成工具函數&#xff08;推薦&#xff09; 三、以上工具函數在 Vue3 組件中使用 1. 在選項式 API 中使用 2. 在組合式 API&#xff08;setup 語法糖&#xff09;…

【Flink】DataStream API:基本轉換算子、聚合算子

目錄基本轉換算子映射&#xff08;map&#xff09;過濾&#xff08;filter&#xff09;扁平映射聚合算子按鍵分區&#xff08;keyBy&#xff09;簡單聚合&#xff08;sum/min/max/minBy/maxBy&#xff09;規約聚合&#xff08;reduce&#xff09;基本轉換算子 有如下POJO類用來…

從淘寶推薦到微信搜索:查找算法如何支撐億級用戶——動畫可視化

本篇技術博文摘要 &#x1f31f; 本文通過動畫可視化深入解析數據結構中的核心查找算法&#xff0c;從基礎概念到高階應用&#xff0c;全面覆蓋順序查找、折半查找、分塊查找、B樹/B樹及散列查找的核心原理與實現細節。文章以動態演示為核心工具&#xff0c;直觀展現算法執行過…

圖像正向扭曲反向扭曲

在圖像處理領域&#xff0c;正向扭曲&#xff08;Forward Warping&#xff09;和反向扭曲&#xff08;Backward Warping&#xff09;是兩種核心的圖像坐標映射與像素重采樣技術&#xff0c;核心區別在于“像素映射的方向”——是從“原始圖像”到“目標圖像”&#xff0c;還是從…

【C語言】 第三課 函數與棧幀機制詳解

1 函數的基本概念 在C語言中&#xff0c;函數是程序的基本執行單元。一個函數的定義包括返回類型、函數名、參數列表和函數體。例如&#xff1a; int add(int x, int y) { // 函數定義int z x y;return z; }在使用函數前&#xff0c;通常需要聲明&#xff08; declaration&am…

多個大體積PDF文件怎么按數量批量拆分成多個單獨文件

在現代社會中&#xff0c;電子文檔在我們的身邊無所不在&#xff0c;而PDF文件時我們日常接觸非常多的文檔類型之一。PDF由于格式穩定、兼容性好&#xff0c;因此經常被用于各行各業。但是&#xff0c;我們平時在制作或搜集PDF文件時&#xff0c;文件太大&#xff0c;傳輸和分享…

ansible-角色

角色 一、利用角色構造ansible playbook 隨著開發更多的playbook&#xff0c;會發現有很多機會重復利用以前編寫的playbook中的代碼。或許&#xff0c;一個用于為某一應用配置MySQL數據庫的play可以改變用途。通過利用不同的主機名、密碼和用戶來為另一個應用配置MySQL數據庫。…

git命令行打patch

在 Git 里打 patch&#xff08;補丁&#xff09;其實就是把某些提交的改動導出來&#xff0c;生成一個 .patch 文件&#xff0c;方便別人用 git apply 或 git am 打進代碼里。&#x1f539; 常用方式1. 基于提交導出 patch導出最近一次提交&#xff1a;git format-patch -1 HEA…

文華財經多空提示指標公式 變色K線多空明確指標 文華wh6贏順多空買賣提示指標

XX:240C;YY:MA(C,1);A1:POW(XX,2)/360-POW(YY,2)/260;A5:EMA2(EMA2(A1,20),5),LINETHICK2;A6:A5*0.9999,COLORSTICK;A20:EMA2(EMA2(A5,20),5),LINETHICK2;A60:EMA2(EMA2(A20,20),5),LINETHICK2;支撐:HHV(A5,30),COLORRED;天數:BARSSINCE(A5HHV(A5,0));YL:REF(A5,1)2.79-天數*0.…