# 魷魚遊戲
[toc]
## 環境安裝
### 已有前測環境
```bash
#找到前測環境的資料夾
cd MLGame
git clone https://github.com/ocar1053/swimming_squid_funai25.git
# 進入虛擬環境
# 如果出現了「這個系統上已停用程式碼執行」的錯誤,請在設定->系統->開發人員專用->Powershell
# 將「...允許本機Powershell指令碼...」選項開啟,詳情請看環境介紹影片1:10處
(windows)
.\funai\Scripts\Activate.ps1
(mac)
source funai/bin/activate
cd ./swimming_squid_funai25
#手動玩遊戲指令,遊戲正常啟動代表安裝成功
python -m mlgame -i ./ml/ml_play_manual.py ./ --level 1
```
### Windows 環境建置
```bash
# python 要是 3.10 !!!!!!!
git clone https://github.com/ocar1053/swimming_squid_funai25.git
cd .\swimming_squid_funai25\
# 建立虛擬環境
python -m venv funai
# 進入虛擬環境 (todo cmd version)
# 如果出現了「這個系統上已停用程式碼執行」的錯誤,請在設定->系統->開發人員專用->Powershell
# 將「...允許本機Powershell指令碼...」選項開啟,詳情請看環境介紹影片1:10處 https://www.youtube.com/watch?v=VHBVYl70tp4
# 進入虛擬環境安裝套件
.\funai\Scripts\Activate.ps1
# 安裝需要的套件
pip install -r .\requirements.txt
#手動玩遊戲指令,遊戲正常啟動代表安裝成功
python -m mlgame -i .\ml\ml_play_manual.py ./ --level 1
```
### Mac 環境建置
```bash
# python 要是 3.10 !!!!!!!
git clone https://github.com/ocar1053/swimming_squid_funai25.git
cd ./swimming_squid_funai25
# 建立虛擬環境
python3 -m venv funai
# 進入虛擬環境
source funai/bin/activate
# 安裝需要的套件
pip install -r ./requirements.txt
#手動玩遊戲指令,遊戲正常啟動代表安裝成功
python -m mlgame -i ./mlml_play_manual.py ./ --level 1
```
## 遊戲介紹

* pygame座標
* 原點在左上方
* 關卡
* 1~15關
* 遊戲物件
* 魷魚
* 動作
* UP:向上移動
* DOWN:向下移動
* LEFT:向左移動
* RIGHT:向右移動
* NONE:原地不動
* 食物(有三個等級)
* 垃圾(有三個等級)
* 升級
* 吃食物會讓魷魚升級,跑得更快
* 目標
* 在遊戲停止前,用 AI 模型操控魷魚,得到最多分數
## 遊戲破關介紹
### 破關三階段

### 策略參考

