ぷよぷよAIを作りやすくしてみた

## ぷよぷよAIを作ることは中々面倒であるという話

私はとあるぷよぷよ好きなプログラマです。
以前は`コンピュータ将棋`に力を入れて開発していたのですが、最近は`ぷよぷよAI`にハマっています。
こっそり自分で作って、動いているところを見て一人で楽しんでいましたが、やはり他の方が作ったプログラムと対戦させてみたい欲がでてきました。
ただこれが、現状だと難しいのです。
というのも、`ぷよぷよAI`界は、`コンピュータ将棋`界ほどインフラが整備されていないからです。

## 何が足りないのか

### 1. GUIを作らずに済む仕組みがない

まず、ぷよぷよAIを作るうえで面倒なのは、`GUIを作らないといけない`という点でしょうか。
`探索`や`評価`のアルゴリズムだけを追求したい開発者にとって、絵を書いたり、音声を探したり、はたまたそれらを動かしたりするプログラムを書くのは苦痛です。(コンソールだけでも作れなくはないですが……)
将棋には、この問題を解決するための仕組みとして、`USIプロトコル`があります。
`USIプロトコル`とは、`GUIと思考エンジンの通信プロトコル`です。
なんのこっちゃと思うかもしれませんが、根底にある考えは、「`GUI`と`思考部分`をプログラム的に独立させること」です。
すなわち、`GUIプログラム`と`思考プログラム`は別々に作り、相互に通信することで動くようにするということです。その通信方法の取り決めが`USIプロトコル`です。
このような作りにしておくと、`GUI`は「他の誰かが作ったもの」を使用できるため、エンジン開発者一人一人が`GUI`を作る必要がなくなります。
この辺の考えについては以下のページがよくまとまっているので、ご参照ください。
http://shogidokoro.starfree.jp/why.html

ぷよぷよにもこのような仕組みがあれば、面倒なGUI作成から解放されますね。

### 2. ルールが統一化されていない

ぷよぷよは将棋ほどルールが明確ではありません。ゲームの種類(ぷよぷよ通、ぷよぷよテトリス、ぷよぷよeスポーツ等)によって動作に違いがあります。
例えば、落下速度、硬直時間、連鎖時間、お邪魔ぷよ相殺時の振る舞い（クロス、割り込み）等です。
この辺が統一化されていないと、エンジン開発者はどのルールに合わせて作ればいいのかわかりませんね。
この問題の解決方法として、ルールを統一化するのではなく、「複数のルールが存在すること」= 「将棋でいう`持ち時間`の違いのようなもの」と考える、という方法があります。
つまり、思考エンジン同士が通信対戦を開始する前に、通信対戦サーバが「このルールでやるよ！」ということを各思考エンジンに通知し、思考エンジンは、対戦中はそのルールに従って思考すればよいのです。
つまり、通信対戦サーバと、思考エンジンとの通信プロトコル次第で解決する問題であるということです。

### 3. 思考エンジン同士が対戦ができる環境がない

#### インターネット上

将棋には`floodgate`という環境がありまして、ここで24時間365日、思考エンジン同士の戦いが繰り広げられています。
いつでもだれでも参加できるので、思考エンジン開発者の大きなモチベーションになっていると思います。
ぷよぷよにもこういった環境があれば、人口が増えて盛り上がりそうです。

#### リアル

将棋には`世界コンピュータ将棋選手権`と、もう終わってしまいましたが`将棋電王トーナメント`がありました。
ぷよぷよAIのリアル大会はあるとお聞きしたことはありますし、大会の様子を配信されているのも見たことはあるのですが、現在もどこかでどなたが募集されているんでしょうか。。機会があればぜひお誘いください。

## 既存のフレームワークについて

