# QuoridorAI 仕様
Repository:
[](https://github.com/grkon03/Quoridor-AI)
## 必要なクラス(型)
- SquareEdge // be used for expressing wall
- Square
- Fence // one fence(wall)
- SEFile // SquareEdge File
- SERank // SquareEdge Rank
- Bitboard96
- WallBBOD // Wall One Direction
- Move // planning to express by SquareEdge
- Color
- WallDir
- Board
- CommandLine
- Zobrist Hashing 関連(何bitにする?)
- Thread 関連... (未定)
あとで改善する可能性のあるものは、抽象にした方がいいのかもしれない...
### SquareEdge
| | A | B | C | D | E | F | G | H | I | J |
| -----| :-----: |:----:| :-----: |:-----:| :---: |:----:| :---:| :----:|:----:| :----:|
| R9 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 |
| R8 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
| R7 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 |
| R6 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |
| R5 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
| R4 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 |
| R3 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
| R2 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| R1 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| R0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
### Move
Square と Fence からなる(Castによって得られる)
- enum で定義
- MakeMove 関数で SquareEdge 2つから作成できるものとする.
- -1 を invalid とする.
- 最初8bitは値が小さい方の SquareEdge 次の8bitは値が大きい方のSquareEdge
```C++
enum Move : int {
MoveInvalid = -1,
NumberOfMove = 209
}
```
### Square
- MakeSquare
- 大きいSquareEdge - 小さいSquareEdge = 11 となる対角線をとる.
- 一応 = 9 となるような場合も MakeSquare できるものとする(自然と = 11 となるようになる)
```C++
enum Square : int {
SquareInvalid = -1,
NumberOfSquare = 81,
}
```
### Fence
- MakeFence
```C++
enum Fence : int {
FenceInvalid = -1,
NumberOfFence = 128
}
```
### Color
プレイヤーの色
```C++
enum Color : int {
White = 0,
Black,
ColorLimit,
};
```
### WallDir
Wall の縦横
```C++
enum WallDir : int {
Vertical = 0,
Horizontal,
WallDirLimit,
}
```
### WallBBOD
#### 継承
```c++
class WallBBOD : public Bitboard96
```
#### 必要な変数
- `WallDir` **wallDir**
#### メモ
Rank が若い順, Rank が同じなら File が若い順
### Board
#### 変数
- `Square` **kingSq[ColorLimit]**: Player の King の位置のマス
- `Bitboard96` **kingSqBB[ColorLimit]**: Player の King の位置の Bitboard
- `Color` **turnPlayer**: 現在のターン
- `WallBBOD` **fixedWall[WallDirLimit]**: WallDir の設置された壁の Bitboard
KingBBはいるのか...?
### CommandLine
#### 変数
- `Board` **realtimeBoard**: 現在のボード
## 必要な演算
### メイン層
- [ ] m1: Board.動けるマスのBitboard96変数を返す
- [ ] m2: Board.マスを受け取り、そこに動けるかを判定boolean
- [ ] m4: Board.勝ち負け引き分けを判断する // これは簡単ね
- [ ] m6: Board.Moveを受け取って合法か判定boolean
- [ ] m7: Board.Moveを受け取って手を指す
- [ ] m8: WallBBOD.Moveを受け取って置けるか判定(この置けるというのは, 他の壁が邪魔をしないという意味)
- [ ] m9: WallBBOD.置ける壁のMoveのvectorを返す(この置けるというのは, 他の壁が邪魔をしないという意味)
- [ ] m10: Board.合法Moveを返す
### サブ層
- [ ] s1: Board.Moveを受け取って、それにより閉じ込められるか判定
- [ ] s2: Board.マスを受け取り、通る壁のBitboard96を2つ返す
- [ ] s3: Board.壁の位置を受け取り、そこに置けるか判定boolean // これむずそう...
### 各演算のクラスごとの分配
#### Board
m1-m7, m10, s1-s3
#### WallBBOD
m8-m9
## Indexer
```C++
class Indexer {
public:
static const Indexer indexer; // 標準の indexer
// static functions
static int SquareToIndex(Square);
static int FenceToIndex(Fence);
static int MoveToIndex(Move);
public: // note: public
// variables
Square IndexedSquare[81];
Fence IndexedFence[128];
Move IndexedMove[209];
};
```
Square, Fence, Move に対して固有の Index を対応させる
### Indexing Rules
#### Square
合計81種
SquareEdge の小さい順に並べる。
A3
### Fence
合計128種
縦, 横で分ける:
- 縦:0 - 63
- 横:64 - 127
SquareEdge の小さい順に並べる。
### Move
Square: Square のインデックスのまま
Fence: Fence + 81
## Thread の分配
## Zobrist Hashing
キング81マス $\times$ プレイヤー2人 = 162
壁1方向64マス $\times$ 2方向 = 128
合計290種
### HashKey
```C++
using HashKey = uint64_t;
```
## Shorthand Notation
- King Move
- Rule: expressed in "K" + (bottom-left square edge)
- e2f3 $\rightarrow$ Ke2
- a7b8 $\rightarrow$ Ka7
- Fence Move
- Rule: expressed in (wall direction) + (bottom-left square edge)
- d7f7 $\rightarrow$ Hd7
- b2b4 $\rightarrow$ Vb2
## メモ
- 道を塞いだかどうかは dijkstra で判定
- 道を塞ぐ壁は Board に保存, リアルタイム更新