# Gobblet Gobbler - [name=Zaidan Yahya] - [time=Sat, Nov 26, 2022 12:56 PM] ## 目次 [TOC] ## 動作確認済み環境 - Python 3.10.8 動作確認済み - Python 3.11.0 動作確認済み ## 必要なモジュール - sortedcontainers - 以下のコマンドでインストールするできる ```shell pip install sortedcontainers ``` ## 環境クラス (GameControllerクラス) 以下の environment というのは 変数名だけなので、GameController()を呼ぶ時の変数を使ってください. ### 報酬の設定 --- - 勝ちの場合、報酬 10 を返す - 負けの場合、報酬 -10 を返す - 与えられた行動が不可能の場合, 報酬 -1 を返す - それ以外、報酬 0 を返す ### メソッドリスト --- 以下は GameControllerクラスのメソッド、それ以外のメソッドもあるが、多分使いませんので、ここには書かないことにします。個別のメソッド説明もありますので、読んでおいてください。 ```python environment = GameController() environment.init() environment.get_state() environment.get_state_is_goal() environment.get_random_action() environment.get_possible_random_action() environment.do_action() ``` ### init() メソッド --- 環境を初期化するためのメソッド - 引数 :special_rule: bool型 (デフォルトはFalse) - 通常ルール(special_rule : False)で初期化すること - 特殊ルール(special_rule : True)で初期化すること - 戻り値:なし - 使用例:以下 ```python # 環境初期化 environment = GameController() # 通常ルールで環境を初期化する # 以下の全てが同じことをやっています environment.init() # special_rule=False と同様 environment.init(False) # special_rule=False と同様 environment.init(special_rule=False) # special_rule=False と同様 # 特殊ルールで環境を初期化する # 以下の全てが同じことをやっています environment.init(True) # special_rule=True と同様 environment.init(special_rule=True) # special_rule=True と同様 ``` ### get_state() メソッド --- 環境の状態を収得するためのメソッド - 引数 :なし - 戻り値:文字列 (これが環境の状態を表す) - 使用例:以下 ```python # 環境初期化 environment = GameController() environment.init() # 使用例 state = environment.get_state() print(state) ``` ### get_state_is_goal() メソッド --- 今の状態が目的(最終状態)であるかどうかを知るためのメソッド。勝ち負け関係なく、ゲームが終わったら、目的状態(最終状態)である。 目的(最終状態)であれば、Trueを返し、そうでなければ、Falseを返す。 - 引数 : なし - 戻り値: True, または False - 使用例:以下 ```python # 環境初期化 environment = GameController() environment.init() # 使用例 if environment.get_state_is_goal(): print("ゲームが終わっている") else: print("ゲームがまだ続いている") ``` ### get_random_action() メソッド --- ルール上で可能かどうか関係なく、ランダムな行動を返す。 - 引数 :なし - 戻り値:tuple[bool, int, int] (これは行動を表すtuple型。tuple型とは何かが分からなかったら、ネットで検索してみてください) - 使用例: ```python # 環境初期化 environment = GameController() environment.init() # 使用例 action = environment.get_random_action() print(action) from_hand, origin_index, target_index = action print(from_hand) print(origin_index) print(target_index) ``` ### get_possible_random_action() --- ルール上で可能なランダム行動を検索し、それを返す。 - 引数 :なし - 戻る値:tuple[bool, int, int] (これは行動を表すtuple型。tuple型とは何かが分からなかったら、ネットで検索してみてください) - 使用例: ```python # 環境初期化 environment = GameController() environment.init() # 使用例 action = environment.get_possible_random_action() print(action) from_hand, origin_index, target_index = action print(from_hand) print(origin_index) print(target_index) ``` **補足説明**: このメソッドはルール上で可能な行動が得られるまでget_random_action()を実行し繰り返すというやり方で検索するので、無限ループになる可能性がある。無限ループを避けるために、500回以内で検索して見つからないとき、500回目のランダムした結果の行動を返す。また、ルール上で可能な行動がなくなったと判断し、ゲームを終わることにして、引き分けにします。 ### do_action() メソッド --- 引数から受け取った値で行動し、報酬を返す. - 引数 :3つある - from_hand: bool型 - 手から駒を取るかどうか、Trueの場合手から駒を取る、Falseの場合ボード上の駒を取る - origin_index: int型 - 元駒の位置を指す    : 手:0~5,  ボード上:0~8 - target_index: int型 - 駒を置く場所の位置を指す: ボード上: 0~8 - 戻り値:報酬 - 使用例:以下 ```python # 環境初期化 environment = GameController() environment.init() # 使用例 1 reward = environment.do_action(False, 8, 8) # 使用例 2 reward = environment.do_action(True, 5, 8) # 使用例 3 action = environment.get_random_action() from_hand, origin_index, target_index = action reward = environment.do_action(from_hand, origin_index, target_index) # 使用例 4 action = environment.get_possible_random_action() from_hand, origin_index, target_index = action reward = environment.do_action(from_hand, origin_index, target_index) ``` **補足説明**: 引数で与えられた行動の from_hand, origin_index, target_indexによってルール上で行動が可能かどうかを判断し、行動可能の場合、行動を実行し、自動的に相手にうつる。引数で与えられた行動が不可能の場合、なにもしない、相手にもうつらない、報酬 -1 を返す。今の相手はルール上で可能なランダム行動を取るだけ。報酬の設定を参照してください。 **報酬の設定** :  - 勝ちの場合、報酬 10 を返す - 負けの場合、報酬 -10 を返す - 与えられた行動が不可能の場合, 報酬 -1 を返す - それ以外、報酬 0 を返す - ここは上で述べた[報酬の設定](#報酬の設定)と全く同じで、参照するためのものだけです。 <br> ## QTable クラス このクラスは強化学習を支援するためのクラスです。 ### メソッドリスト --- 以下は QTableクラスのメソッド。個別のメソッド説明もありますので、読んでおいてください。 ```python q_value = Qvalue() q_value.set_q_value() q_value.get_q_value() q_value.get_action_with_max_q_value() q_value.get_max_q_value() q_value.save() q_value.load() ``` ### set_q_value()メソッド --- 与えられたQ値(q_values)を与えられた状態(state)と行動(action)のQ値に代入するメソッド。与えられた状態(state)がQテーブルにない場合、与えられた状態(state)を新しい状態としてQテーブルに追加し、Q値を0で初期化してから、Q値(q_values)を代入する。 与えられた行動(action)が不適切な場合、例外(ValueError)を発生させる。適切な行動は:GameControllerクラスの[do_action()メソッド](#do_action-メソッド)を参照すること 成功したらTrueを返す - 引数 :3つある - state : str (文字列) - action : tuple[bool, int, int] (これは行動を表すtuple型。tuple型とは何かが分からなかったら、ネットで検索してみてください) - q_value : float (浮動小数点実数) - 戻り値:bool (成功したら True) - 使用例:以下 ```python # 初期化する q_table = QTable() environment = GameController() environment.init() # 状態と行動 state = environment.get_state() action = (True, 0, 0) new_q_values = 10 # 使用例 q_value.set_q_value(state, action, new_q_values) ``` ### get_q_value() --- 与えられた状態 (state) と行動 (action) のQ値を取得するためのメソッド。与えられた状態(state)がQテーブルにない場合、与えられた状態 (state) を新しい状態として、Qテーブルに追加する。 与えられた行動(action)が不適切な場合、例外(ValueError)を発生させる。適切な行動は:GameControllerクラスの[do_action()メソッド](#do_action-メソッド)を参照すること。 - 引数 : - state : str (文字列) - action : tuple[bool, int, int] (これは行動を表すtuple型。tuple型とは何かが分からなかったら、ネットで検索してみてください) - 戻り値: - float (Q値を表す浮動小数点実数) - 使用例:以下 ```python # 初期化する q_table = QTable() environment = GameController() environment.init() # 状態と行動 state = environment.get_state() action = (True, 0, 0) q = q_table.get_q_value(state, action) ``` ### get_action_with_max_q_value() --- 与えられた状態 (state) でQテーブルに最大のQ値を持つ行動 (action) を検索し、その行動を返す。与えられた状態(state)がQテーブルにない場合、与えられた状態 (state) を新しい状態としてQテーブルに追加してから、最大のQ値を持つ行動を返す。 返された行動 (action) は tuple[bool, int, int] という形式で返す。 - 引数 : - state : str (文字列) - 戻り値: - action : tuple[bool, int, int] (これは行動を表すtuple型。tuple型とは何かが分からなかったら、ネットで検索してみてください) - 使用例:以下 ```python # 初期化する q_table = QTable() environment = GameController() environment.init() # 使用例 state = environment.get_state() action = q_table.get_action_with_max_q_value(state) # 行動を実行 from_hand, origin_index, target_index = action reward = environment.do_action(from_hand, origin_index, target_index) ``` ### get_max_q_value() --- 与えられた状態 (state) でQテーブルに最大のQ値を取得する。与えられた状態 (state) がQテーブルにない場合、与えられた状態 (state)を新しい状態としてQテーブルに追加してから、最大のQ値を返す。 - 引数 : - state : str (文字列) - 戻り値: - float (最大のQ値を表す浮動小数点実数) - 使用例:以下 ```python # 初期化する q_table = QTable() environment = GameController() environment.init() # 使用例 next_state = environment.get_state() next_state_max_q = q_table.get_max_q_value(next_state) ``` ## GameView クラス **説明:** ボード, 持ち駒を見やすくするためのクラス。学習するとき、使わなくても可能です。使わないことをお勧めします。 ### メソッドリスト --- 以下は GameView クラスのメソッド。個別のメソッド説明もありますので、読んでおいてください。 ```python view = GameView() view.print_board() view.print_gobblets_in_hand() ``` ### print_board() --- GameControllerのボードをターミナルに表示するメソッド。 - 引数 : - board : (GameControllerのボード) - 戻り値: - なし - 使用例:以下 ```python # 初期化する environment = GameController() view = GameView() environment.init() # 使用例 view.print_board(environment.board) ``` ### print_gobblets_in_hand() --- プレイヤー又は相手の持ち駒をターミナルに表示するメソッド。 - 引数 : - player (GameControllerのプレイヤー又は相手) - 戻り値: - なし - 使用例:以下 ```python # 初期化する environment = GameController() view = GameView() environment.init() # 使用例 1 (プレイヤーの持ち駒) view.print_gobblets_in_hand()(environment.player) # 使用例 2 (相手の持ち駒) view.print_gobblets_in_hand()(environment.enemy) ```