本文へジャンプ

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

送信されたすべての情報は安全です。

  • 閉じる [x]

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む


送信されたすべての情報は安全です。

  • 閉じる [x]

Robocodeの達人たちが明かす秘訣: 反重力移動

バトルフィールド上の特定の地点を避け、移動パターンを作成し、敵の弾丸をかわす

Alisdair Owensは、英国サウサンプトン大学のコンピューター・サイエンスの学生です。Java言語によるプログラミングに2年間携わっており、Robocodeに特に関心を寄せています。彼の連絡先は、awo101@ecs.soton.ac.uk.com です。

概要: 反重力移動 (多くの修正版がある) は、大部分の熟練したRobocodeプログラマーが採用する移動のタイプです。この移動方法では、マップ上で避けるべき地点を定義することができ、移動パターンを容易に作成し、敵の弾丸をかわすことができます。Alisdair Owensは、この有用な技法を実装する方法を紹介し、試運転のためのサンプル・ロボットを提供します。

日付:  2002年 5月 日
レベル:  中級 この記事の原文:  英語
アクティビティー: 3764 ビュー
お気軽にご意見・ご感想をお寄せください: 


反重力移動は、パターン分析型のロボットを欺くのに役立つ高度に柔軟な技法であり、バトルフィールド上で避けるべき特定の地点 (重力ポイント という) を定義することができます。重力ポイントにはそれぞれ、強さ が割り当てられます。この強さのx方向とy方向の成分を分析することにより、すべての敵ロボットを効果的に回避できます。(このヒントで使われる用語を理解する助けとして、「反重力の用語」という補足記事をご覧ください。)

この記事の前半では、基本的な反重力の技法を紹介し、後半では、この基本的なコードの根本的な限界を回避するためのアイデアについて説明します。

反重力の用語

重力ポイント: Robocodeバトルフィールド上に定義するポイントで、そこから反発力または誘引力が働くようにしたい領域のことです。

力: 各重力ポイントには、 もしくは 強さ を割り当てます。この値が大きいほど、その力を発生させているポイントに対してロボットが誘引または反発される度合いが大きくなります。

力の成分: それぞれの力には、x (水平) 方向に働く成分 と、y (垂直) 方向に働く成分があります。角度が45度の場合は、x方向とy方向の成分が等しくなります。角度が90度の場合は、x方向にのみ力が働き、角度が0度の場合は、y方向にのみ力が働きます。

力を分析する: 複数の力が相互に作用するときに、生成される合計の力を算出するプロセスのことです。たとえば、x方向に -200の力が働いているときに、同じくx方向に300の力も働いているとすると、生成される全体の力はx方向に100となります。

反重力移動の背後にある数学

三角法の実用的な知識を持っていれば、反重力の背後にある数学はごく簡単に理解できます。

図1で、"F" という矢印は、CrazyからAntiGravityBotに対する力の方向を示しています。力は、x方向とy方向の成分として考えるとことができます。これは、図にある他の2つの矢印で示されています。力を分析すると、すべての重力ポイントからの力をx方向とy方向で単純に加算することができ、x方向とy方向における合計の力を算出できます。


図1. 力を分析する

遠く離れたロボットから自分のロボットへの影響を小さくするには、重力ポイントから自分のロボットに対する力の計算に、 force = strength/Math.pow(distance,2) という関数を使用しなければなりません。この関数で、strength は重力ポイントのパワー、 distance は重力ポイントと自分のロボットの距離です。2というべき乗値は、固定ではありません。重力ポイントに非常に近づいたときにのみそのポイントを避けるようにするには、3という値を使用することもできます。


コード

この後のリストは、基本的な反重力システムのコードを示しています。リスト1は、メインの反重力関数です。この関数は、ベクトル内のすべての重力ポイントをたどり、力を解分析し、ロボットを正しい方向へ移動させます。敵ロボットを反発ポイントにすることをお勧めします。そのためには、バトルフィールドについてかなり最新の全体像を保持しなければならず、レーダーをかなり頻繁に回転させる必要があります。


リスト 1. The anti-gravity workhorse: antiGravMove()
                
