ロシアAIカップ2017での私の戦略

みなさんこんにちは。



占星術師は1週間発表しており、 ロシアAIカップ2017コンペティションについて、または私が書いたボットについてです。 私はこの競技会に6年連続で参加しています-戦車から始めても。 MLブートキャンプとHighLoad Cupへの参加から私を知っている人もいるかもしれません。



場所は最初にではなく(再び)撮影されましたが、何か書いておくべきことがあります まず第一に、この記事は、今年の参加者、またはそのような次のコンテストのアイデアを取り上げたい人、あるいは単にロシアのAIカップ競技のトピックに精通している人にとって興味深いかもしれません。







ゲームのルールを繰り返しません。 それらに精通している人々-精通している人々、および精通していない人々-は、いくつかのリーダーゲームを見ることができます。 私のプロフィールへのリンク。



今年のテーマは当初はあまり好きではありませんでしたが、私は参加することを事前に決めていました。 最初のバージョンが送信されるとすぐに、関心が急激に高まり、少なくともいくつかのアイデアが現れ始めました。 したがって、来年参加するかどうか疑問に思う人は、最もcな戦略を送信することをお勧めします。 意見は大きく変わる可能性があります。



管理の複雑さは、多くの参加者、さらには新参者を怖がらせました。 参加者の数は記録的に少ない。 そして、最初の3週間のトップにいるほとんどの人は、明らかに見込みのない戦術を持っています。 しかし、これらはすべて私にとって手元にあるだけです。



コンテストには多くの努力が費やされています。 自由時間を100%広げます。 しかし、これでは十分ではありません。



叙情的な余談は完了しました。私の戦略を説明します。



ビジュアライザー



ローカルランナーのフルタイムのテクニカルビジュアライザーでは十分ではありません。 デバッグ情報を描画するには、独自に記述するか、誰かのベストプラクティスを使用する必要があります。 初日、私は昨年Windows Formsの気取らないビジュアライザーを新しいルールに適応させ始めました。



最低限必要な機能があります。通常のビジュアライザーが実行できるすべての機能に加えて、ハイライト、ベクターの周りの移動、建物のキャプチャなどの小さなアニメーションがアニメーション化されます。



外観の短いビデオ:





最初のバージョン



上記で書いたように、APIを感じ、アイデアが出始めるには、少なくともいくつかの戦略を書く必要があります。 先に進み、不器用な「トルネード」は、敵ユニットを優しく「トリム」する後続バージョンをすべてテストするための優れた戦略です。



基本的な戦略を書く時が来ました。



過去のロシアAIカップの経験によると、成功する戦略の必要な要素は、動きの列挙+ゲーム世界の正確なシミュレーションでした。 何よりも私を混乱させたのは、戦略開発の明確な計画が、以前のように見えないことでした。 賭けは優れたマイクロコントロールに基づいて行われ、対戦相手が何をしているのかを見て、戦術を後で考え直すことができます。 そこにすべてが落ち着きますが、あまり変わらないカーネルを作成する必要があり、新しい機能を増やすことができる場所になります。



コードアーキテクチャは非常に単純です。 タイプMyVehicleのオブジェクト-Model.Vehicleクラスのラッパー、およびサンドボックスオブジェクト(サンドボックス)があります。 実際、後者は神のオブジェクトです。 彼に任意のコマンドを与えることができます-Model.Moveと同じであり、事前に数ティックの世界をシミュレートします。



意思決定は、グローバル評価機能に基づいています。 世界の状態を評価して実数を返す1つの関数(ハザード関数)があります。 1回の移動で、この数ができるだけ小さくなるように世界の状態を変更するよう努めています。



以前のCodeWizardsコンテストでも同じアイデアを使用しました。 なぜなら ウィザードが1つ(つまり、2次元空間)しかない場合、関数の値をグラデーションスケールとして描画することができました(昨年のビデオへのリンク )。 ここでは、1つの共通機能を備えた500ユニット(多次元空間)を視覚化せずに実行する必要がありました。



後で、この関数の計算方法についてさらに詳しく説明します。



次に、さまざまな動きを整理する必要があります。 最後のオプションは、ユニットごとに次の動きを整理することです。





このリストは、さまざまなアクティビティ全体をカバーするのに十分でした。



ハザード関数の計算。



これは、次の値の合計で構成されます(長くて面倒な係数が選択されています):





上記のすべてのポイントは、ユニットに属しているかどうかに関係なく、ユニットごとに個別に考慮されます。





これらはすべて混戦要因です。 さらに最も難しい。 軍隊を敵に向かって移動させる方法は? 最も近い、または最も太い? 軍隊を敵から逃げさせ、ヘリコプターをAPCの後ろに隠す方法は? 軍隊を動かして建物を占領する方法は? フライを癒す方法は?



ここでは、グループ化に関する情報が必要になります。 敵ユニットのクラスター化と同様(5〜7グループの借方が500よりも便利であるという事実のみ)。





一般的に、これにはすべて太字のプラスと太字のマイナスがあります。 松葉杖がなければ、新しいアイテムを追加できます:核、建物、治療。 係数は絶えず調整する必要があります。ある状況では修復しますが、他の状況では破壊します。

