世界1位のオセロAIをSiv3Dで人生初アプリ化した話

# 世界1位のオセロAIをSiv3Dで人生初アプリ化した話
1年半くらいずっとオセロAI "Egaroucid" を作っています、にゃにゃん(山名琢翔)です。今回は[Siv3D Advent Calendar 2022](https://qiita.com/advent-calendar/2022/siv3d)への投稿として、自作オセロAIをSiv3Dでアプリ化した話を書きます。競技プログラミングほぼ純粋培養かつGUI初心者だった私が、どうやってGUIアプリを作ったのかを書き連ねます。

制作したアプリはこちらで無料公開しています: https://www.egaroucid.nyanyan.dev/ja/

Windows向けダウンロードはこちらから: https://www.egaroucid.nyanyan.dev/ja/download/

こんな感じのアプリです。
![app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/b290e0da-f108-d59a-1e4a-d6442a248b31.png)


# オセロAIを作って世界1位になった話(超ダイジェスト版)
2021年4月、ひょんなことからオセロAI(オセロの強い手を見つけるプログラム)を作り始めました。そして紆余曲折あって、半年ほど経った11月にはコンテストで世界1位になりました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ついに！オセロAI世界一です！！！世界一のオセロAIの作者とお呼びください！！！ <a href="https://t.co/OPLqAj3vgn">pic.twitter.com/OPLqAj3vgn</a></p>&mdash; にゃにゃん@アカウント移行中 (@Nyanyan_Cube) <a href="https://twitter.com/Nyanyan_Cube/status/1462555880172363776?ref_src=twsrc%5Etfw">November 21, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 

今回の記事に関係ないからと言って、あまりにも細かいところを端折ってしまいました。世界1位になるまでの紆余曲折が気になる方はこちらをお読みください。

https://qiita.com/Nyanyan_Cube/items/195bdc47bb1d7c6f8b24


# Siv3Dとの出会い
ということで、せっかく強いオセロAIを作ったのですから、今度はこのオセロAIを多くの人に使ってもらいたくなってきました。ただ、私には1つ重大な問題がありました。GUIアプリの開発経験があまりにも乏しかったのです。唯一経験があったのがPythonでのtkinterでしたが、ライブラリの仕様がいまいち掴みきれていなかったのと、オセロAI自体をC++で作っていたこともあって、別のなにかを探して彷徨っていました。

そんな時、思い出したのです。

「そういえば、以前E869120さんがオセロAIアプリを作って公開してらっしゃったな？」

https://github.com/E869120/Othello_AI_E869120

ということで、このレポジトリを見に行くと、こう書いてありました。

> OpenSiv3D を用いて実装しています。

「ん～、とりあえず使ってみるか！」

これが、Siv3Dとの出会いでした。

# とりあえず作ってみた

Siv3Dは「とりあえず動かす」がとにかく迅速にできる印象でした。デフォルトで使えるボタンなどを使いつつ、オセロAI特有のグラフ描画などは自分で書きつつ、「それっぽい」アプリを作ってみました。

2021年12月下旬には、とりあえずこのような画面が出来上がっていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/c6f4e413-eae1-d33f-9e04-cb1873c93695.png)

ちなみにこの画像では私が自作AIと戦っているのですが、言うまでもなく白がAIです。ボコボコにされていますね…

# 自分のデザインセンスのなさに絶望した

それから約1ヶ月後、2022年1月には、私はこんな見た目のアプリを錬成していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/bc09b4e6-88e1-29e0-44b3-df33836bfdca.png)

ちょっと待ちましょう。あまりにも悲惨なデザインセンスです。色々な便利機能をつけるのは良いのですが、全部1つの画面に詰め込むのはやめましょう。それと、文字が多すぎです。

どんなに良いライブラリを使っても、結局、見た目を作るのは自分です。

# 見かねた友人がデザイン案をくれた

「さすがにこの見た目のままリリースするのはヤバすぎる」

一度立ち止まって、根本的に画面を刷新することにしました。とは言え、私はUI設計の経験など微塵もありません。困りつつも、やるしかないのでデザインを練りつつ、進捗報告としてインスタでボヤきました。すると、友人がDMをくれました。

「デザイン系で手伝えることがあればぜひ、、」

映像作品を色々と作る[金子映像](https://twitter.com/kaneko_eizo)として活動している友人です。ありがたい限りです。

色々と話しつつ、現状のアプリも使ってもらいつつ、友人の多大な貢献によって徐々にデザインが固まってきました。初期のデザイン案がこちらです。

![image832.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/41e49d84-7068-e42c-5133-d319e92a9908.png)

記事の冒頭に貼った実際のアプリの画面でも、盤面は丸みを帯びたデザインになっていますが、そのアイデアはここで生まれました。

# メニューバーを作ってみた

アプリ化にあたって、様々な便利機能を実装しました。対戦機能、ヒント表示機能、入出力機能、などなど…。色々な機能をつければ、当然のようにユーザが設定する項目が増えてしまいます。そして、ボタンの数が増えます。しかし、それでは非常に使いにくいアプリになってしまうのは明白でしたので、友人にデザイン案をお願いすると同時に、私はメニューバーを作ってみました。現在のアプリでも使用している、これです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/9c8fd530-12a4-10be-d067-d251c3143284.png)