void antiGravMove() {
    double xforce = 0;
    double yforce = 0;
    double force;
    double ang;
    GravPoint p;
    
    for(int i = 0;i<gravpoints.size();i++) {
        p = (GravPoint)gravpoints.elementAt(i);
        //Calculate the total force from this point on us
        force = p.power/Math.pow(getRange(getX(),getY(),p.x,p.y),2);
        //Find the bearing from the point to us
        ang = 
    normaliseBearing(Math.PI/2 - Math.atan2(getY() - p.y, getX() - p.x)); 
        //Add the components of this force to the total force in their 
        //respective directions
        xforce += Math.sin(ang) * force;
        yforce += Math.cos(ang) * force;
    }
    
    /**The following four lines add wall avoidance.  They will only 
    affect us if the bot is close to the walls due to the
    force from the walls decreasing at a power 3.**/
    xforce += 5000/Math.pow(getRange(getX(), 
      getY(), getBattleFieldWidth(), getY()), 3);
    xforce -= 5000/Math.pow(getRange(getX(), 
      getY(), 0, getY()), 3);
    yforce += 5000/Math.pow(getRange(getX(), 
      getY(), getX(), getBattleFieldHeight()), 3);
    yforce -= 5000/Math.pow(getRange(getX(), 
      getY(), getX(), 0), 3);
    
    //Move in the direction of our resolved force.
    goTo(getX()-xforce,getY()-yforce);
}

リスト2に示したヘルパー・メソッドを利用すると、自分のロボットと敵ロボットの距離を保つために最も効率の良い位置へ移動できます。


リスト 2. Helper methods
                
/**Move in the direction of an x and y coordinate**/
void goTo(double x, double y) {
    double dist = 20; 
    double angle = Math.toDegrees(absbearing(getX(),getY(),x,y));
    double r = turnTo(angle);
    setAhead(dist * r);
}

/**Turns the shortest angle possible to come to a heading, then returns 
the direction the bot needs to move in.**/
int turnTo(double angle) {
    double ang;
    int dir;
    ang = normalisebearing(getHeading() - angle);
    if (ang > 90) {
        ang -= 180;
        dir = -1;
    }
    else if (ang < -90) {
        ang += 180;
        dir = -1;
    }
    else {
        dir = 1;
    }
    setTurnLeft(ang);
    return dir;
}

/**/Returns the distance between two points**/
double getRange(double x1,double y1, double x2,double y2) {
    double x = x2-x1;
    double y = y2-y1;
    double range = Math.sqrt(x*x + y*y);
    return range;	
}

最後に、リスト3の GravPoint クラスは、重力ポイントについて必要なすべてのデータを保持します。反発させるためには、 power を負の値にしなければならないことに注意してください。


リスト 3.GravPoint class
                
class GravPoint {
    public double x,y,power;
    public GravPoint(double pX,double pY,double pPower) {
        x = pX;
        y = pY;
        power = pPower;
    }
}

このヒントのソース全体は、 参考文献からダウンロードできます。


振る舞いを改善する

リスト1~3のコードは、理にかなった振る舞いをロボットにさせますが、戦闘におけるパフォーマンスはあまり良くありません。ロボットは全般的に他のロボットから離れた位置を保ちますが、壁ぎわで立ち往生してしまう傾向があります。その理由は、たとえばロボットが下側の壁に達すると、自分より下にロボットは1台もないからです。したがって、ロボットを壁から押し戻す力は、壁そのものによる反発力しかありません。壁の反発力には限られた範囲しかないため、貧弱な振る舞いになってしまうわけです。

この問題と闘うために、私は、競技場中の一連のポイントにおける力を合計するシステムを使用しています。その後、力の総合計の平均値より力が大きいポイント (つまり、近くにロボットがいるポイント) に反発力の値を割り当て、平均値より力が小さいポイントに誘引力の値を割り当てます。その上で、あらためて、これらの新しいポイントから自分のロボットに対する力を分析します。誘引ポイントを割り当てる際には、きわめて慎重にしなければなりません。自分のロボットが誘引ポイントに近づくと、ロボットはその周囲をうろつくだけで、決して離れなくなってしまうからです。その理由から、これらの中間ポイントの位置をランダムに割り当てることと、その位置を定期的に変更することをお勧めします。

この拡張のためのコードを作成することは、読者にお任せします。基本的な原理はまったく同じままで、上記のコードに少しの変更を加えるだけですので、安心してください。もう少しのヒントとして、中間ポイントから自分のロボットへの力を計算する際に、 force = strength/Math.pow(distance,1.5)を使うことをお勧めします。


