MON.T+α ProgrammingRoom

MON.T+α Programming Room

MON.T+αの活動を綴っています。

【検討】SamurAI Coding 追加検討

 

はじめに

 先日Postmortemとして投稿したSamurAI Codingについてですが、そのゲーム性についてもう少し検討したいと思います。以下文体が敬体ではなくなりますが、今回は私の脳内の再現ということでご理解のほどお願いいたします。

 

SamurAI CodingのPostmortemはこちら

montplusa.hatenablog.com

 昨年度とのゲーム性の違い

 このタイトルはPostmortemでも挙げたが、より具体的にはどう違っていたのだろうか。

 このため、一度具体的なマップを用意してみる。

f:id:montplusa:20210321142633p:plain

※以下Visualizerの画像は公式様Visualizerよりお借りします

上のほうの犬、侍と穴は考えないとして、この4×4のマスを今回考慮する範囲とする。

昨年のルールでの検討

このマップ、昨年のルールでは侍は一切埋蔵金を掘ることができない。自身を犬として操作し、侍がどう動こうと絶対に守れるか実際に動かしてみる。

一手目

f:id:montplusa:20210321142655p:plain

 一手目は対称性からおおよそこのような形になる。侍は休息するという手もあるが、昨年のルールでは休息したところで機動力は変わらないので、より敗着になるだけに思われる。実際取れないのだが、それはかなり自明なので省略する。

二手目


f:id:montplusa:20210321142558p:plain

 今回犬は一個も取らせないことを目標とするので、犬は次に相手が掘りうる埋蔵金の上に移動するほかない。もし侍がその埋蔵金を掘ろうとしていたら、失敗してかつ犬が真横につくので、機動力の問題から今後絶対に取ることができない。犬が埋蔵金を防御することが分かっていたとして相手の侍を行動させるなら、おそらく上の画像のようになるだろう。

三手目以降

 三手目以降も自然な流れで考えることができる。犬は相変わらず次侍が掘りうる埋蔵金の上に乗るのみである。もし侍がその埋蔵金を掘ろうとしていたら、失敗してかつ犬が真横につくので、機動力の問題から今後絶対に取ることができない。侍が犬が防御することを察知して移動していたとしても以降千日手のような手順となる。

今年のルールでの検討

 これに対し今年のルールでは、一手目に斜めで早速一個とることができる。

 さすがにこれだとつまらないので、一手目に斜めを使わなかった場合について考える。その場合、同じ理論で二手目まででこのような状態にできる。

f:id:montplusa:20210321142558p:plain

三手目、四手目

 三手目、侍はRESTすることで優位に立てる。犬は駒の衝突判定の特性上、自分が今いるマスと、自分が次移動した先のマスの二つの二つしか守ることができない。それに対し、上の場面でRESTした侍は、その次のターンで三つの埋蔵金を見据えている(画像では見えないが、マップの設定としては犬がいるマスにも埋蔵金がある)。したがって、侍を完全に防ぐことはできない。犬がこのターンで侍横の埋蔵金に移動すると、その次のターン防げるかは相手がとろうとした埋蔵金と自分が守りに行った埋蔵金が一致するかの確率問題となり、その確率は50%と言って差し支えない。まして、侍が掘りに行くのではなくその埋蔵金の上に乗ろうとしてきたら、防衛陣の崩壊はより大きくなる。

少しマップを一般化した検討

 上記のような特定のマップではなく、少し一般化して考えてみる。なお、ここでも穴については考えない。考えるとおそらくコーナーケースが多量に出てくるため、一般的に話しづらいからである。

 以下の画像は昨年のルールでの主な犬の妨害戦略を示した図である。犬は侍のそばについているとき、四方向中の二方向を防ぐことが可能である。よって下の画像で右上方向に目標地点がある場合、この構図ではいつまでたっても目標に到達することができない。正確には一マス退くことで戦場を移動できるが、犬の斜め動きを延長した直線の反対側には到達できない。

 

f:id:montplusa:20210321153456p:plain

 これに対し、今年度の侍はRESTすることで8方向に進める。下に二枚の画像があるが、一枚目は右上方向に目的地がある場合、二枚目は右方向に目的地がある場合である。

