遊戲設置 - LanKuDot/MLGame GitHub Wiki

本章節介紹遊戲在 MLGame 的擺放位置與如何設置遊戲與參數。

資料夾結構

在 MLGame 中,遊戲皆放在 games 資料夾底下,一個遊戲存放於一個資料夾,該資料夾的名稱就是 MLGame 啟動遊戲的名稱。每個遊戲資料夾內有三個子資料夾:

  • game:存放遊戲程式碼的資料夾。關於如何將一個現有遊戲導入到 MLGame 可以參考 將遊戲導入 MLGame遊戲與 MLPlay 類別
  • log:存放產生的紀錄檔的資料夾。未建立的話,在第一次執行遊戲時,MLGame 會自動產生;
  • ml:存放玩家程式碼的資料夾。可以包含一個 ml_play_template.py 檔案作為玩家的範例程式。

在遊戲資料夾、game、ml 這三個資料夾中,需要有 __init__.py 檔案,使這些資料夾成為 python package。此外,在遊戲資料夾下需要幾個檔案:

  • config.py:告知 MLGame 如何啟動遊戲。格式參考下方的遊戲設定章節;
  • README.md:介紹遊戲的檔案,包含遊戲規則、場景資訊格式、遊戲物件、遊戲指令等。

資料夾結構的樹狀圖如下,假如有一個遊戲 "snake" 要放在 MLGame 中:

games/
└── snake/
    ├── __init__.py
    ├── config.py
    ├── README.md
    ├── game/
    │   ├── __init__.py
    │   └── 遊戲程式碼
    ├── log/
    └── ml/
        ├── __init__.py
        ├── ml_play_template.py
        └── 玩家程式碼

以此為例,啟動遊戲的指令就是 python MLGame.py -i ml_play_template.py snake

遊戲開發者可以將一個遊戲資料夾設成一個專案,如此一來,玩家只要將整個資料夾放入 games 資料夾底下,就可以透過 MLGame 遊玩。

遊戲設定

在遊戲資料夾中的 config.py 檔案負責設定遊戲,每個遊戲都必須提供這個檔案,否則 MLGame 無法執行。以下介紹 config.py 中的參數。

GAME_VERSION

遊戲版本,為一個字串。可不指定,預設為空字串 ""

透過 python MLGame.py --list 列出所有遊戲時,也會一同列出遊戲版本。

GAME_PARAMS

遊戲參數,為一個 dict。可不指定,預設為:

GAME_PARAMS = {
    "()": {
        "prog": 遊戲資料夾名稱,
        "game_usage": "%(prog)s"
    }
}

MLGame 利用 argparse 模組來幫助解析使用者在命令列下的遊戲參數的有效性,而 GAME_PARAMS 就是用來幫助產生 argparse.ArgumentParser 物件的資訊。命令列中所有指定在遊戲名稱後面的參數,都會傳給產生的 argparse.ArgumentParser 解析。以下介紹 GAME_PARAMS 的格式:

建構子

GAME_PARAMS 中的鍵為 "()",其值為一個 dict。dict 中的每個鍵值對應代表要呼叫 argparse.ArgumentParser() 的參數。例如:

GAME_PARAMS = {
    "()": {
        "prog": "snake",
        "description": "A simple snake game",
        "usage": "python MLGame.py [options] %(prog)s"
    }
}

等同於

argparse.ArgumentParser(
    prog = "snake",
    description = "A simple snake game",
    usage = "python MLGame.py [options] %(prog)s")

而在 MLGame 中可以指定 "game_usage"。MLGame 會在 "game_usage" 前面加上 "python MLGame.py [options] " 的前綴,並取代 "usage",所以 "usage""game_usage" 只能擇一存在。例如上面的例子也可以寫成:

GAME_PARAMS = {
    "()": {
        "prog": "snake",
        "description": "A simple snake game",
        "game_usage": "%(prog)s"
    }
}

參數

GAME_PARAMS 中除了 "()" 以外的鍵都是參數,該鍵的值即為參數名稱,其值亦為一個 dict。而 dict 中的每個鍵值對應代表要呼叫 ArgumentParser.add_argument() 的參數。例如:

GAME_PARAMS = {
    "()": {
        "prog": "snake",
        "description": "A simple snake game",
        "game_usage": "%(prog)s <difficulty>"
    },
    "difficulty": {
        "choices": ("EASY", "NORMAL", "HARD"),
        "metavar": "difficulty",
        "help": "Specify the game style. Choices: %(choices)s"
    }
}

等同於

parser = argparse.ArgumentParser(
    prog = "snake",
    description = "A simple snake game",
    usage = "python MLGame.py [options] %(prog)s <difficulty>")
parser.add_argument("difficulty",
    choices = ("EASY", "NORMAL", "HARD"),
    metavar = "difficulty",
    help = "Specify the game style. Choices: %(choices)s")

而在 GAME_PARAMS 所指定的參數順序會等同於傳入給遊戲類別的參數順序。

如果在 config.py 中有指定 GAME_VERSION 的話,MLGame 會在 GAME_PARAMS 中增加 "--version" 的參數,就可以透過 python MLGame.py snake --version 來看遊戲版本:

"--version": {
    "action": "version",
    "version": GAME_VERSION
}

使用 python MLGame.py snake -h 就可以看到由 argparse.ArgumentParser 產生的幫助訊息。

GAME_SETUP

遊戲的啟動設定,為一個 dict。以下介紹鍵值對應:

"game"

指定要執行的遊戲類別。遊戲類別必須含有指定的函式供 MLGame 呼叫。

"dynamic_ml_clients"

遊戲是否為動態玩家數量,為一布林值。可不指定,預設為 False

如果為 True,MLGame 會依照玩家指定的程式碼數量來生成對應數量的機器學習端,但不會超過 "ml_clients" 指定的數量。

"ml_clients"

指定機器學習端的名稱與傳入的參數,為一個 list。list 內的每一個元素都是 dict,內容如下:

  • "name":機器學習端的名稱,為字串。
  • "args":要傳給 MLPlay 類別的位置參數(positional arguments),為 tuple,可不指定。
  • "kwargs":要傳給 MLPlay 類別的關鍵字參數(keyword arguments),為 dict,可不指定。

GAME_SETUP 的範例:

from .game.pingpong import PingPong

GAME_SETUP = {
    "game": PingPong,
    "ml_clients": [
        { "name": "ml_1P", "args": ("1P",) },
        { "name": "ml_2P", "args": ("2P",) }
    ]
}
⚠️ **GitHub.com Fallback** ⚠️