ぷよぷよ AI 人類打倒に向けて

1,967 views

Published on

Game Programming Workshop 2015 で使った ぷよぷよ AI のスライドです。

Published in: Engineering
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,967
On SlideShare
0
From Embeds
0
Number of Embeds
144
Actions
Shares
0
Downloads
4
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

ぷよぷよ AI 人類打倒に向けて

  1. 1. ぷよぷよAI 人類打倒に向けて Shinya Kawanaka (@mayah_puyo)
  2. 2. 国民的パズルゲーム ぷよぷよ 言わずと知れた国民的対戦パズルゲーム 1991年にMSX2およびディスクシステムで 発売、1993年に発売されたSFC版は100万 本以上のヒット 2作目であるアーケード版ぷよぷよ通は 1994年に発売
  3. 3. 現在でもアーケード版ぷよぷよ通を用いた
 大会・対戦会が広く行われている アーケード版ぷよぷよ通A級S級リーグ 2015年で5回目 各地の大学祭での大会 東大、京大、阪大、早大、…… 毎週行われている対戦会 鹿島田マットマウス 立川オスロー 高田馬場ミカド 蕨デイトナ 津田沼エース 名古屋BOX Q3 静岡、京都、北陸、……
  4. 4. 当然のようにクローンやAIが開発される 代表的なものでは poje (独自ルール, 池田研究室) 愛, infinity, niina (GeNEs WoRK, @test_lockit) mayah(AI) (実機, @mayah_puyo, etc.) そのほか、ぷよふらなどのぷよぷよクローン上のAI、数多の独自ぷよぷよクローン とその上で動くAIが作成されている
  5. 5. test_lockit 氏のniinaがすこぶる強かった GeNEs WoRKsというWindows上の独自クライアントで動作 8, 9万点規模 (13~14連鎖) の大連鎖をわりと撃ってくる 催促への対応もできる、潰しもできる
  6. 6. 脱線: ぷよぷよのルールは? 2つ1組で降ってくるぷよを、4つ同じ色をつなげると消える 消えると上にのっているぷよが下に落ち、また同じ色が4つつながると消える これを連鎖といい、N回消えるとN連鎖という 「連鎖の得点」で連鎖の大きさを測るのが普通 70点につき1つおじゃまぷよと呼ばれるぷよを相手のフィールドに送り込める 連鎖数や消えたぷよに応じて2次関数的に得点が増える 3連鎖1000点、5連鎖4840点、10連鎖36840点 フィールドは72マスなので、72 * 70 = 5040 点あれば相手のフィールドが必ず全部埋まる 相手の連鎖中にこちらも連鎖を行えば、降るはずのおじゃまぷよを相殺できる 3連鎖の例
  7. 7. 脱線: ぷよぷよの基本戦略 (1) 相殺があるので、基本的に相手より大きな連鎖(本線)を作れば良い 5連鎖4840点と6連鎖8680点の差は3840点で、ほとんどフィールドが埋まる量 5連鎖以上なら、基本的に相手より1つでも大きな連鎖を作ると勝てる しかし、連鎖が進行している間は自分は何もできない そのため、先に打った連鎖が行われている時間を利用して、相手は大きな連鎖を組む ことができる 後打ち有利の法則と呼ばれている
  8. 8. 脱線: ぷよぷよの基本戦略 (2) 自分が本線を後打ちするために、小連鎖を打って相手に本線を打たせる発火催促が発明される 相手が本線を打たないと負ける程度の量であり、かつ連鎖の終了が速い連鎖として、2連鎖ダブル
 (2連鎖同時消し)が最もよく使われる(だいたいおじゃまぷよ3段ぐらい) 発火催促に対しては、同程度の量の連鎖を使って相殺することがよく行われ、これを対応という 相手の発火催促より少し大きめの対応を持っている場合、相手の発火催促を引き出すための催促もよ く行われる(この目的には1連鎖ダブルが使われることが多い) 大きすぎる対応をした場合は使いすぎと呼ばれ、相手に本線を打たれ自分の本線が相手の量を上回れ ずに負ける 催促と対応によってお互いに大連鎖を作るためのリソースを削り合う作業を中盤戦とよぶ
  9. 9. niinaに人類は一度完敗する niinaがあまりに強かったため、人間とAIのどちら か強いのかを決する勝負が行われることとなった 第1回 人類 vs 最強AI ぷよぷよ通対戦 当時の全国10位付近の猛者達がダブルスコアを付 けられて完敗 niina はパラメータの違いにより 3 タイプが開発さ れていた また、さらに強いkamestry選手も電脳戦と称して niinaと戦い、71 - 100で敗戦 [1] http://sengiken.web.fc2.com/html/AI/vsAI201205.html ぐっくる 21 - 50 GTR型 ようかん 20 - 50 対応型 HIRO 26 - 50 ノーマル型
  10. 10. しかし人類側からずるいという声も聞かれた 人間側が慣れていない操作環境、AIの操作の圧倒的な速さ 操作が速ければぷよをたくさん引くことができ、圧倒的に有利 不慣れな環境では操作も遅くなりがち AIに有利になるような実機との仕様のズレ アーケード版では、NEXT2が見えるのが遅く、NEXT2まで使って連鎖を読むことはできない NEXT2 = 操作している次の次のぷよのこと。現在操作しているぷよが操作可能になってから16 フレーム後に見えるようになるが、16フレームあるとぷよを画面の下の方まで動かせるため、 NEXT2を思考に組み込むと必然的に遅くなる
  11. 11. そこで、実機で動くAIの開発が望まれた 人間側に一切の言い訳を許さない、完全に人間と同じ土俵 これでAIが勝てるようであれば、AIが完全に人間の上をいったと言える AI勢としては、ここを目標にしたい
  12. 12. 実機版AIの開発 有志で実機版のAIの開発に取り掛かる もともとはWindows版ぷよぷよフィーバーを対象に開発をスタート しかし、ぷよ界はアーケード版の格式が高いため、アーケードと同じ環境で動く AIの開発へとシフト アーケード版のエミュレーションであるWiiVirtual Console Arcade を用いて開発、 のちに本物のアーケード基板でも動くように移植
  13. 13. アーケード版AIの構成 中間ハーネスを
 作成して取り付け 映像信号をS端子へとコンバートし、
 市販のビデオキャプチャで取り込み PC で思考 Arduinoにボタンを押させる
  14. 14. ACぷよぷよ通 第一回 人類 vs AI 対抗戦 アーケード版が動いたので、実際に人類代表とAIが戦うイベントを開催 アーケード版ぷよぷよ通 第一回 人類 vs AI 対抗戦 2015年7月4日、ゲームセンター 蕨デイトナIII 対戦は本物のゲーム筐体で行なわれ、人間側に一切の不利益がない形で行なわれた。
  15. 15. ビデオ 1P ソウマ 2P mayah(AI) 大連鎖勝負のもの 小連鎖勝負のもの http://puyoevent.sakura.ne.jp/vsai_1/
  16. 16. 結果は人類側の勝利 人類は、トッププレイヤーより少し下の選手 ソウマ選手、bookmark選手は全国30~50位 程度の選手 もこう選手はおそらく結構下(もこう選手 のレーティングがないのでわかりません) niinaは実機版のため、独自クライアント版と は実装が異なる mayah (H) 29 - 30 ソウマ niina 30 - 24 もこう mayah 19 - 30 bookmark
  17. 17. 敗因の分析 もともとniinaが独自クライアントで人類討伐に成功していたので同じようにやろうとした しかし、NEXT2が見えないことに対するペナルティは思ったより大きかった ぷよを有効に使えない場面が増えるため、最終的に構築可能な連鎖が1, 2連鎖小さくなる 中盤戦でNEXT2まで見ないと対応を見つけられなかったり、相手に対応がないと思って催促を打ったらNEXT2ま で見ると対応があったりする 操作が完璧でないこと、画面認識が100%でないことなどもいくつかの敗戦要因となった ぷよぷよ通の操作は実は結構くせがあり、画面にぷよが詰まっている状態で任意の場所にぷよを持っていくのは結 構難しい AIに有利な要素が大きすぎるために独自クライアントでは適当なAIでも勝ててしまったのでは? との疑念が拭えない
  18. 18. ぷよぷよAIの難しさ
  19. 19. ゲームプログラミング的な難しさ(1) そこそこの盤面の状態数の大きさ 1列13個まで、おじゃま、色ぷよ(4色)の5種類が置け、それが相手も含めて12列分ある さらに操作ぷよ(色ぷよのみ)がNEXT2までの6個が見えるので、相手を含めて 412 (50 + 51 + … + 513 )12 ・ 412 ≒ 10116 この試算はぷよが4つ繋がっていることを考慮してないので実際はもっと少ないはず 参考: チェス 1050 将棋 1071 とされている
  20. 20. ゲームプログラミング的な難しさ(2) リアルタイムゲームであり、うまい探索方法がまだ確立されていない ナイーブにはalpha-beta探索が適用できない 「ぷよを置く」というのを1手にすると、連鎖を行うには何手もぷよを積む必要があるので、相手 に攻撃するまで読むには何手も読まなければならない 「連鎖を行う」のを1手とするにも、ぷよを積んで連鎖を探す必要があり、1手を探索するのにも 時間が掛かる(後述しますが現状はこの方法を採用しています) 配ぷよはランダムであるため、可能性を全て考慮すると計算量が多すぎる 現状、操作を最速でやるには300~500ms以内に思考して次の手を決める必要があり、深い読みを行うに はあまりに時間が不足
  21. 21. ゲームプログラミング的な難しさ(3) 相手には見えない画面外の13, 14段目が存在し、ここはしばしば勝負で用いる 13段目に乗っているぷよの色によっては大連鎖なのか小連鎖なのかわからなくす ることができ、この戦術をファジーと言う 実機版AI特有の難しさとして、画面認識や操作を完璧に行うことが実装的に困難と いう問題もある
  22. 22. ぷよぷよAIの現状 — mayah(AI)の実装
  23. 23. AIを作るのに重要視したところ 速度 思考時間が短いので、可能な限り高速化する 対人間で十分な本線力 邪魔されずに8万点、本当は10万点を目指したい ある程度の中盤戦 中盤戦はAIにとって難しいことがので、中盤戦はするができれば本線力で勝負した い
  24. 24. ビットボードによるフィールド実装の高速化 フィールドは横6列、見えない部分を含めて縦14段 番兵として壁を上下左右に入れれば8列16段となり、ちょうど128個 128bitのxmmレジスタにぴったり入る(1列16bit使って、左下から8列分詰める) 最低限表さなければならないぷよは、空白、おじゃま、色ぷよ(4色)の6つ xmmレジスタ6つ(もしくは空白を除いた5つ)を使っても良いが、連鎖時に浮いているぷ よを「落とす」という操作が必要で、少し重いので減らしたい レジスタ3つあれば3bit分表すことができ、色ぷよを4色に限定するならこれで十分
  25. 25. ぷよの消去判定 全部AVX2(もしくはSSE)を用いたビット演算 上下左右にある同じ色のぷよの個数を次数とすると、次数が3のぷ よが1つ、もしくは次数が2のぷよが連結していればそのぷよは消え る(シードと呼ぶ) 上下左右の連結はビット演算で簡単に求められる シードに隣接する同じ色のぷよは消える 次数2以上のものは全てシードとして列挙されており、次数1のも のはシードに必ず隣接するので、隣接の隣接は考えなくて良い 1 131 1 2 21 22 22
  26. 26. ぷよの落下ルーチン 現状はBMI2命令で実装 どのぷよが消えるかは分かっているので、PDEP, PEXT 命令で消えないぷよだけ下に落とせばよい PDEPとPEXTは64bit命令しかないので、128bitレジ スタに対して2回行う レジスタは3つあるので、最大で6回行う Haswell以前向けにAVX版も用意、こちらは1列ずつ落 としていく方法(遅くはないがBMI2の方が高速) PEXT x: HGEFDCBA mask: 01100100 result: 00000GEC PDEF x: HGFEDCBA mask: 01100100 result: 0CB00A00 1列目 2列目 ABCDEFGH IJKLMNOP rest: 00011101 00010101 mask: 00001111 00000111 pext: 00000000 0DEFHJNP pdep: 0000DEFH 00000JNP
  27. 27. 連鎖シミュレーションのパフォーマンス 19連鎖のシミュレーションにかかるサイクルをRDTSCP命令で測定 得点計算などを少々省いた高速版 Haswellで1200+サイクル (知人のBroadwell上でやってもらうと800+サイクル程度らしい) 得点計算をしっかりやった版 Haswellで1500+サイクル程度 フィールドをナイーブに配列で実装していた頃より3~4倍程度高速
  28. 28. mayah(AI)の特徴 なるべく人に近い積みを選択する ぷよをやっている人に見せると、しばらく人間と勘違いする程度には人間に近い 本線の平均火力は、NEXT2の情報を使わずに2手読み平均80000点程度(13~14連鎖程度) 現在の実験版ではNEXT2なしで14連鎖以上を7割以上というところまでは来ている (ただし計算が追いついていないので、実際に使うにはさらに高速化が必要) NEXT2の情報が使える場合、同じようなパラメータで平均95000点程度までは可能 中盤戦は、連鎖のツリーを作り、催促や潰しを打つ
  29. 29. mayah (AI) の評価関数の構成 現状は特徴の線形和 操作、形、連鎖、発火(凝視) 凝視 = 相手のフィールドを把握する技術で、相手の連鎖数や持っている手、 狙っている手を読み取ること ゲームの進行度に応じて係数を適宜調整 序盤はある程度のスキを許してより大きな連鎖を構築することを狙う、など
  30. 30. 操作に関する評価 「ぷよの置き方」に対する評価 操作にかかったフレーム数 ちぎりの回数
  31. 31. フレーム数 ぷよを置くのに必要なフレーム数が大きいほど減 点する ただし、最終的にはフィールドを埋め尽くすほ どぷよを置いてしまうはずなので、今遅い置き 方でも後で取り返せる 微小な減点のみにとどめてある 基本的にはタイブレークとしてのみ使われる 6列目の方が若干遅いが、
 どうせあとで6列目に
 置かなければならない
  32. 32. ちぎりの回数 これは単純なフレーム数と異なり、単に時間のロス 1回100~200点程度の減点
  33. 33. 形に関する評価 自分のフィールドから得られる特徴に関する評価 U 字型 連結 山谷
  34. 34. U字型 AIは端を使うのが苦手なので、積極的に置 くようにする U字型から外れることに対して減点 理想の高さを平均高さから求め、そこか らの二乗誤差で減点 高さが低いときはU字型を意識しなくて も良いので、高さに応じて減点を調整 この辺が使いづらい
  35. 35. 連結数 連結が多いほど連鎖になりやすく、対応もしやす い ただし、あまりやりすぎると愚形が増えたり暴 発が増えたりする 本当は連鎖の形として評価するべき? 2連結 3連結
  36. 36. 山・谷 山: 左右の列より高い列 谷: 左右の列より低い列 山や谷を作るとそこに置けるぷよが制限される のでできることの幅が狭まってしまう 高さ4以上の山、もしくは深さ4以上の谷に対し て2000点以上の大きな減点 谷(深さ5) 山(高さ4)
  37. 37. 連鎖に関する評価 自分のフィールドから可能な連鎖を列挙 列挙した連鎖に対して評価を行なう 「本線」と「副砲」の両方を別の基準でカウントし、それぞれ良いものを1つずつ選ぶ おそらくもっと良い方法がある(本線や副砲の想定が1つというのはよくないので は?) 評価基準 連鎖数、発火までに必要な個数、定積
  38. 38. 連鎖の列挙 フィールドが与えられたときに、想定さ れる連鎖を列挙する 2つの方法を併用する パターンマッチでの補完による列挙 パターンを使わない場合の列挙 現在のフィールド 想定される連鎖
  39. 39. パターンマッチによる補完 人がよく使いそうな連鎖をパターンとして保持 A→青、B→赤、C→黄 マッチしたら、空白パターンをマッチした もので埋める この状態で、3連鎖が見つかる 数百パターンぐらいの3連鎖のパターンを持っ ている 現在自動獲得を目指しており、将来的に1万 ぐらいにしたいが、パターンが増えると速 度の問題がある A..... ABC... AABCCC BBC... GTR pattern埋める前 埋めた後
  40. 40. パターンマッチによる補完 (contd.) 連鎖が見つかったら、 連鎖を1つ進めて、さら にパターンマッチを行う パターンの重複を減らし つつもマッチする量を 増やす仕組み ...... ..B.C. .AABBB AABCCC 連鎖前 1つ進めて C→緑を補完別のパターン
  41. 41. パターンマッチによる補完 (contd.) 補完したぷよを、最初にフィールド に全部補完して、連鎖が壊れてないこ とを確認 この場合、「青2個、赤1個、緑1個を 補完して4連鎖」という連鎖が列挙で きたことになる
  42. 42. パターンを使わない場合の補完 消せるぷよは、消すためのぷよを補完して消してみ る 右の場合、黄色を2列目に2個、もしくは4列目に1 個、6列目に1個おくと消える どういう連鎖になるのかはわからないが、とにかく 消せるものは補完して消してみる よい連鎖かどうかは後の評価で分かるので、とに かく候補を列挙する
  43. 43. パターンを使わない場合の補完 (contd.) 補完したら、パター ンを使う場合と同様 に1連鎖進める 連鎖が進んで補完が 必要ない場合もある 黄色を補完 補完不要 補完不要 黄色を補完
  44. 44. 連鎖の再帰的な列挙 パターンを使う、使わないに 関わらず、ぷよ補完が起こる のを3回まで許して、再帰的 に、可能な限り補完していく あまり補完しすぎても遅く なる
  45. 45. 連鎖の評価 このようにして得られた連鎖 に対して、本線および副砲と して評価点を計算 最もよいものを本線・副砲の 連鎖の評価点として選ぶ 現在のフィールド 本線 副砲
  46. 46. 連鎖の評価方法 連鎖数 連鎖の形 連鎖までに必要なぷよの数
  47. 47. 連鎖数 本線は単純に連鎖数 * 1000点 副砲は2連鎖に1000点、3連鎖に500 点、それ以上は0点など 7連鎖、7000点 2連鎖、2000点本線としての評価 副砲としての評価 0点 1000点
  48. 48. 連鎖の形 連鎖としても、山や谷、U字型になっ ているかどうかを評価する 形の悪い連鎖を目指しても良くな いので、形の良い連鎖を最終的に 目指すようにおいていく 2列目に高さ1の山、6列目に深さ1の谷 6列目が低いので、U字型としての評価は低い
  49. 49. 連鎖までに必要なぷよの数 連鎖を発火するのに補完したぷよから、何個ぷよを引けば連鎖が発火できるかを計算 補完が赤1個なら、 確率50%で赤を1個引く場合、ランダムに3回引くことが必要 確率80%で赤を1個引くには、ランダムに6回引くことが必要 何回ぷよを引く必要があるかを計算し、二次関数的に減点 この場合の確率はひとまず50%での値を使う この確率は、プログラム開始時に事前に計算している
  50. 50. 凝視と発火に関する評価 いくつかのハードコーディング(ただし、消したい) N個以上おじゃまが自陣に降るなら対応する、など if文並ぶだけであまりおもしろくないので省略します RensaHandTreeと呼ばれる木の作成と評価 自分の想定される連鎖と、相手の想定される連鎖の打ち合いを行なった後、どちらにおじゃま ぷよがどれぐらい降るかを予測する こちらにおじゃまが降りそうならば減点する。こちらから発火時するときは、相手に返されな いことを確認できる
  51. 51. RensaHandTree どういう連鎖が打てるのか、その連鎖を打っ た後にさらにどういう連鎖が打てるのかを 木で表現したもの 全部の連鎖を列挙するには連鎖の数が多 すぎる、木として抽象化し、不要そうな 連鎖を間引いて所持 何フレームで何連鎖が打てて、何フレー ムで終わるかを列挙 ナイーブにはalpha-betaができないので、自 分と相手の可能な手をツリー状に列挙し、 このツリーを元にmin-max探索のようなこと をする 現在 2ダブ 5連鎖 11連鎖 0F,120F 32F,183F 0F, 612F 3連鎖 5連鎖 0F, 180F 0F, 250F 5連鎖 120F, 250F xF, yF
 x: その連鎖を打つために引く最後のぷよを引くのにかかるフレーム数
 y: 発火した時に、操作を開始してから発火終了までに何フレームかかるか
  52. 52. RensaHandTreeの作り方 まずフィールドから考えられる連鎖を 列挙できるだけ列挙 列挙した連鎖を終了フレームでソート 先頭から見て行って、今までで一番連 鎖の得点が大きかったら選ぶ 選ばれた連鎖を発火後にもう一度同じ ことをやって、木の次段を作成する 5連鎖 250フレーム 4000点 2連鎖 150フレーム 1000点 3連鎖 300フレーム 1200点 採用 今までの最大点 1000 採用 4000 不採用 4000
  53. 53. RensaHandTreeの評価 (ケース1) 今、自分はすぐに打てて 120フレームで終了する2ダ ブがある 相手には240フレーム後に打 てる14連鎖しかない(他の連 鎖がない) つまり、2ダブが刺さると 判断できる 現在 2ダブ 11連鎖 0F, 120F 120F, 550F 3連鎖 5連鎖 0F, 150F 0F, 250F 現在 14連鎖 240F, 840F 相手自分
  54. 54. RensaHandTreeの評価 (ケース2) 0Fで打てる2ダブを打つと、 相手は4連鎖で対応できる 対応されてもて260Fまでに 自分は4連鎖を打てる相手は その後、2連鎖しか打てず、 12連鎖には間に合わない 最終的に相手に10個ぐらい のおじゃまが降りそう 現在 2ダブ 11連鎖 0F, 120F 120F, 550F 4連鎖 5連鎖 0F, 150F 0F, 250F 現在 14連鎖 240F, 840F 相手自分 4連鎖 60F, 260F 2連鎖 12連鎖 130F, 200F 250F, 600F
  55. 55. 発火判断 RensaHandTreeの結果に従う 打った後に、RensaHandTreeを評価し、おじゃまが相手のフィールドに何個か降ると判断 されるならば、おそらく打って良いとして加点、こちらのフィールドに降ってくるなら、 返されるとして減点 実際には掘り(おじゃまぷよの下に埋まっている連鎖を掘り起こすこと)や伸ばしなども 考慮して打って良いかどうかを判断 ただし、現状はこの結果がまだ不正確なことがしばしばあり、中盤戦がきっちりできる とは言えない状態になってしまっている
  56. 56. これからの課題 連鎖力はまだ不足 AIも現状8万点程度の火力はあるが、10万点程度までは伸ばしたい 中盤戦 RensaHandTreeの評価が甘いことがあり、多数のテストケースの追加と不具合のあるケースの洗い出し 具体的には自分から仕掛けたり、追い打ちをしないことが多い 評価関数の自動獲得 一度強化学習も試したが、特徴ベクトルが少ないのか、当時は人間を模倣するような積みを実現することはできなかった パターンの自動獲得も含めて自動化して行きたい ただし使える棋譜があまりないのが問題で、ニコニコ動画などにあがっている動画の自動解析などを取り入れるべき?
  57. 57. AI専門家の力にかかれば
 強化学習なども技術的な課題は克服できると考えています。 開発に一緒に参加していただける方を募集しています。 http://github.com/puyoai/puyoai

×