f:id:montplusa:20210321185637p:plain f:id:montplusa:20210321185658p:plain

 マスの色は、オレンジが目的地に2マス近づくマス、濃い黄色が1マス、薄い黄色が変化なしに該当する。一枚目において薄い黄色になるべきマスが塗られていないが、今回の検討には使わないので省略する。

 一枚目、二枚目ともに最善のマスは犬は必ず押さえるべきである。犬はあともう1マス守ることができるのだが、どちらも、色付きのエリアを完全に守ることはできない。二枚目の写真では、薄い黄色のエリアなので目的地には近づいていないが、この次の試行が一枚目のパターンになるので詰められてしまう。よって、穴のないマップでは任意のマスについてその一マス手前までは到着できることが保証されている。

 では、実際にはどれくらいかかるのか。これは相手の犬がどれほど最適な動きをしているかが問題であるので、まずは犬の最適な行動を考える。私の出す結論としては、犬はこのようなにらみ合いでは「どうせ守れないなら二枚目の場面を最も多く経験させる方向に妨害失敗する」というのが平均所要ターン数が伸びる。実際は犬がその三マスのうちのどこにいるかによっても違うが、概算ということで誤差とする。

 「どうせ守れないなら二枚目の場面を最も多く経験させる方向に妨害失敗する」が良いというのは、二枚目は防げなかったとしてもそのターンで目標地点との距離が縮まるわけではないからだ。なお、二枚目は右隣に犬がいるとすると、どちらかにヤマを張って防げなければ、その次のターンに侍は一マス確実に近づけてしまうのだが、犬は侍の右隣にいる際はあえて守りに行かないことで、一枚目の状態に遷移させることができるので、こうすれば一枚目+2ターンと考えられる。

 また、この犬との駆け引きを成立させるには侍は基本斜め移動でなくても毎度RESTしなければならない。RESTしなければ動きの選択肢は昨年度と同じであり、近づくことは許されない。なお、実は決勝で提出したAIでは相手の犬が妨害する犬かどうかを最初に判定したうえで、犬と隣接する際は毎度RESTを置いている。

 これを踏まえて必要ターンを計算してみる。仮の状況としては、侍が10マス右の地点を目指し、すでに右隣に犬がいることとする。二枚目については、一回の行動には2ターンかかるとし、それぞれの場面で相手の犬を回避できる確率を50%とする。一枚目、二枚目ともに場合によっては切り抜けたのちにもう1マス接近できるが、それをなしにすると、最長は

二枚目⇒一枚目⇒二枚目⇒・・・

を繰り返しジグザグに進むことだといえる。二枚目はあえて防御せず右隣に居座るのが総合的に一番長くなるので、2ターンで切り抜けられ、一枚目は平均4ターンで切り抜けられると考えられる。(なお、上の戦術を相手の侍がプレイ中の情報から推定していた場合は一枚目を100%で切り抜けられるので一枚目も2ターンである)これを9回繰り返すので平均ターンは54ターン(戦術を知っていれば36ターン)と求められる。

 妨害なしならば9ターンであったのが犬の妨害で54ターン、およそ6倍となる。100ターンでゲーム終了であることをふまえると、侍の動きは強化されたとはいえ埋蔵金エリアが偏っている場合には犬の妨害は十分に有効である。

決勝で使われたマップでよりうまく動く戦法

 一方、決勝でよく見られた、秘匿埋蔵金が多いマップだとどうなるのかというと、あまり効果を発揮しない。というのも、開始時点で穴のないマスに50%程の確率で秘匿埋蔵金のあるマップの場合、序盤は8箇所に平均4か所程度埋蔵金が存在する。検討の最初で述べた通り、犬は高々2箇所しか守れないので、埋蔵金のありうる地面を掘り起こし続けるだけで得点は十分に得られる。

 では、そのようなマップではどのようなAIが良いのかというと、よく分からない。実際に試したわけではないが、個人的には犬に侍近辺の探索をさせてみるのがよいように思われる(し、実際にそれに全力な犬を見てみたいところがある)。相手の近くで妨害する犬には、その妨害と引き換えに相手に近辺の埋蔵金を見せてしまう欠点が存在する。よって、埋蔵金率が高い場合は、犬は自分の侍近辺のマスを踏んで確認しつつ、自分の侍の妨害に来た敵犬もうまく迂回させるなどして、最大限自分の侍の役に立ってもらう。犬の妨害が有力だっただけに見落としがちだったが、ゲーム名の一部にもなっている「Dig here」というのはそもそもそういう意味ではないか。

