GOWOG
:
GOWOG
是一款迷你的,使用 Golang 編寫的多人 Web 遊戲。
試玩遊戲
Demo:http://game.giongto35.com
在 Agent 上的 AI 實驗
由於伺服器,客戶端和訊息是分離的,因此很容易與後端進行通訊。
此專案是用 Python
編寫的 AI agent
,可以學習與環境的互動。
這個實驗是利用 neuroevolution
(神經進化)在迷宮中尋找一條路徑。
油管 Demo:https://www.youtube.com/watch?v=pWbb1m91mhU
本地 Docker 執行
run_local.sh
#!/bin/bash
docker build . --build-arg HOSTNAME=localhost:8080 -t gowog_local|| exit
docker stop gowog
docker rm gowog
docker run --privileged -d --name gowog -p 8080:8080 gowog_local server -prod client/build/
執行,我本地是 Mac
:
./run_local.sh
本地開發
遊戲包含兩部分:伺服器和客戶端。伺服器使用 Golang
,客戶端使用 Node.JS
和 Phaser
遊戲引擎。
伺服器
為少調整過的專案:Kirk-Wang/gowog
我的本地環境是 go 1.14
。
本地啟動:
go run cmd/server/*
伺服器將監聽 8080
。
客戶端
npm install
npm run dev -- --env.HOST_IP=localhost:8080 # HOST_IP -> 伺服器地址
注意
在開發過程中,客戶端在埠 3000
上執行,伺服器端在埠 8080
上執行。
在 production
和 docker
環境中,已構建 Client
,golang 伺服器將在同一埠 8080
上返回客戶端頁面。因此,如果我們執行 docker
環境,則遊戲將在瀏覽器中的 http://localhost:8080 執行。
通訊約定
伺服器和客戶端之間的通訊包基於 protobuf
。 安裝 protoc
以生成 protobuf
。
每次你在 server/message.proto
中有更改(package singature)時。請執行:
cd server
./generate.sh
遊戲前端設計
這個前端專案是基於:
├── client
│ ├── index.html
│ ├── src
│ │ ├── config.js: javascript config
│ │ ├── index.html
│ │ ├── main.js
│ │ ├── sprites
│ │ │ ├── Leaderboard.js: Leaderboard object
│ │ │ ├── Map.js: Map object
│ │ │ ├── Player.js: Player object
│ │ │ └── Shoot.js: Shoot object
│ │ ├── states
│ │ │ ├── Boot.js Boot screen
│ │ │ ├── const.js
│ │ │ ├── Game.js: Game master
│ │ │ ├── message_pb.js: Protobuf Message
│ │ │ ├── Splash.js
│ │ │ └── utils.js
│ │ └── utils.js
每個物件都是從 Sprite
繼承的類。
玩家包含 shootManager
,每次射擊時,shoot manager
都會生成新的 bullet
。
遊戲後端設計方案
Components(元件)
遊戲中主要有 5
個實體。他們的狀態是私有的
實體 | 私有狀態 | |
---|---|---|
Client |
websocket.Conn | client hold 住 websocket 連線 |
Hub |
Client | Hub 處理所有通訊, 包含所有 client 列表 |
ObjManager |
Player, Shoot, ... | ObjManager 包含所有 Player 和 Shoot,處理遊戲邏輯 |
Game Master |
ObjManager, Hub | Master object 由 ObjManager 和 Hub 組成 |
Architecture(架構圖)
不同的實體通過包裝在函式中的 channel
彼此呼叫。
Client 與 Server 互動設計方案
Player connect(玩家連線)
Player Disconnect(玩家斷開連線)
Client input(客戶端輸入)
Profile
Profile
是研究 Golang
效能並找出 slow components
的方法。執行伺服器時,可以使用標誌 --cpuprofile
和--memprofile
來配置 server。
cd server
go run cmd/server/* --cpuprofile --memprofile
程式碼結構
├── server
│ ├── cmd
│ │ └── server
│ │ └── server.go: Entrypoint running server
│ ├── game
│ │ ├── common
│ │ ├── config
│ │ │ └── 1.map: Map represented 0 and 1
│ │ ├── gameconst
│ │ ├── game.go: Game master objects, containing logic and communication
│ │ ├── mappkg
│ │ ├── objmanager
│ │ ├── playerpkg
│ │ ├── shape
│ │ ├── shootpkg
│ │ ├── types.go
│ │ └── ws
│ │ ├── wsclient.go
│ │ └── wshub.go
│ ├── generate.sh: Generate protobuf for server + client + AI environment
│ ├── message.proto
│ └── Message_proto
│ └── message.pb.go
├── Dockerfile
└── run_local.sh
AI 訓練設計方案
此倉庫包含遵循 openAI Gym
格式和訓練指令碼的 CS2D
環境。
訓練指令碼使用 NeuroEvolution(神經進化)
在迷宮中找到到達目的地的最短路徑。
https://www.youtube.com/watch?v=pWbb1m91mhU
執行
按照的說明執行 gowog
環境。即本地 Docker 執行:
./run_local.sh
使用 virtualenv
設定 python3
虛擬環境(直接用 Docker 吧~)。
- 安裝
requirements.txt
所包含的庫。
執行訓練指令碼
python train_ga.py -n save_file_name
save_fie_name
是儲存權重(weights
)的地方。
在下一次,如果我們指定了一個現有的檔案,它將繼續從該檔案的最後一次執行中的權重(weights
)進行訓練。
Genetic Algorithm(遺傳演算法)
_cs2denv_ga.py 的實現_
基於機器學習的目的,CS2D Agent
是在 CS2D
上構建的。
它遵循 openAI gym
,支援 agent
的基本方法,包括:reset()
、step()
、observation_space
和action_space
。
ObservationSpace
是一個一維陣列,它由來自伺服器的 update_player
訊息構造而成
- Player position(
玩家位置
), player size(玩家大小尺寸
), number of columns(列數
), number of rows(行數
), block width(塊寬度
), block height(塊高度
) - 到左,右,上,下到最近 block(
塊
)的距離。此輸入是為了避免碰撞 - 玩家在二進位制塊地圖(binary block map)中的位置。地圖是
0
和1
的2
維陣列(0
為空,1
為塊) - binary block map
獎勵是 1 / distance(目標的距離)
。如果 agent
接近目標 100
點,那麼獎勵就是 1
,情節結束。
NeuroEvolution(神經進化)
_train_ga.py 的實現_
神經網路(Neural Network
)通過使輸入(觀察空間)通過神經網路來獲得最佳動作。
NeuroEvolution
(神經進化)是使用進化演算法不斷改進人工神經網路的AI。對於每次迭代(生成),程式將基於前一次迭代中的最佳設定生成一組新的神經網路權重。 由先前的 NN(神經網路)
生成一個 NN
的過程叫做 Mutate
,它給神經網路中的每個引數新增隨機噪聲。
一個特別的改進是,我們只儲存應用於神經網路的噪聲種子列表,而不是儲存所有的代權值。因為在同一個種子下,所有的隨機化都是相同的,所以一個種子可以代表一個網路的突變運算元。我們不需要保留每一代的所有權值,我們只需要儲存一組從開始到當前一代的種子,然後從這組種子中重新構造權值來得到所有神經網路的權值。
程式碼是基於 Maxim Lapan
的 "Deep Reinforcement Learning Hands-On"
我是為少。
微信:uuhells123。
公眾號:黑客下午茶。
謝謝點贊支援???!