こういった「便利アイテム」を自分の好きな形で実装するのはとても楽しい作業でした。Siv3D自体、図形や文字の描画はとても簡単にできるので、あとはそれをどう配置するかというところだけを考えれば済みます。メニューの階層構造などだけを考えれば、あとはそこまで苦労せずに作れました。

# リリース前にユーザテストを行った

1ヶ月ほどして、デザインの刷新もあらかた終わってきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/23698359-e878-d99c-1fce-9be3ef91b6bd.png)


リリースが見えてきたその頃、数人の知り合いに先行してアプリを使っていただきました。アプリのバグを見つけたり、わかりにくいUIを見つけたりするためです。

GUIアプリを作って気づいたことですが、GUIはユーザが行える行動が多すぎて、全てを開発者が予測することはかなり大変です。オセロAIアプリで言えば、AI自体の計算はそこそこ重いものなので、例えば計算が終わる前にユーザが待ちかねて別の行動をしてしまうなどです。こういった行動一つ一つに対して、予期せぬ挙動を起こさぬよう、注意しなくてはなりません。これが結構大変でした。

しかし、このような大変さも、コードの書き方で大幅に緩和できます。ただ、私がそれに気づくのはまだ先の話です。

# リリースした

2022年3月、ついにアプリをリリースしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/9e66b4c8-d9c6-9611-7ec1-45aa10c77ea2.png)

多言語対応を含めて様々な機能をさらに追加し、アプリとしての完成度を高めました。このアプリに開発に協力してくださったたくさんの方々に感謝しつつ、無事にアプリを公開できました。

実は、2021年度からクリエイターとして採択していただいている「クマ財団」の展示会が2022年の4月上旬にあり、その展示に間に合うようリリースしたいという思いがありました。この日程についてもなんとか達成できました。

展示会はこちらです

https://kuma-foundation.org/exhibition2022/

# スパゲッティコードを書き直した
初回リリース以後、バグを潰したり新機能を追加したりと、様々なアップデートをしました。しかし、約半年後、スパゲッティコードの代償を払うことになりました。私はGUIアプリの制作経験も乏しく、「とりあえず動け！」精神で突っ走って作っていたので、その頃にはとても読めたものではないレベルのコードが錬成されていました。

2022年8月頃から、怒涛の勢いでリファクタリング、というかもはや書き直しを始めました。GUI部分だけではなくAI部分も技術的負債が溜まっていたので、もうこの際なのでまるっきり書き換えることにしました。全部合わせて1万行程度あったコードを、全部綺麗に書き直してまた1万行にまとめました。

UIのデザインも大幅に変更を加えたので、引き続き[金子映像](https://twitter.com/kaneko_eizo)として活動する友人に助言をもらいつつ実装しました。そして、ユーザテストも行い、10月には最新バージョンをリリースしました。冒頭のこれです。アプリとしての完成度も上がってきている気がします。

![app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/b290e0da-f108-d59a-1e4a-d6442a248b31.png)

# リファクタリングで学んだこと
Siv3Dにもかなり慣れてきましたし、バグらせにくい書き方も、多分なんとなくわかるようになってきました。見つかった全ての技術的負債を解消し、リファクタリングが完了して、いざ動かしてみると、自然とバグは少なかったのです。

GUIアプリを作る上で大事だと私が学んだのは、とにかく「今、この画面でやるべきことは何なのかを明確にする」ことに尽きます。何をするための画面なのかが明確であれば、実装すべき機能や抑制すべき機能も自然と整理され、バグりにくくなると現状の私は考えています。

# 今後やりたいこと

最後に、今後私がオセロAIに関連してやりたいことを紹介します。

オセロAI自体で言えば、ただひたすらに高速化を進めたいです。高速化すれば、そのぶん時間あたりの強さが増すためです。

そして、Siv3Dに関することで言えば、Siv3D for Webにとても興味があります。現在、私のオセロAIは[Web版](https://www.egaroucid.nyanyan.dev/ja/web/)も公開していますが、こちらはAIをwasm化して、JSから呼び出しています。これを、全部Siv3Dで完結できる可能性があるというのですから、気になります。

# Siv3Dのサンプル集に投稿した(余談)
余談ですが、Siv3Dのサンプル集に簡易的なオセロAIを投稿しました。

https://github.com/Siv3D/Siv3D-Samples/tree/main/Samples/SimpleOthelloAI

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494375/1779cf3c-1f32-fe93-28bd-f35aa0d7859b.png)

コメントも含めて900行ちょっとでこれだけの完成度のアプリが作れます！ぜひ手元で動かしてみてください！そして、Siv3Dでいい感じのものを作ったらぜひ投稿してみてください…！

# 関連記事

もしオセロAI自体に興味を持った方がいらっしゃったら、ぜひこちらもご覧ください。

https://qiita.com/Nyanyan_Cube/items/1839732d7bdf74caff21

https://note.com/nyanyan_cubetech/m/m54104c8d2f12