その他の拡張点

反重力は、非常に柔軟性のある技法です。そのため、実現できる振る舞いすべてを説明することは実際的でありません。しかし、興味深い拡張点のいくつかを、ここで紹介しておきます。

標的の選択: 攻撃しやすい標的、または弱っている標的の反発値を低く設定すれば、それらの標的の近くに移動して、弱い相手を仕留めることができます。

ランダム化: かなり定期的に、xおよびy方向の力からランダムな値を加算または減算することにより、いっそうランダムな動きを実現できます。時には停止することさえ可能でしょう。そうすれば、敵の標的合わせシステムを欺くことができます。この振る舞いを実装することを、強くお勧めします。

混戦で弾丸をかわす: 敵から自分に向けて弾丸が発射された時点を検知できるのであれば、発射された弾丸を反重力ポイントとしてモデル化できます。たとえば、敵の弾丸が直線方式の標的合わせで発射されたと想定される場合は、その重力ポイントの位置を各動作 (turn) ごとに更新することにより、弾丸をかわすことができます。しかし、この拡張を完全に実現したロボットはまだありません。

リーダーに従う: この拡張には、自分のロボットに誘引ポイントを設定して従わせることが関係しています。こうして、そのポイントを移動することにより、自分の望むパターンを (Robocodeの物理法則の範囲内で) 生み出すことができます。しかも、標準的な反重力の壁反発には従います。



ダウンロード

内容ファイル名サイズダウンロード形式
Source codej-antigrav.zip12KBHTTP

ダウンロード形式について


参考文献

  • 反重力の技法を実際の戦闘でテストしてみるには、この完全に機能するロボットをご利用ください。

  • alphaWorksから最新版のRobocode をダウンロードできます。

  • Christian Schnellによる RoboLeague は、Robocodeのためのリーグおよびシーズン・マネージャーです。これを利用すると、どんなグループ分けでも実際に試合を実行し、その結果を管理し、HTMLの状況報告書を生成できます。

  • 闘え、Robocode (ロボコード)」(developerWorks、2002年1月) では、Robocodeの武装を解きほぐし、カスタマイズされた軽量で平均的な戦闘マシンの構築を始める手ほどきをします。

  • 闘え、Robocode (ロボコード): 第2ラウンド」(developerWorks、2002年5月)では、Sing Li氏が、高度なロボットの構築とチーム・プレイに目を向けます。

  • Javaの初心者にとっては、 Introduction to Java programming" (developerWorks、2004年11月) が、Java言語プログラミングの基礎を順を追って学習できるチュートリアルになっています。

  • その他のJava関連の参考資料は、 developerWorksJava technologyゾーンで参照できます。

著者について

Alisdair Owensは、英国サウサンプトン大学のコンピューター・サイエンスの学生です。Java言語によるプログラミングに2年間携わっており、Robocodeに特に関心を寄せています。彼の連絡先は、awo101@ecs.soton.ac.uk.com です。

不正使用の報告のヘルプ

不正使用の報告

ありがとうございます。 このエントリーは、モデレーターの注目フラグが設定されました。


不正使用の報告のヘルプ

不正使用の報告

不正使用の報告の送信に失敗しました。


developerWorks: サイン・イン


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


お客様が developerWorks に初めてサインインすると、プロフィールが作成されます。 プロフィールで選択した情報は公開されますが、いつでもその情報を編集できます。 お客様の姓名(非表示設定にしていない限り)とディスプレイ・ネームは、投稿するコンテンツと一緒に表示されます。

表示名をお選びください

developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

(半角英数字で3文字以上31文字以下にする必要があります)


「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 利用条件

 


この記事を評価する

コメント

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology
ArticleID=284462
ArticleTitle=Robocodeの達人たちが明かす秘訣: 反重力移動
publish-date=052002
author1-email=awo101@ecs.soton.ac.uk.com
author1-email-cc=jaloi@us.ibm.com

タグ

Help
このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。

スライダーバーを使用することで、より多く(少なく)タグを表示します。

人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。

マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。

このタグで、My developerWorks のすべてのタイプのコンテンツを見つけるために検索フィールドを使用します。人気のタグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するトップのタグを表示します。マイ・タグは、この特定のコンテンツ・ゾーン(例えば、Java テクノロジー、Linux や WebSphere など)に対するお客様ご自身のタグを表示します。