# 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)
```