ロシアAIカップでの戦車操縦





Mail.ruグループITコンテストの1つに参加することについてのちょっとした話。





「ロシアのAIカップとCodeTanksに招待します!」という手紙を受け取りました。 私はずっと参加したかったので、登録に行きました。 フォームは驚くほどシンプルでしたが、受け取った手紙は喜ばなかった(((((





この日、すべてが登録時に終了しました。 時間は0:27で、午前中は仕事をしていました。 私は週末に座ってアルゴリズムを勉強して書くことにしました。



週末が来た、私はマニュアルを読み始めた、私はすべてを再説するつもりはありません。 主題の誰がすべてを知っていて、誰が知らないのか、短い余談で十分です。 それぞれ独自の戦略(アルゴリズム)を備えた6つの戦車が置かれる、所定のサイズのフィールドがあります。 ここでは、ちょうど戦略と競争の参加者を書きます。 この戦略には、追跡可能なフィールド上に、弾丸、戦車、ボーナス、オブジェクト座標、各トラックのエンジン出力、その他多くのオブジェクトとパラメーターがあります。 その他







組み込みの数学関数には2つしかありません。これは、オブジェクト間の距離と、1つのオブジェクトの中心を通る線とオブジェクトの中心を結ぶ線との間の角度です。 他のすべては、戦略を書く人の手に落ちます。



主なポイントは、できるだけ多くのポイントを獲得し、生き続けることではありません。 他の戦車に命中して破壊するためのポイントが与えられます。



私が思いついた最初のアルゴリズムは非常に簡単でした。 フィールドの周りに乗って、フィールドに表示される最も近いボーナスを収集し、タンクを撃ちます。これにより、タワーの回転角度は最小になります。



size_t selected_tank = all_tanks.size(); for(size_t i = 0; i < all_tanks.size(); ++i) { //     Tank tank = all_tanks[i]; if (!tank.teammate() && tank.crew_health()) { //       :)     double angle_to_enemy = fabs(self.GetTurretAngleTo(tank)); //        if (angle_to_enemy < min_angle_to_enemy) { //   min_angle_to_enemy = angle_to_enemy; selected_tank = i; } } }
      
      







このようなアルゴリズムはあまり良いものではありませんでしたが、すでに良い結果を示しています。





ゲームに安定性があれば問題はありませんが、スケジュールでわかるように、最初に、最後に場所があります。



このアルゴリズムの最適化が開始されました。 最初の最適化では、ティックが40を超えない場合は直線モーションを追加し、ターゲットが500ピクセルより近い場合は超弾丸で撃ちました。



  if (self.GetDistanceTo(all_tanks[selected_tank]) < MIN_DISTANCE_FOR_PREMIUM_AMMO || self.premium_shell_count() > 2 || all_tanks[selected_tank].crew_health() < 35 || all_tanks[selected_tank].hull_durability() < 35 ){ move.set_fire_type(PREMIUM_PREFERRED); //   ,   } else{ move.set_fire_type(REGULAR_FIRE); //   ,   }
      
      







これらの変更は肯定的な結果を生みませんでしたが、逆に結果は悪化しました。



いくつかの戦いを分析した後、フィールドの端から押し出すことにしました。これは、フィールドの中央に4分の1に分割するように取り付けられたためです。







そして、私がどのクオーターにいるかに応じて、コーナーを出るときとコーナーを出るときに特定のルールを適用しています。



  if( self.GetDistanceTo(640,400) < 50 || last_tick_stright_move + 60 < world.tick() && all_shels.size()){ move.set_left_track_power(1.0); //     30  move.set_right_track_power(1.0); //     if( last_tick_stright_move + 80 < world.tick()){ last_tick_stright_move = world.tick(); counter_tick_straight_move++; } } else if (angle_to_center > MIN_ANGLE) { //    , move.set_left_track_power(1*mod_l); //   , move.set_right_track_power(0.5*mod_r); //    . } else if (angle_to_center < -MIN_ANGLE) { //    , move.set_left_track_power(0.5*mod_l); //   move.set_right_track_power(1*mod_r); //   . } else { move.set_left_track_power(1.0*mod_l); //     30  move.set_right_track_power(1.0*mod_r); //     counter_tick_straight_move++; if(counter_tick_straight_move > 30){ last_tick_stright_move = world.tick(); counter_tick_straight_move=0; } }
      
      







したがって、彼は問題を打ち負かし、端のタンクが向きを変えるのに多くの時間を費やさないようにしました。





(チャートでは、ドロップは1回の最適化であり、その後の離陸は2回目の最適化です)



もう一度少し分析します。 そして、端から私は避けていたことが明らかになりましたが、これをしている間、私は他に何も反応しません。 そして、根本的に新しいアイデアが生まれました。 古いアルゴリズムを忘れて、新しいアルゴリズムを作成します。その秘密は、競技終了後に公開しますが、今すぐチャートを表示する準備ができています。





最新の成長は、新しい戦略の実現と関連しています。 14ゲームのうち、4位を獲得したゲームが1つ、3位を獲得したゲームが2つ、2位を獲得したゲームが1つ、リーダーになったゲームが10ゲームありましたが、残念ながら選択したことに気付きましたプレーヤーの評価アルゴリズムには誤算があります。 そして、ここにアルゴリズムの記述とともに

選択した評価システムの学習に切り替えました。 ドキュメンテーションから、彼らは評価システムEloを使用して、 読むために走っことが判明しました。

ええ、このシステムは、チェスなど2人が参加するゲームのプレイヤーの相対的な強さを計算するために使用されます。 掘り下げて、引用しません-multibukaf。 しかし、ポイントは、このシステムは特定の瞬間にプレイヤーの急激に変化したスポーツ形態を考慮しないということです。つまり、戦車を制御するアルゴリズムを大幅に改善したことで、最も近いライバルを歩き回ることになります。予測されたシステムよりも多くの利益を得て、システムの予測は常に最大になります。 すべての対戦相手が強制的に近くにいる場合、レーティングはそれほど大きくなりません。



最も厄介なのは、コンテストの最初のラウンドが始まる数時間前にそれを読み、サンドボックスから900個のアルゴリズムしか渡されなかったことです。 そして、すぐに新しいアカウントを作成するために急いで行きました。そこで、アルゴリズムをアップロードしましたが、900の通過場所に入るための1戦が十分ではありませんでした!



同時に、いつものように、政権は彼らのブログの投稿に賢明に反応しませんでした。 そして、この記事を書いた3日後、彼らは評価システムの更新をリリースしました! 控えめに言っても、選択したシステムの欠陥を認識している場合:

? , , , , , , .

.








しかし、最高の900個のアルゴリズムの選択はすでに合格しています! さらに、同じ投稿で、彼らは戦車の環境と戦闘特性を変更しますが、これはもちろん参加者の間でポジティブな感情とネガティブな感情の両方を引き起こします...



結論は、主催者に良い大会に参加する機会を与えてくれたことに感謝し、プレーヤー評価システムを選んだ人たちをカバーすることです。 ただし、主催者が誰であるかを割り引いたので、彼らはそのような人々を誓うのではなく、単に理解をもって彼らを扱います。 感謝します。



shulyakovskiyの要請により発行



All Articles