もちろん、上記に書いたことを解決する方法を考えた先人の方がいらっしゃいます。[puyoai](https://github.com/puyoai/puyoai)です。
実質、下記3点すべてを解決するフレームワークです。

- GUIを作らずに済む仕組みがない
- ルールが統一化されていない
- 思考エンジン同士が対戦ができる環境がない

`puyoai`は、実機でぷよぷよAIを動かすことを目的としており、「人間と同じ土俵で戦う」というポリシーが感じられます。
ただ、自作のぷよぷよプログラム上で動くAIを作ることは目的とされていないように見受けられましたので、本フレームワークは使用しませんでした。
※`puyoai`の目的や用途について間違っていたら申し訳ございません。

## それで、結局作ったもの

- UPIプロトコル
- UPIプロトコル準拠のGUI
- UPIプロトコル準拠の思考エンジン

### UPIプロトコル

先ほど述べた、GUIを作らなくて済む仕組みを作るために考案しました。プロトコル本文は下のリンクを参照ください。
https://github.com/TukamotoRyuzo/upi-protocol/blob/master/README.md

`USIプロトコル`をベースとしています。これで完成というわけではなく、あくまで案なので、改善案があれば教えてください。

### UPIプロトコル準拠のGUI

`upi-gui`と名付けました。詳細は下のリンクを参照ください。
https://github.com/TukamotoRyuzo/upi-gui

ダウンロードリンク
https://github.com/TukamotoRyuzo/upi-gui/releases

### UPIプロトコル準拠の思考エンジン

~~ソースは公開していません。~~ 実行バイナリは`upi-gui`とともにダウンロードできます。
10連鎖以上を安定して組める方なら勝てると思います。

(2019/11/27 追記)
思考エンジンをpythonで書きました。通信部や思考ルーチンのサンプルとしてご活用ください。
https://github.com/TukamotoRyuzo/upi-engine


### 使い方(2020/3/13 追記)

#### 1P: 人間、2P: 思考エンジンとして対戦する方法

upi-gui.exeを起動すると、このようなウィンドウが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/36fbb21a-7c21-4ce5-4247-f5448c95dd05.png)

まずは思考エンジンを登録します。
設定(P) → エンジン管理をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/b2c7f023-848d-5f0d-9a73-05a33763f8e7.png)

出てきたウィンドウで追加をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/e621be9b-3a10-f91a-0415-9a3dd9ebd32c.png)

pui_default_ai1.1.exeを選び、`開く`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/51c4c830-2b30-3764-d1cb-4abc208fff9c.png)

するとエンジンが登録されます。エンジン管理画面に、`default1.1`が表示されます。
されない場合は`pui_default_ai1.1.exe`を直接ダブルクリックで起動してやってからもう一度↑の手順をやってみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/863d50d2-941a-957b-adfb-c95bde890d04.png)

エンジン管理画面を閉じると、↓の方のドロップダウンに`default1.1`が出てきています。2Pに`AI`にチェックを入れてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/49db78d6-8772-1803-ea04-f19e06256c25.png)

これでスタートを押すと、1P: 人間、2P: 思考エンジンで対戦できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/09211188-8377-1b22-a38f-0501fe46fc48.png)

#### 1P: 思考エンジン、2P: 思考エンジンとして対戦する方法

1P側の`AI`にもチェックを入れてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/1bba9262-fbcd-322f-ae31-9cb554c121c6.png)

これで対戦すると思考エンジン同士での対戦がはじまります。
ただ、同じ思考エンジンなので同じ手を置き続け、永遠に対戦が終わりません。
ということで、`put_default_engine1.2.exe`を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/8f6ccfeb-c1ec-6b99-f83a-269291085e3c.png)

すると`default1.2`を選べるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265561/245b2041-aef7-f6a1-55cf-b6218a414e17.png)

この状態で対戦を始めると、1pと2pで違う置き方をするので、いい感じに対戦してくれます。

## これから作りたいもの

- 通信対戦機能
  - `ネット対戦サーバ`（floodgate的なもの)を作って、`upi-gui`で接続できるようにしたいです。
- `UPIプロトコル`のブラッシュアップ
  - 正直、対戦相手もいないので、仮決定している今のUPIプロトコルにどんな問題が潜んでいるかかわからない状態です。問題があればぜひご指摘いただいて、どんどんブラッシュアップしていきたいです。

## 最後に

リリースというより、こんなものを作っている、という紹介です。
いろんな方（ぷよらーの方やAI開発者の方）の意見が聞きたいと思い、この記事を書かせていただきました。
（モチベーション維持のためでもあります…）
現時点でエンジンと対戦することはできますので、GUIの動作でおかしいところや、UPIプロトコルのおかしいところをご指摘いただければ幸いです。