今回の提出AIの反省

  私のTeamが提出したAIは上の「決勝で使われたマップでよりうまく動く戦法」について全く考慮していなかった。一度は考えないではなかったが、計算時間的にすべて考慮するのは無理だと諦めていた。これについて、一つに見落としていたのが、今回のAIプログラムはサイズ制限に余裕があるので、たくさんのモードをつけても問題なかったことである。このゲームは秘匿埋蔵金総量や、これまでの行動からどの位の割合で埋蔵金を得られるかを取得することができる。当然だが、最初の20ターンほどで相手の戦術を見ることもできる。最初の20ターンほどで情報を収集し、それに相性の良い戦術のAIを呼び出せばよかったのである。たしかに毎ターンあらゆる場面に対応するには時間が足りないが、この方法では最初の情報集計時間を除いて計算時間はほとんど変わらない。

 特に一番後悔したのは、相手の戦術をあまり見なかったことである。「相手の犬が自分に向かって直進してきているか」「自分の犬が妨害成功したときに次の動きを変えているか」「二つの埋蔵金と敵の犬がそばにいる場合、埋蔵金量の多いほうを狙うのか」など、これらの動きはAI同士の相性が存在する。先ほどの検討で同じ地点に36ターンで行けるのか54ターンで行けるのでは大きく話が違うし、相手の侍の序盤の動きから戦術を推測でき防御率90パーセントならば先ほどの検討の結果は198ターンに膨れ上がる。50パーセントで埋蔵金を掘れることが80パーセント、100パーセントでできるようになるのも大きな差になる。今回のトーナメント戦ではそこまでの柔軟性を持つAIはいないような気がしたので(たまたま実戦にわかりやすく表れてなかっただけかもしれない)、もしそのようなチームがいればマップ選出、対戦相手にかかわらず高順位間違いなしだったことだろう。あえて苦戦するとすれば、どちらが良いとも言い切れない二択に対しては乱数を使用して選択しているようなプログラムだろうか。

 私のTeamの提出した決勝AIは、プログラムを修正する際に過去の自分との試合結果を参考にしている。このため、どうしても相手の行動を過去の自分で仮定したプログラムの戦績がよくなってしまっていた。また、マップもGithubに上がっているマップ候補でしか戦わせていなかった。結果、想定と違うような場面に対応できずにいた。いわゆる特定の条件下での「過学習」を手動で行ってしまったというところだろうか。

おわりに

 おそらくここを見ている人はいないと思いますが、見てくださった方はありがとうございます。今回の反省を通じて遠くから広い視野で見つめることの重要性に気づきました。「プログラムの提出に関する制限」「バリエーションのある実験マップやAI」「ゲームをみづからの手で動かして考え直すこと」など、それぞれ広く今後の開発に生かせることだと思いますので、今回の失敗だけで終わらせずにしっかりと活用していきたいと思います。

それでは。

【Postmortem】SamurAI Coding 2020-21

f:id:montplusa:20210319180010p:plain

SamurAI Coding 自身の一回戦のイメージ画像

※上の画像は公式様Visualizerよりお借りしました

 

はじめに

 今回、2021/3/19に日本情報処理学会様主催で行われました、SamurAI Coding 2020-21にTeam「monk1」として参加いたしました。結果は準々決勝敗退でした。今回はその感想、戦術について書こうと考えております。私はプログラムを始めてまだ間もない者で、あまり深く難しいことには突っ込むことができませんので、主に戦術に関して述べていきます。

 SamurAICoding公式サイトはこちら

 

追記:今回同じTeamでお世話になったstatiolakeさんが参加日記を投稿したそうです!早速一読しましたが、私のブログの内容を前提知識にするとより一層楽しめる物語となっております。

 

ゲーム概要

 

 このゲームは、二人のプレイヤーのうちどちらがより多くの埋蔵金を掘り当てられるかを競うゲームです。 このゲームでは、それぞれのプレイヤーに、

自分の周囲の地面を掘ることができる「侍」という駒

自分の周囲の埋蔵金を知ることができる「犬」という駒

がそれぞれ一つずつ存在します。

 同じマップに対して、Player1とPlayer2のゲーム開始時の駒の位置を入れ替えた試合を続けて行い、その二試合の合計点で一点でも多くの埋蔵金を掘り当てたほうの勝ちとなります。

 より詳細なルールについては、こちらを参照ください。

