ロシアのAIカップ2018 CodeBallに参加するボットの作成





スポーツプログラミング競技の後、勝者または選手だけがHabréに記事を投稿して、競技に参加することの素晴らしさ、そして優勝の選択肢として伝えることが伝統となっています。 もちろん、将来の競技会のために彼の記事から多くを集めることができます。



しかし、ベータテスト段階での現在の競争への参加についての記事はほとんどないと思います。決定コードを公開できないことは明らかです。 著者は、読者に出発列車に立ち寄って、ゲーム戦略の世界への新年旅行を楽しむ機会を与えます。



まず、記事を開いてくれてありがとう、すぐに秘密を共有したい。これは、遺伝的アルゴリズムとニューラルネットワークに触れたい一連の記事になるだろう。 それまでの間、すでに上で書いたように、ロシアのAI Cup CodeBallへの旅行へようこそ。



チャンピオンシップのクイックスタートページへのリンク。



上記のリンクで、読者はチャンピオンシップのルール、ゲーム自体のルール、およびボットを作成するために必要な数学的装置の主要部分を見つけることができます。 また、クイックスタートページには、さまざまなプログラミング言語用に既に作成されたボットの例があり、初期起動を大幅に促進します。



シンプルなCodeBallチャンピオンシップタイトルから始めましょう。



コードとボールの素晴らしい組み合わせ、ほとんどサッカー。 ゲームのルールとロジックもサッカーに似ていますが、各ラウンドでより複雑になります。そのため、ゲームの初期条件を基礎とします。



最近の歌で述べられているように、ゲームの本質:プレーヤーが得点し、ゴールキーパーがボールを打つ必要があります。



回路図の競技場:







ボットはXZアリーナフロアの平面内を移動し、Y軸がゲームオブジェクトの高さを担当することに注意してください。



また、ゲームのオブジェクト(ボールとボット(主催者はロボットと呼びます))の概略図







写真をサポートするためのテキストを追加しました。 競技場は3次元の閉じた空間であり、ボールもボットもそれを超えることはできません。 このスペースでは、ボールがプレーヤーの1人によって得点されたと見なされる、ヒット時の「ゲート」の2つの領域があります。 ゴールを数えるためには、ボールがゴールラインの後ろに完全にあることが必要です(図の点線で示されています)。



ゲームオブジェクト(アリーナ、ボール、ボット)の衝突(衝突)の計算を簡素化するため、ボットとボールは理想的な球体(ボール)と見なされます。これは、球体の半径、球体の中心の座標、質量、速度によって記述されます。 また、アリーナは理想的な数学的プリミティブによって記述されるため、ポリゴンの関与なしで衝突計算が不要になり、タスクが大幅に簡素化されます。 チャンピオンシップルールを最後までスクロールすると、読者は擬似コードでプログラムを見つけます。このプログラムは、上記の計算を行うだけです。 この疑似コードは、物理的な労力をほとんどかけずに、選択したプログラミング言語に翻訳されており、非常に機能します。 しかし、それについては後で。



ゲーム世界の物理学についてのいくつかの言葉。 アリーナで起こっていることの信頼性を高めるために、重力が導入されます。つまり、ボットとボールは常に、アリーナの床に対して下向きの重力の影響を受けます。 物体の摩擦や角速度(回転)などの物理的な相互作用の他の形式は、物理世界の記述の単純さを支持して、主催者によって無視されました。 アリーナの壁にぶつかると、ボールはそのエネルギーの一部を失いますが、これは世界を大きく複雑にすることはなく、ボールの形で永続的なモーションマシンを作成する方法がないことは外部から理解できます。



世界をさらにもっともらしいものにするために、TicksとMikrotiksによる計算スキームが適用されました。 彼の最初の記事で、著者は演奏時間の目盛りの概念について詳しく説明しました。 このコンペティションでは、ソースコードの物理エンジンを見ることができます。彼が言ったように、これは将来役に立つと思います。プレイヤーにはTicsがあり、エンジン内ではすべてがMikrotikで発生します。オブジェクトの衝突を記述し、アリーナ外のオブジェクトの障害や、オブジェクト間の相互作用のエラーにつながる相互の障害などの不快なことを避けます。







世界(アリーナ)とゲームの時間を把握しました。ボットとボールのゲームオブジェクトを見てみましょう。 上で競争のルールからすでに見つけたボールは球体です。 簡単に言うと、ボットは半径が小さく、質量が大きいボールであり、コマンドを与えることができます:目的の速度(これは方向と速度の長さまたは大きさの両方を含む3次元ベクトルです)と、ジャンプが視点から現在推奨されている場合のジャンプの強さを示しますゲームのロジック。 競争のこの段階では、ボットが飛行中の場合(アリーナの壁に触れない場合)、速度を変更するコマンドを実行する機能がないという単純化が導入されました。



