私がぷよぷよAIを作り始めるに至った過程と、現状の報告をしようと思います。
そもそもの私のAI開発の出発点には、一つの体験がありました。
それは、wataさんという方が作成した、ぷよぷよの総当たり探索ツールを見たときのことです。
■wataさんのツールに受けた衝撃
ぷよぷよというゲームを、理詰めで、かつ網羅的に分解しようとするその姿に、感動したことを今でも覚えています。
本来、ぷよぷよというゲームの盤面を検証しようとすれば、
エディターを開き、一手一手人力で操作して、確認する。
そんな手間がかかるものです。
ところがこのツールは、それを一瞬で終わらせてしまうのです。
「もしこのぷよをここに置いたら…」
「この形を伸ばしたらどうなるか…」
そんな人間なら時間をかけて試すはずの無数のパターンを、
総当たりという方法で一網打尽にする。
目の前にあったのは、人間では踏み込めない領域を、機械が軽々と踏み越えるという光景でした。
まさに、知の領域を拡張する道具だったのです。
私はそれを、ただただ凄いと眺める側でした。
■生成AIによって「作れる側」へ
時は流れ、技術の世界に大きな変化が訪れました。
ChatGPTをはじめとした生成AIが世に出てきたのです。
この技術は、私のような者にとって、大きな転機となりました。
わからないことを尋ねれば答えてくれる。
間違っていても訂正してくれる。
必要な関数、足りない変数、処理の考え方、すべてを相談できる。
「もしかしたら、自分でもwataさんのツールを作れるんじゃないか?」
そうして私は、生成AIの助けを借りながら、
Pythonで総当たり探索ツールを作ることに挑戦しました。
この時点では、AIを作ろうなんていう事は考えていませんでした。
ただ単に、後追いで同じものを作ろうとしただけです。
■最初のツール、そして立ちはだかる速度の壁
挑戦の末、なんとか動くものが出来上がりました。
しかし、嬉しくはありませんでした。
処理が遅すぎたのです。
作るために選定したPythonはとても扱いやすい言語ですが、
探索のように膨大な試行回数を必要とする処理には向いていません。
全パターンを確認するには何日もかかってしまう。
これではとても実用には耐えられない。
そう判断した私は、速さを求めて別の言語を探すことにしました。
■Rustとの出会い
私が出会ったのは、Rustという言語でした。
Rustで再実装した私のツールは、
Python時代の平均1000倍の速度を出すようになりました。
特定の条件下では、
1万倍の高速化も実現しました。
これは集計結果を図に表したものの一番最初の盤面です。Y字のあとに続く連鎖は、20000件の形の内、この青の形が最も候補が多いということが分かります。
これがたった1分未満で出力できるのです。
これを出力出来た時の感動は、今でも忘れられません。
自分の手で作ったものが、
目で見える“有用性”を提示してくれる。
このツールは、ようやく
「人前に出しても恥ずかしくない」レベルに育ったのだと、確かな手応えを感じました。
■AIを作る
ちょうどその頃、「amaAI」というAIが登場し、界隈を賑わせていました。
その強さは本物で、人間と互角に渡り合うプレイが話題になっていました。
私は思いました。
「どうせなら、amaAIより良い手が置けるようにしたい」
■評価値ベースのAIと違和感
最初、私は将棋AIのように、
「局面ごとに評価値を与えて、最も良い手を選ぶ」方法を試してみました。
これが驚くほどうまくいきました。流石、先人の知恵といったところでしょうか。
探索+評価値によって、AIは自然と連鎖を組み始めました。
場合によっては11連鎖程度なら簡単に作ることもできました。
けれど、その構築手順は人間とはかけ離れていました。
「連鎖を組む意志」があって置かれた手ではないと感じました。
例えるならこうです。
「階段連鎖を組むぞ」と意図して構築されたものではなく、
「階段っぽい形がたまたま出力された」だけのもの。
私のAIは、連鎖を知っていたわけではなく、ただ、連鎖になりそうなパターンを評価値で引っ張ってきただけでした。
これに私は、強い違和感を覚えました。
この違和感は、
「強さ」よりも「置く手順」を重んじる
私なりのぷよぷよ観から来ていたのだと思います。
つまり、強さや効率よりも先に、形を目指す“意志”を持たせたいと考えたのです。
私が欲しいのは、
「なんかそれっぽい形になった」AIではなく。
「この形を作りたいから、こう置いた」と言えるAIだということに、この時気付きました。
■採用した新たなアプローチ:mayah式検出 × wata式探索
この問題意識を持って情報を探す中で、私は再び先人たちに導かれました。
▷ mayahさんのAI連鎖検出アプローチ
https://mayah.booth.pm/items/1042933
昔買ったこれを読みなおしました。
過去にmayahさんが開発していたAIでは、
既に連鎖の形を目指すための技術が実装されていました。
彼のアプローチでは、
すでに連鎖形として完成しかけている盤面に対して、何をどう置いたら連鎖になるのかを試して、最も連鎖が伸びる置き方をもとに連鎖を検出するという考え方が取られていました。
この考え方は、まさに私が求めていたものに近かったのです。
そこで私は、mayah式の連鎖形評価に加え、
以前自分が高速化に成功していたwataさん式の総当たり探索を組み合わせることにしました。
■「頭伸ばし」と「後ろ伸ばし」という概念
このフェーズで、私は連鎖の構築を
「頭伸ばし」と「後ろ伸ばし」の2つに分けて考えるようになりました。
これらのアプローチは、ぷよぷよをある程度やり込んだプレイヤーなら自然と使っている概念です。
しかしAIにとっては、「どういう伸ばし方があるか」という分類自体が難しい。
探索でこれらを明示的に再現するためには、
理想形に向かう差分の計算と、それに対応するぷよの配置の特定が必要でした。
私は、現在の盤面を理想形と比較し、どのぷよをどこに置けば一歩近づけるかを判定する仕組みを実装しました。
その上で、実際に置ける場所を探索し、最もスムーズに理想に近づく手を選ばせるようにしました。