昨年度とのゲーム性の違い

 この犬と侍を動かして埋蔵金を得るゲームですが、実は昨年度の大会でも似たような趣旨のゲームが行われていたようです。私は参加しておりませんが、昨年の予選、決勝を観戦し、それを踏まえて今年度の違いを考えてみました。

 実は、ルールはほとんど同じです。一点違うのは、侍が直前1ターンに休憩をとることで斜めにアクションをとれるようになったことでした。また、それに付随して、斜め移動同士で交差するような行動の場合は侍が優先的に動けることになりました。昨年度の大会では侍の機動力の低さから犬を妨害に用いることで相手の侍がほとんど掘れないようにすることが可能でしたので、その修正だろうと思われます。

 ルールの変更で侍が強化されたにも関らず、依然として妨害してくる犬を相手に埋蔵金を獲得するのは難しい問題でした。しかし、しっかりと休憩をすることで昨年度のような盤面の隅に追いやられる姿は見られなくなりました。

 逆に、犬にとっての最適な戦術が敵の妨害であるかどうかも疑わしくなりました。昨年度はほぼ確実に封じ込められるからこそ有効であったこの戦術ですが、今年度は、敵が遠くにいる場合、わざわざ向かうよりも自分の侍周辺の埋蔵金捜索を行ったほうが良い場合もあり得ます。

 そういった点で、今年度は昨年度のゲームルールに比べて最適が見つかりにくく、また、相手のAI、マップの相性もあるので、決勝でも上位陣の間ではどちらが強いともいえず、どちらが勝つかわからないような戦いや予選の順位表をひっくり返すような戦いが見られたと思います。

決勝AIで使用した主な戦術

 今回の基本アルゴリズムとしては(準)貪欲法を利用しており、侍は各ターンどのマスを掘りに行くかを決め、その最短ルートにあたる行動をとります。

 また、今回挑戦した言語がPythonで、高速化も十分に行っていないため断念した戦術も多く存在します。それらについてはまた下のほうにまとめておきます。

犬は敵の妨害役

 多くの方々がお気づきだとは思いますが、犬を無策で散歩させ、埋蔵金を見つけ次第踏んで知らせるのは自分にとってほとんどプラスになりません。

 というのも、このゲームは犬が踏んだ場合、同じく埋蔵金の情報が相手に伝わってしまい、見つけ次第踏んだ場合自分と相手のどちらがその埋蔵金に近いかは50:50です(使用されるマップの候補は上がっているので正確にはそうではないですが、戦術的にその犬はどちらにも与しない中立的な動きになってしまいます)。

 上の問題を解決するには、犬の動きはおおよそ

・衝突判定を利用して敵の動きを阻害する

・自分の侍に近いマスを捜索する

・自分の侍にしか分からないような特別な合図をする

に分けられます。これらの動きを場面によって使い分けるという方法もありますが、実装の単純さから今回は一番上のみを採用しました。敵のうちでも、敵の侍に焦点を当てて、敵が移動しそうな方向を潰すように妨害しています。

侍は相手の犬のほうが近い埋蔵金は避ける

 上にあった犬を妨害に使うという戦術ですが、練習会の段階ですでに複数の方が使っていらっしゃいました。そのため必然的に既に存在の知られている埋蔵金は妨害をされて取りに行くのが難しいです。

 その対応策として、自分の侍の行動を決める際、相手の犬のほうが近い埋蔵金はその埋蔵金量を低く見積もりました。

あり得るマスに埋蔵金を仮定する

 このゲームでは、毎ターンまだ掘られていない埋蔵金の量を取得することができます。そこで、埋蔵金があるかわからないマスにその埋蔵金を分配しておくことにしました。すでに存在が知られている埋蔵金を犬が死守するであろう上位陣の方々を考えると、上位陣との対戦でより効果のある戦術だろうと思われます。

ここで、埋蔵金があるかわからないマスというのは以下の条件すべてを満たすもののことを言います。

  • 駒の初期位置になっていない
  • 一度も犬が上を通っていない
  • 一度も穴ができていない
  • そのマス埋蔵金があることが知られていない

この戦術によって、博打要素はありますが、平均で一試合に得られる埋蔵金の量が多少増加します。

掘った次を考える

 基本的に貪欲法ではありますが、例外があります。それは、掘ろうとしているマスの目の前まで来た時です。そのまま貪欲に掘ってしまうと、その次に掘りたい場所へ移動するために掘った場所を埋めなおして移動しなければならない可能性が出てきます。

 今回提出したAIでは、自身の侍が1ターンで行ける場所とそうでない場所の2グループでそれぞれ最大評価の埋蔵金を探し、上に述べたような事象が発生する場合は先に上を通過してから掘るようにしています。なお、敵の犬がある程度近いときは悠長なことはしていられないので貪欲に掘ります。

その他

そのほかの戦術としては

  • 埋蔵金埋蔵金量を掘るまでにかかるターンで割ってそれを評価とする
  • スタック防止のため直近に行ったいくつかの行動は再びとらない
  • 採掘を妨害された場合、そのマスは犬のほうが近いうちは狙わない

などになります。

 

実装を断念した戦術

 AIの実装に完成はないとはよく言われますが、今回の実装は様々な改善点の残るものとなってしまいました。中にはそもそも処理速度的にどの言語でも間に合わないだろうものもあれば、ただただ手間を惜しんだだけのものもあります。