最も困難なもの、またはその逆の単純なものに目を向けます。それはすべて、3次元ベクトルの操作における読者の経験に依存します。 ゲームオブジェクトの場所の説明。 サポート画像







植物学に取りかかりましょう。



ゲームのティックごとに、戦略は次のオブジェクトを受け取ります。



ボール:



class Ball: x: Float //     y: Float z: Float velocity_x: Float //    velocity_y: Float velocity_z: Float radius: Float //  
      
      





各ボットのデータを含むボットのリスト:



 class Robot: id: Int player_id: Int is_teammate: Bool // true,      x: Float //     y: Float z: Float velocity_x: Float //    velocity_y: Float velocity_z: Float radius: Float //    nitro_amount: Float //     touch: bool // true,      touch_normal_x: Float //        touch_normal_y: Float ( null,   ) touch_normal_z: Float
      
      





このデータを扱うのが不便であることはすぐに明らかであり、クラス(オブジェクト)3Dベクトルとクラス2Dベクトルを導入することが望ましいです。 ここでは、選択したプログラミング言語に大きく依存します。 通常、これらのクラスはすでに作成されており、目的のプログラミング言語用にインターネットで簡単に見つけることができます。 著者は現在、C ++でボットを書いていますが、疑似コードに制限しようとしています。 本格的なベクトルのクラスを導入すると、加算、減算、乗算、正規化、およびその他のベクトル演算の操作がクラス内に残り、戦略の作業が大幅に簡素化されます。



リスト内のどのボットがあなたのものであるかを示すプレーヤークラスもあります。



 class Player: id: Int me: Bool // true,      strategy_crashed: Bool score: Int //   
      
      





ゲームワールドに関するデータを戦略の入力に送信した後、ゲームエンジンは制御を提供し、計算のタイマーを開始します。計算の時間は、ティック内のすべてのアクションで平均で約20ミリ秒に制限されます。 現時点では、受信したデータをデシリアライズし、戦略によってサーバーに送信されたデータをシリアライズする時間も含まれているのではないかと疑われています。 しかし、ボットの数は4(2人と2人の対戦相手、最終ラウンドではボットの総数が6に増える)であるため、これらの操作の時間は無視できます。



チームの時が来ました。



たとえば、ボットにボールに向かって移動するコマンドを与えたいとします。 速度の方向の目的のベクトルを見つけるには、ボールの位置からボットの位置を減算する必要があります。ボールへの方向ベクトルを取得し、それを正規化して、世界定数からボットの最大速度を掛けることができます。 写真でもっと







おそらく、読者はスライド上で、3Dベクトルと2Dベクトルの両方に対して計算を実行できることに気付きました。 ボットがアリーナの床面により多くの時間を費やすという事実を考えると、計算を2つの座標に単純化しても、ボールをインターセプトする計算の精度には影響しません。 もちろん、ボールの高さを忘れてはなりませんが、重力を考慮すると、遅かれ早かれボットに沈みます。



ボットジャンプは垂直速度(垂直速度)の追加であり、ボットのジャンプの方向は現在のボット速度の方向と一致し、Y軸に沿ってコンポーネントが追加されます。



上記の単語に動きのより複雑なロジックを追加すると、ボットの次の動作を取得できます。





現在、このサイトにはゲームを見ることができるサンドボックスがありますが、戦略を書いてゲームをフォローしても何も気になりません。 数十行のコードで構成される最も単純な戦略でさえ、非常にうまく機能することが実験的に確立されました。



頭に浮かぶ戦略の単純な形式のうち、ゲートを保護するために1つのボットを割り当て、攻撃者を作るために2番目のボットを割り当てる戦略。 攻撃者の主な目的は、ボールを追いかけ、成功した場合、相手のゴールに向かって攻撃することです。 ゴールキーパーとしてプレーするボットは、通常、フィールド内での動きが制限されており、主にゴールエリアで動作します。 これらはすべて、選択した言語のif-else構造を使用して簡単に記述できます。 いずれにしても、読者はこの段階で戦略を考え出し、作成する必要があります。 競争の条件に従って、戦略のソースコードを公開することはできません。 しかし、戦略を設計するアプローチを議論することは禁止されていないと思います。



コンテストの主催者がトーナメントの興味深いトピックを選んだようです。唯一のサイトは少し遅いですが、すぐに修正されることを望みます。



チャンピオンシップの参加者からのいくつかの美しいゲームの瞬間:





この記事に関するコメントでフィードバックを待っています。詳細については何を説明しますか。

次の記事では、戦略の中でより意味のあるボットのゲームに間に合うようにボールの挙動を予測する方法を説明します。



それまでの間、2019年の新年がおめでとうございます!



継続する。



All Articles