37
mayah(AI) の実装 @mayah_puyo

ぷよぷよ AI: mayah(AI) の実装

  • Upload
    mayahjp

  • View
    8.163

  • Download
    3

Embed Size (px)

Citation preview

mayah(AI)の実装@mayah_puyo

@mayah_puyo最近の普段の仕事

chrome のビルドを速くする仕事

3年ぐらい前はShadowDOMの実装とか

ぷよぷよ AI

ACぷよぷよ通 第一回 人類 vs AI 総監督

現状のフレームワーク大体全部書いた

ぷよ歴は断続的に20年ぐらい

古くは ばよえ~んツアー '97 CSA愛媛大会マスター

Red Bull 5g 2014 ぷよぷよ東日本代表決定戦 3位

← この娘は誰?mayah (擬)

イラスト もりやあこ様

人類 vs AI のときに、最近の流行りにのって擬人化しとくかと思った

ぷよら~エンジニア飲み会でたまたま横に座ったので発注させていただきました

今日のお話mayah (AI) について

mayah (AI) の特徴

mayah (AI) の評価方法

特徴的な評価方法の実装

mayah (AI) の特徴人間らしい積み方でそこそこの強さ

左が mayah (AI)

GTRなど、人間が組みそうな連鎖を好んで組むようになっている

mayah (AI) の評価方法基本は単純な2手読み

NEXT1 と NEXT2 を見て、NEXT1を置く場所を考える

それぞれの置き方に対して評価点を付与し、最も高得点な場所へ置く

1連鎖1000点で線形に増えていくような評価点

5連鎖 = 5000点、10連鎖 = 10000点

評価点の計算なんらかのフィールド上の「特徴」に対して、その特徴が現れた回数だけその特徴に対する得点を付与

序盤、中盤、終盤で評価点が異なる

序盤・中盤・終盤は、フィールド上のぷよの個数で決める程度のラフな決め方

序盤はスキが多少あっても良い(スキが増えるものに対する減点を小さくする)、終盤はいつでも打てるようにする、など

評価点は4つの評価の和

操作に関する評価

形に関する評価

連鎖に関する評価

凝視と発火に関する評価

操作に関する評価

「ぷよの置き方」に対する評価

操作にかかったフレーム数

ちぎりの回数

フレーム数ぷよを置くのに必要なフレーム数が大きいほど減点する

ただし、最終的にはフィールドを埋め尽くすほどぷよを置いてしまうので、今遅い置き方でも後で取り返せる

従って、1フレーム 0.1 点程度の微小な減点のみにとどめてある

基本的にはタイブレークとしてのみ使われる6列目の方が若干遅いが、どうせあとで6列目に置かなければならない

ちぎりの回数

これは単純なフレーム数と異なり、単に時間のロス

1回100点程度の減点

形に関する評価

自分のフィールドから得られる特徴に関する評価

U 字型

連結

山谷

U字型AIは端を使うのが苦手なので、積極的に置くようにする

U字型から外れることに対して減点

理想の高さを平均高さから求め、そこからの二乗誤差で減点

高さが低いときはU字型を意識しなくても良いので、高さに応じて減点を調整 この辺が使いづらい

連結数

連結が多いほど連鎖になりやすく、対応もしやすい

ただし、あまりやりすぎると愚形が増えたり暴発が増えたりする

2連結、3連結に対してそれぞれ10点、30点程度の加点

2連結 3連結

山・谷

山: 左右の列より高い列

谷: 左右の列より低い列

山や谷を作るとそこに置けるぷよが制限されがち

高さ4以上の山、もしくは深さ4以上の谷に対して2000点以上の大きな減点

谷(深さ5) 山(高さ4)

連鎖に関する評価自分のフィールドから可能な連鎖を列挙

列挙した連鎖に対して評価を行なう

「本線」と「副砲」の両方を別の基準でカウントし、それぞれ良いものを1つずつ選ぶ

評価基準

連鎖数

発火までに必要な個数

定積パターンマッチ

連鎖の列挙

フィールドが与えられたときに、想定される連鎖を列挙する

2つの方法を併用する

パターンマッチでの補完による列挙

パターンを使わない場合の列挙現在のフィールド 想定される連鎖

パターンマッチによる補完mayah (AI) は、人がよく使いそうな連鎖をパターンとして保持

A→青、B→赤、C→黄

マッチしたら、空白パターンをマッチしたもので埋める

この状態で、3連鎖が見つかる

mayah (AI) は100パターンぐらいの3連鎖のパターンを持っている

A.....ABC...AABCCCBBC...

GTR pattern埋める前 埋めた後

パターンマッチによる補完 (contd.)

連鎖が見つかったら、連鎖を1つ進めて、さらにパターンマッチを行なう

......

..B.C.

.AABBBAABCCC

連鎖前 1つ進めて C→緑を補完別のパターン

パターンマッチによる補完 (contd.)

補完したぷよを、最初にフィールドに全部補完して、連鎖が壊れてないことを確認

この場合、「青2個、赤1個、緑1個を補完して4連鎖」という連鎖が列挙できたことになる