埋蔵金への最短ルート複数取得

 今回のゲームはボードが格子状で、移動は前後左右や斜めに一マスだったために、同率でたくさんの最短ルートが出てきます。このうち、敵の犬をできるだけ避ける最短ルートを取得できると、確実に強化されると思いました。

敵の侍に近づけない犬を補助

 大会で使用されるマップの候補の中には、マップの状態が恣意的に用意されているものが多く、中には犬が穴で閉じ込められているものがありました。そういったマップ以外でも、ゲームの過程で自分の犬と相手の侍の間に穴で隔たりが生じている場合がしばしばみられました。

 これらの場合において、穴を埋めて犬を自由に動けるようにするのが有効かどうかはケースバイケースであり、特にこの先のターンが少ない場合や出だしの積極さで勝敗が決まりそうな場合は、この戦術はマイナスに働きます。その判定は非常に難しく、生半可な判定は弱体化につながるため断念しました。

シミュレーションによって全行動を試し盤面を評価する

 少々戦術というよりはアルゴリズムの話になるので私からは控えますが、これについては、高速化処理を十分に行っていないため断念いたしました。駒から各埋蔵金への距離を求めるのに想像以上に時間がかかり、一手全探索も叶いませんでした。

狙って埋蔵金が取れるかの判定

 埋蔵金は、その立地によっては犬が妨害してきても強引にとることができます。基本的に埋蔵金が単体で存在しているとき(マップ内に一個しかないときを想像すると分かりやすいです)、その埋蔵金は犬が上に乗り続けた場合にいつまでたっても掘ることはできません。その埋蔵金の隣接するところにもう一つ埋蔵金が存在した場合でも、同様に犬が二つを行き来しているといつまでたっても掘ることはできません。

 ただし、かたまって三つ存在する場合、あるいは一つとびで埋蔵金が存在する場合は妨害を受けつつも一つとることができます。そのため、この判定方法でとれると判定したものは相手の犬が近くても押し通すのも有効だと考えました。

 しかし、この戦術は各埋蔵金ごとにその周辺のマス状態を確認して判定する必要があるため、断念しました。また、この判定を用いた戦術は100ターンでは掘り切れないほどのマスがあるこのゲームでは弱体化になりうるとも考えました。実際、当日のマップではこれまでにないほど多量の秘匿埋蔵金が用意されているマップもあり、実装しないで正解だったようです。

大会登録開始から今までの流れ

 この大会を知って参加登録をしたのは2020年の12月だったと思うのですが、一番最初に感じたのは、最低限のプログラム提出までが難しそうということでした。Windowsで開発するにはWSLが必須でしたし、このゲームのルールも少しややこしいと感じました。このゲームは前大会に修正を加えたもののようで、前大会から出場している方はすんなりと入ったかと思います。

 ゲームのルールで一番の難関は犬と侍の衝突判定でした。動線が交差した際の優先度などが与えられてはいましたが、練習会開催時期はまだゲームマネージャー、ビジュアライザーともに誤判定があり、満足な開発ができずにいました。

 誤判定の中で開発していたこともあり、monk1は練習会の段階では一位を取っていましたが、中にはマップ運で勝っていた試合も存在しました。

 実は、練習会の段階でAIがそれなりの思考時間を使用していたために、以降大きな追加はできなくなっていました。予選ではmonk1と同じく妨害型の犬が多数見られ、かなりの接戦で二位となりました。この時の所感ですが、このように本番でいきなり大きな進化を遂げるチームが出てくるのも面白いですが、一日ごとなど短い間隔で提出ファイルで対戦を行い、その結果が逐次公開されるのも面白いのではないかと思いました。

 予選のAIはほぼ完成だったのですが、犬に違和感があったので締め切り間際に大きく改善し完成版となりました。

 決勝については、一回戦でこちらの環境では起きなかったタイムアウトが発生し焦りつつも勝利しました。二回戦については僅差で負けてしまいましたが、聴講者の方々が楽しめるような熱い戦いを提供できていたならば幸いです。

おわりに

 ここまで読んでくださってありがとうございます。

 今回出場した大会ですが、私の中で初の大会だったのですが協働開発してくださった方の支援もあり、個人的には満足しております。

 あわせて、練習会、予選、決勝で対戦してくださった方々、この情勢の中オンラインでの大会の運営を行ってくださった方々に心から感謝いたします。

 来年以降については開催はしない予定とのことですが、また似たような機会があればぜひ参加したいと思いました。何かご存じの方がいらっしゃったらご連絡ください笑

 それではまた。

 

ぜひstatiolakeさんのこちらも。ここまで読んでいただいた方ならきっと面白いです。