separo-rsの記事

もう三週間くらい前になると気づいて結構驚愕しているのだが、SEPAROというゲームの対戦相手を書いた。

(この画像なんとかならんかったんか???)

遊べるWebサイトはここ、

toruniina.github.io

レポジトリはここ。

github.com

ゲームのAIというものを作るのは始めてで、「モンテカルロ囲碁」というのがあるらしいくらいの知識からスタートしたのだが、調べてみると割り合い上質な情報がたくさん転がっているようで比較的簡単に対戦可能なAIを書けた。ちなみにAIAI言ってるがディープなやつではなくてより古典的なアルゴリズムです。commit履歴に補強された記憶からは、だいたい以下のようなタイムラインだったようだ。夜って書いてるのは業務終了後という意味。

  • 金曜日の夜: モンテカルロ囲碁の調べものとrustwasmのチュートリアルを読んだ。
  • 土曜日一日: 盤面のレンダリングとゲームのルールの実装
  • 日曜日の夜: 疲れたのでランダムなシミュレーションを見ながらデバッグと表記の調整
  • 月曜日の夜: pure MCとMCTSを実装したもののMCTSにバグがあったことに気づいてたっぽい。
  • 火曜日の夜: MCTSのバグを修正し、人間がプレイできるようにして、公開

だいたいどういうことをしたのかを、せっかくなので日英両方で書いた。英語を用意しようとしたせいで異常に時間がかかってしまった。まあでも、たまに纏まったことをした時はちゃんと残しておきたいので、たまにはそういうのも良いと思う。そう思わないと書いてられるか

toruniina.github.io

英語で記事を書くという行為は、基本英語が公用語になっているGitHubに置いておくという意味では良いかもしれないが(果たして誰か読みに来るのかというのは置いておいて)、英語だとどう書いて良いか思い浮かばない、あるいは長くなりすぎてしまうなどの理由によって一部の細かな内容を抜いてしまいがちになるという欠点がある。ちなみにこの欠点は英語で記事を書くという行為の欠点というよりは、自分の怠惰という問題が可視化されているに過ぎないのだが。例えば、上に書いたタイムラインはこの記事では書いていないし(重要だと思わなかったため)、他のアルゴリズムにしなくてもできそうなことはまだあるのだが、書かなかった(やっていないことを労力を費やして書くのもなあと思ったので)。

ここはほぼ口語なので自分にとって敷居が低いし、書いておくことにしよう。例えば、MCTSではツリーを構築するのだが、このツリーは打てる手の数だけ分岐する。だが打つ手の順番が入れ替わっただけで盤面があとで同じになるような分岐(木が合流してグラフになる瞬間)はあり得るだろう。今の実装ではこの場合、到達した盤面には本質的に違いがないのだが別のノードとして扱われている。これは木であることがアルゴリズムとして重要だったからではなくて、単に一直線に実装するとそうなったからというだけだ。この場合、その合流したノード以下の読みとランダムプレイアウトの結果は区別する必要はなく、集計した方が良い。同じ盤面の状態から全く同じ選択肢を考える必要はないのだ。このことにはしばらく気づいておらず、ボーッと考えながらSEPAROで遊んでいる時に「そう言えばそうだな」という感じで思いついた。これを集計する方法はそこまで難しくなくて、盤面の状態からデータを引くmapを用意すれば良いだけだ。Hashでも計算すれば良い。ノード間の遷移は新しい手を打つことに対応するので、グラフになっても辿れる方向が存在する。そういう意味では有向グラフになるわけだ。なので探索がややこしくなるということもない。まあこの程度のことはわざわざ私が言わなくても専門の人が100年くらい前にやってるだろう。100年前にはMCTSがなかったのでそれはないです。

あと、文章を日英両方で書こうとすると、お互いに引っ張られてちょっと文体や文章の流れが歪んでしまうような気がしている。未熟ゆえだと思うけれど。今は区切りがいいところまでザーッと英語で書いたあと日本語を書いてみて(先に英語を書くのは日本語で書きまくってしまうとあとで英語にするのが大変なことになりそうで怖いからです)、流れを修正して、英語を通しで読み直して文法チェックをし、みたいな流れでやっているのだが、どうにも行ったり来たりしているうちに頭がおかしくなってくる。英語をもっと認知負荷なく読み書きできるようになりたいものですね。