これによって、AIは単に評価値が高い手ではなく、
「この形を伸ばしたい」という文脈のある手を選ぶようになったのです。
■「定形」を目指すAI
さらに私は、次のステップとして
定形連鎖(決まった連鎖パターン)を構築させる機能を組み込みました。
GTRや鍵積み、土台折りなど──
ぷよぷよには「基本形」と呼ばれる形がいくつも存在します。
これらをAIに教えるためには、
まず定形そのものを表現する方法を定義し、
その形に向かって伸ばすための手順を差分的に認識させる必要があります。
現時点では、この機能はまだ不完全で、
色の選択や組み合わせが理想から大きく外れることもあります。
ですが、人間の知識をAIの文脈に翻訳する第一歩としては、十分に意味のある成果でした。
これはGTRを組ませたものです。これくらいなら作れるようにまで成長しました。
■課題:評価値
皮肉なことに、私がかつて違和感を覚えて切り捨てた「評価値」が、
ここに来て必要な存在として再登場することになりました。
なぜなら、目指す形から逸れたとき、どう置くかは、結局良し悪しの判断基準が必要になるからです。
たとえば:
現在手では定形に寄与する置き方が存在しない
次の手を捨てる必要がある
一時的に形を壊すことが必要になる
そんなとき、どこに置けば致命傷を避けられるかを判断する必要があります。
このとき、評価値のようなスコアリングの概念が、副次的な基準として活きてくるのです。
■やってみてわかったこと
私はAIを作ることで、自分が思った以上にぷよぷよの手順という部分に対する思想が強いことが分かりました。
ただ強いだけじゃなく、手順に意図を含ませたいという思いがこれほど強くなるとは思っていませんでした。
現状、まだ手順に意図を持たせられたとは言えません。なので、これから更に作り込む必要があります。
■アドベントカレンダーに寄せて
本当は完成させて出したかったのですが、出さずに終わるよりはマシかと思い文章を書かせていただきました。
ここまで読んでくださった方、ありがとうございます。
もし少しでも興味を持っていただけたなら、
AIの進化を今後もそっと見守っていただけたら嬉しいです。
そして、是非一度で良いので作ってみてください。面白いので。
今ならあなたも生成AIを使えば気合で作れます。根拠は私です。
どこまで深くぷよぷよの理解に近づけるかを目指して、これからも製作を続けます。