シミュレーション



高いシミュレータパフォーマンスを実現するには、衝突の円をすばやく確認し、戦闘の近くにいる隣人を見つけることができるデータ構造が必要です。



コンテスト開始の少し前に、コンテスト開発者のgithubリポジトリでアクティビティを観察しました。 QuadTree.javaファイルがcodeforces-commons リポジトリに追加されましたが、 それでも最初の推測では、多数のユニットで競争が行われると思われました。 シミュレータの実装を始めて初めて、この構造を思い出し、使い始めました。 結局のところ、ローカルランナーでも使用されます。 上記の実装では、ポイントの削除、ポイントの座標の変更(削除と再追加は非効率的)、ツリーのクローン作成のための十分な方法がありませんでした。 自分で追加する必要がありました。



ユニットの衝突をチェックすることは、私のコードの中で最も費用のかかる操作であり、時間制限にはほとんど適合しません。



チームマネージャー



チームマネージャー? 分隊の優先キュー? 保留中のコマンドとキャンセルされたコマンド これはすべてではありません。 上記のように、すべての決定は、現在の状況に基づいてのみ行われ、各ユニットの最後の順序を知っています。 TickIndexの原則に従って、利用可能なアクションは60ティックに均等に分散されます%10 ==0。各ティックから計算するにはコストがかかりすぎます。



ラウンド1



Arrvのようなユニットを何らかの方法で適応させるのに数晩かかりました。 チェッカーボードパターンでTankとIfvとそれらをミックスすることにしました。 構造は最適ではありませんが、これまでのところは最適です。



GIF




最初のラウンドの開始までに、私は一貫して多くのリーダーを倒しました。 「サンドイッチ」タイプのライバルの下で自分を研ぎ澄まさなければならなかったが、彼らは決勝戦には適していないことを理解した。 私は主にud1とGreenTeaに焦点を合わせました-それらの戦略は私のものに似ていました。



ラウンドの準備2。



2回目のラウンドまでに、彼らは建物を押収し、生産を管理する方法を学ばなければなりませんでした。 Arrvユニットのミキシングは捨てられなければなりませんでした。 時間がかかりすぎた-平均900ティック。 潜在的な最適化が2倍であっても、これはまだ多くのことであり、その考えは放棄されなければなりませんでした。



経路の全長を最短にするために、開始チームのArrv、Tank、Ifv、および新たに建設されたものが散在し、建物を捕獲しました。 これは、ハンガリーのアルゴリズムによって解決される標準の割り当て問題です。 その他の建物選択アルゴリズムは変更されていません。 敵の装備の種類の説明を追加する価値がありましたが、これは優先機能ではないようでした。



パフォーマンスの問題は前面に出ていません。 マップ上のユニットの数が増加し、グループの数も増加しています。これは、あらゆる種類の動きの数を意味します。



最適化に費やした約1週間。 精度を犠牲にして最適化する必要がありました。 マップ全体でアクションをシミュレートする代わりに、各グループの近くで個別にシミュレーションを実行し、結果を貼り付けました。



核爆弾による恥ずかしさを避けるため、地図上に少なくとも1つの爆弾があったときにこれらの最適化をオフにしました。



グループをまっすぐに移動したりスピンしたりすると、さらに先に進み、衝突チェックを無効にする必要がありました。



最後になりますが、周囲に敵がいない場合、Moveの12のすべての方向をソートすることは意味がありません。



しかし、いいえ、最後ではありません。 偶数のグループは偶数の動きをし、奇数のグループは奇数の動きをします。 ちょうど建てられた(別名ホームレスの人々)-3歩ごと。 選択したユニットには、核爆弾モードとゲーム開始時の両方に例外があります(<3000ティック)。



最終準備



最終的には、敵ユニットの数とそれらがどこにあるかを制御する必要がありました。 各ユニットについて、前回表示された場所を思い出しました。 3つの配列があります。



目に見える技術の通常の配列(目に見える)



チェック済みの非表示機器の配列(チェック済み)。 各Idが最後に見られた場所はわかっていますが、もう存在しないことは確かです。



チェックされていない不可視の機器の配列(チェックされていない)。 これは、敵の存在のためにこの領域を偵察する必要があることを意味します。



配列は次のように入力されます。





視界の半径は、殺されたユニットを特定するのに十分な大きさであるか、視界から消えます。 例外は核攻撃による破壊ですが、これは非常にまれなケースです。 したがって、「死んだ魂」はほとんどありませんでした。



同じQuadTreeは、特にティックごとに1回実行する必要があるため、可視性をすばやく確認するという優れた仕事をしました。



これは、おそらく、霧の中でゲームをサポートするために行われたすべてのことです。






私は時間制限を克服しませんでした。以前のように、私のプログラムは、いくつかのマップでいくつかのライバルがいて、220秒に収まりません。 しかし、それでも、転倒に対してポイントで優位に立つことができます。



決勝戦では少し不運だった-最終的には4位、サンドボックスでは2位でした。 次回は強くなります。



どうもありがとう。 ロシアのAIカップ2018でお会いしましょう。






コード



All Articles