パターンを使わない場合の補完消せるぷよは、消すためのぷよを補完して消してみる

右の場合、黄色を2列目に2個、もしくは4列目に1個、6列目に1個おくと消える

どういう連鎖になるのかはわからないが、とにかく消せるものは補完して消してみる

よい連鎖かどうかは後の評価で分かるので、とにかく候補を列挙する

パターンを使わない場合の補完 (contd.)

補完したら、パターンを使う場合と同様に1連鎖進める

連鎖が進んで補完が必要ない場合もある

黄色を補完 補完不要 補完不要 黄色を補完

連鎖の再帰的な列挙

パターンを使う、使わないに関わらず、ぷよ補完が起こるのを3回まで許して、再帰的に、可能な限り補完していく

あまり補完しすぎても遅くなるだけ

連鎖の評価

このようにして得られた連鎖に対して、本線および副砲として評価点を計算

最もよいものを本線・副砲の連鎖の評価点として選ぶ

現在のフィールド 本線 副砲

連鎖の評価方法連鎖数

連鎖の形

連鎖までに必要なぷよの数

連鎖数本線は単純に連鎖数 * 1000点

副砲は2連鎖に1000点、3連鎖に500点、それ以上は0点など

7連鎖、7000点 2連鎖、2000点本線としての評価副砲としての評価 0点 1000点

連鎖の形連鎖としても、山や谷、U字型になっているかどうかを評価する

形の悪い連鎖を目指しても良くないので、形の良い連鎖を最終的に目指すようにおいていく

2列目に高さ1の山、6列目に深さ1の谷6列目が低いので、U字型としての評価は低い

連鎖までに必要なぷよの数連鎖を発火するのに補完したぷよから、何個ぷよを引けば連鎖が発火できるかを計算

補完が赤1個なら、

確率50%で赤を1個引く場合、ランダムに3回引くことが必要

確率80%で赤を1個引くには、ランダムに6回引くことが必要

何回ぷよを引く必要があるかを計算し、二次関数的に減点

この場合の確率はひとまず50%での値を使う

この確率は、プログラム開始時に事前に計算している

凝視と発火に関する評価いくつかのハードコーディング(ただし、消したい)

N個以上おじゃまが自陣に降るなら対応する、など

if文並ぶだけであまりおもしろくないので省略します

RensaHandTreeと呼ばれる木の作成と評価

自分の想定される連鎖と、相手の想定される連鎖の打ち合いを行なった後、どちらにおじゃまぷよがどれぐらい降るかを予測する

こちらにおじゃまが降りそうならば減点する。こちらから発火時するときは、相手に返されないことを確認できる

RensaHandTreeどういう連鎖が打てるのか、その連鎖を打った後にさらにどういう連鎖が打てるのかを木で表現したもの

全部の連鎖を列挙するには連鎖の数が多すぎる、木として抽象化し、不要そうな連鎖を間引いて所持

何フレームで何連鎖が打てて、何フレームで終わるかを列挙

自分と相手の両方作る

フレーム数は50%の確率での値を利用している

現在

2ダブ 5連鎖 11連鎖0F,120F 32F,183F 0F, 612F

3連鎖 5連鎖

0F, 180F 0F, 250F

5連鎖

120F, 250F

xF, yFx: その連鎖を打つために引く最後のぷよを引くのにかかるフレーム数y: 発火した時に、操作を開始してから発火終了までに何フレームかかるか

RensaHandTreeの作り方まずフィールドから考えられる連鎖を列挙できるだけ列挙

列挙した連鎖を終了フレームでソート

先頭から見て行って、今までで一番連鎖の得点が大きかったら選ぶ

選ばれた連鎖を発火後にもう一度同じことをやって、木の次段を作成する

5連鎖 250フレーム

4000点

2連鎖 150フレーム

1000点

3連鎖 300フレーム

1200点

採用

今までの最大点

1000

採用 4000

不採用 4000

RensaHandTreeの評価 (ケース1)今、自分はすぐに打てて120フレームで終了する2ダブがある

相手には240フレーム後に打てる14連鎖しかない(他の連鎖がない)

つまり、2ダブが刺さると判断できる

現在

2ダブ 11連鎖

0F, 120F 120F, 550F

3連鎖 5連鎖

0F, 150F 0F, 250F

現在

14連鎖

240F, 840F

相手自分

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

発火判断

RensaHandTreeの結果を使う

打った後に、RensaHandTreeを評価し、おじゃまが相手のフィールドに何個か降ると判断されるならば、おそらく打って良いとして加点、こちらのフィールドに降ってくるなら、返されるとして減点

実際には掘りや伸ばしなども考慮して打って良いかどうかを判断しているが非常に複雑になるのでここでは省略

ちなみに、どれぐらい連鎖組めるの?

2手読み、とこぷよ

中央値が80,000点ぐらい

RensaHandTreeナシ(重いので)、3手読み、パターンによる補完を3回とすると、中央値が95,000点ぐらいになる

まとめ2手読み

操作、形、連鎖、発火凝視の評価点の和で、最も評価点が高いところに置く

特に特徴的なものはパターンマッチとRensaHandTree

Q&A?