#### 策略說明
以魷魚為中心,對其半徑 R 內的範圍進行搜索,計算 4 個方位的分數,各方位的分數為區域內的食物和海洋垃圾分數的總和。而在每一個幀數,會基於上述的分數決定魷魚該往哪個方向移動。
舉例來說,以上畫面的上區域有大量垃圾,分數總和會是最差,而下區域有大量食物,分數總和會是最高,因此魷魚會選擇往下移動。
#### Hint:
1. 如果發現魷魚很常跑到角落,可以嘗試將總和分數為 0 的區域分數設為 -999 。
2. 若要將物體與魷魚的距離納入考量,可嘗試將食物和垃圾的原始分數乘上權重。
## 程式碼提示
方便學員實作,在 ml 資料夾中,可以找到破關三階段對應的 .py 檔案,同學可以直接對其進行修改來完成階段任務。
### 收集訓練 AI 的資料 (ml_play_collect_data.py)
* function update
```python
def update(self, scene_info: dict, *args, **kwargs):
"""
Generate the command according to the received scene information
"""
```
function update 每一個 frame 會被呼叫一次,可以利用每次傳入的 scene_info,撰寫對應的移動策略 (魷魚的動作)。
- scene_info 的資料格式如下
```json
{
"frame": 15,
"score": 8,
"score_to_pass": 10,
"self_x": 350,
"self_y": 300,
"self_h": 60,
"self_w": 40,
"self_lv": 1,
"self_vel": 10,
"status": "GAME_ALIVE",
"foods": [
{
"h": 30,
"score": 1,
"type": "FOOD_1",
"w": 30,
"x": 40,
"y": 134
},
{
"h": 40,
"score": 2,
"type": "FOOD_2",
"w": 40,
"x": 422,
"y": 192
},
{
"h": 50,
"score": 4,
"type": "FOOD_3",
"w": 50,
"x": 264,
"y": 476
},
{
"h": 30,
"score": -1,
"type": "GARBAGE_1",
"w": 30,
"x": 100,
"y": 496
},
{
"h": 40,
"score": -4,
"type": "GARBAGE_2",
"w": 40,
"x": 633,
"y": 432
},
{
"h": 50,
"score": -10,
"type": "GARBAGE_3",
"w": 50,
"x": 54,
"y": 194
}
]
}
```
* function get_distance
```python
def get_distance(self, x1, y1, x2, y2):
"""
Calculate the distance between two points
"""
return ((x1-x2)**2 + (y1-y2)**2)**0.5
```
此函數可以幫助你計算魷魚和其他物體的距離
魷魚的動作。
* 變數 row
```python
# collect the data
row = [score_vector[0], score_vector[1],
score_vector[2], score_vector[3], command[0]]
```
可以利用變數 row 存儲紀錄訓練資料,score_vector 的索引 0 到 3 對應 [up, down, left, right] 區域的分數,command[0] 則為魷魚的動作。
* function reset
```python
def reset(self):
"""
Reset the status
"""
print("reset ml script")
if self.last_status == "GAME_PASS":
self.all_data.extend(self.data)
with open("dataset/training_data.pkl", "wb") as f:
pickle.dump(self.all_data, f)
print(f"Data appended, total {len(self.all_data)} entries saved.")
self.data.clear()
```
遊戲每結束一回合,reset 會被呼叫,如果此回合通過的話會將訓練資料儲存起來。沒過則不會儲存。
- 資料會存放在 dataset 資料夾中的 training_data.pkl 檔案內
- 若 training_data.pkl 中已存在資料,新通關的資料會接續在原有資料之後。
- 若需清除所有資料,請直接刪除 dataset 資料夾中的 training_data.pkl 檔案。
### 訓練 AI 模型 (knn_train.py)
* 變數 FEATURES_NUM
可以修改此變數,定義特徵長度。
* 變數 DATA_PATH
可以修改此變數,定義資料集的路徑。
### 使用訓練好的 AI 模型破關 (ml_play_knn.py)
* 變數 X
```python
X = [score_vector[0], score_vector[1],
score_vector[2], score_vector[3]]
```
此變數為 4 個方向的分數,會輸入給 KNN 模型。
* 變數 pred_label
```python
pred_label = self.model.predict([X])[0]
```
此變數為 AI 模型預測的結果。
## 遊戲指令運行方式
### 手動操控魷魚
```
# 於/swimming_squid_funai25 下執行
python -m mlgame -i .\ml\ml_play_manual.py ./ --level 1
```
### 收集魷魚移動資料
```
# 於/swimming_squid_funai25 下執行
python -m mlgame -i .\ml\ml_play_collect_data.py ./ --level 1
```
### 訓練 KNN 模型
```
# 於/swimming_squid_funai25 下執行
python .\ml\knn_train.py
```
### 使用 KNN 模型操控魷魚
```
# 於/swimming_squid_funai25 下執行
python -m mlgame -i .\ml\ml_play_knn.py ./ --level 1
```
### 執行自定義模板
```
# 於/swimming_squid_funai25 下執行
python -m mlgame -i .\ml\ml_play_template.py ./ --level 1
```
### 加速遊戲
```
python -m mlgame -f 120 -i .\ml\ml_play_knn.py ./ --level 1
```
* -f 為設定 fps 的參數,數值越大,fps 越高。
## 環境資訊格式
- scene_info 的資料格式如下
```json
{
"frame": 15,
"score": 8,
"score_to_pass": 10,
"self_x": 350,
"self_y": 300,
"self_h": 60,
"self_w": 40,
"self_lv": 1,
"self_vel": 10,
"status": "GAME_ALIVE",
"foods": [
{
"h": 30,
"score": 1,
"type": "FOOD_1",
"w": 30,
"x": 40,
"y": 134
},
{
"h": 40,
"score": 2,
"type": "FOOD_2",
"w": 40,
"x": 422,
"y": 192
},
{
"h": 50,
"score": 4,
"type": "FOOD_3",
"w": 50,
"x": 264,
"y": 476
},
{
"h": 30,
"score": -1,
"type": "GARBAGE_1",
"w": 30,
"x": 100,
"y": 496
},
{
"h": 40,
"score": -4,
"type": "GARBAGE_2",
"w": 40,
"x": 633,
"y": 432
},
{
"h": 50,
"score": -10,
"type": "GARBAGE_3",
"w": 50,
"x": 54,
"y": 194
}
]
}
```
## 競賽說明
* [說明](https://hackmd.io/@IsFp8R6yRX-i3vPPttlq5Q/Hyne7EbBJe)