---
# System prepended metadata

title: Gobblet Gobbler

---

# 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値を０で初期化してから、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)
```