26
プログラミング2 【ロボコード】 提出日:11 月 30 日(金) 所属:工学部情報工学科 学籍番号:075713G 氏名:神山朗

プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

  • Upload
    others

  • View
    0

  • Download
    0

Embed Size (px)

Citation preview

Page 1: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

プログラミング2

【ロボコード】

提出日:11 月 30 日(金)

所属:工学部情報工学科

学籍番号:075713G

氏名:神山朗

Page 2: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

2

【目次】

[1] 各サンプルのソースにコメントをつけ,プログラムをくわしく説明しなさい.

1. Corner ・・・ 3 ̃ 5 P

2. Crazy ・・・ 6 ̃ 7 P

3. Fire ・・・ 8 ̃ 9 P

4. Interactive ・・・ 10 ̃ 12 P

5. RamFire ・・・ 13 P

6. SittingDuck ・・・ 14 ̃ 15 P

7. SpinBot ・・・ 16 P

8. Target ・・・ 17 P

9. Tracker ・・・ 18 ̃ 20 P

10.TrackFire ・・・ 21 ̃ 22 P

11.Walls ・・・ 23 ̃ 24 P

[2] 各ロボットを対戦させ,各ロボットの特徴を調査しなさい.

1. 各ロボット同士のタイマンによる結果 ・・・ 25 P

[3] 感想&参考HP ・・・ 26 P

Page 3: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

3

[1] 各サンプルのソースにコメントをつけ,プログラムをくわしく説明しなさい.

Corners package sample;

import robocode.*; // robocode.*をインポートする。

public class Corners extends Robot{

int others; // int型の変数othersを宣言

// このゲームでの他のロボットの数

static int corner = 0; // int型の変数cornerを宣言(角度として使用)

// 現在使っているのはどの隅なのかを記憶する。

// staticメソッドなのでラウンドが変わっても

// 値は保持される

boolean stopWhenSeeRobot = false; // goCorner()を参照

// booleanは真偽値を表す型。

// stopWhenSeeRobotは下に記述

// されている。

public void run() { // run : Cornersのメインメソッド。

others = getOthers(); // getOthers = 残存している敵ロボットの数を調査。

goCorner(); // goCornerを参照。

int gunIncrement = 3; // int型の 変数gunIncrementを宣言、3に初期化。

while (true) {

for (int i = 0; i < 30; i++) { // int型の 変数iはカウンターのため

turnGunLeft(gunIncrement); // 引数にgunIncrement(= 3)が使用されている。

} // また、turnGunleftで砲塔を3度左回転させる。

gunIncrement *= -1; // while文のループを抜けると

// gunIncrementに-1をかける。

}

}

public void goCorner() { // runメソッドの中のgoCornerの内容を記述

stopWhenSeeRobot = false; // stopWhenSeeRobotをfalseにする。

turnRight(normalRelativeAngle(corner - getHeading()));

// normalRelativeAngleは下に記述。

// getHeading()で現在のロボットの向きを取得

// normalRelativeAngleにとり返された角度だけ右回転する。

stopWhenSeeRobot = true; // stopWhenseeRobot を trueにする。

ahead(5000); // ロボットを前方に5000pxだけ前進させる。

turnLeft(90); // ロボット自体を90度だけ左回転させる。

Page 4: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

4

ahead(5000); // ロボットを前方に5000pxだけ前進させる。

turnGunLeft(90); // 砲塔を90度だけ左回転させる。

}

public void onScannedRobot(ScannedRobotEvent e) {

if (stopWhenSeeRobot)

{ // もし敵ロボットを見つけた場合の行動

stop(); // stopはtrueで停止, falseで停止キャンセル

smartFire(e.getDistance()); // getDistanceで相手との距離を取得

scan(); // レーダーにより他のロボットを探す。

resume(); // resumeによりstopから復帰

}

else

smartFire(e.getDistance()); //

}

public void smartFire(double robotDistance) { // 距離により大砲の威力を変える。

if (robotDistance > 200 ¦¦ getEnergy() < 15)

fire(1);

else if (robotDistance > 50)

fire(2);

else

fire(3);

} // この処理が終わったら上に引き渡される。

public void onDeath(DeathEvent e) { // 死んだ後の行動パターン

if (others == 0) // もし残存する敵の数がゼロ(= 自分の勝ち)なら

return; // そのまま角を変えないで次のバトルへ

if ((others - getOthers()) / (double)others < .75) { // もし敵ロボットの75%が生存なら

corner += 90; // corner に +90する。

if (corner == 270) // そのとき既に corner =270なら

corner = -90; // corner に -90する。

System.out.println("I died and did poorly... switching corner to " + corner);

// 画面に "I died and did poorly... switching corner to [ cornerの数字 ]" を出力

}

else

System.out.println("I died but did well. I will still use corner " + corner);

// 画面に "I died but did well. I will still use corner [ cornerの数字 ]" を出力

}

public double normalRelativeAngle(double angle) { // 角度を-180度から180度の範囲に直したものを返す。

if (angle > -180 && angle <= 180)

return angle;

double fixedAngle = angle;

Page 5: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

5

while (fixedAngle <= -180)

fixedAngle += 360;

while (fixedAngle > 180)

fixedAngle -= 360;

return fixedAngle;

}

}

// 角を1つ占領して攻撃するロボット。超強そうだが、動き回るロボットにはやたら弱い。

Page 6: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

6

Crazy package sample;

import java.awt.Color;

import robocode.*;

public class Crazy extends AdvancedRobot {

boolean movingForward; // boolean型の変数 movingForward を作成。

// while文で使用する。

public void run() {

setBodyColor(new Color(0, 200, 0)); // ロボの色設定。

setGunColor(new Color(0, 150, 50));

setRadarColor(new Color(0, 100, 100));

setBulletColor(new Color(255, 255, 100));

setScanColor(new Color(255, 200, 200));

while (true) {

setAhead(40000); // 40000pxだけ前進するように設定する。この時点ではブロックされている。

// 実際に動くのは、WaitForメソッド(ブロッキング呼び出し)の後である。

movingForward = true; // movingForwardをtrueに設定。

setTurnRight(90); // 右に90度回転するように設定する。

// これもsetAhead同様。

waitFor(new TurnCompleteCondition(this)); // ここでブロックがとかれるのでその間に

// ロボットはカーブを描いて進んでいる。

setTurnLeft(180); // 逆方向にカーブを描くようにSet。

waitFor(new TurnCompleteCondition(this)); // ブロック解除。

setTurnRight(180); // さらに逆方向にカーブを描くようにSet。

waitFor(new TurnCompleteCondition(this)); // ブロック解除。

// 一連の動作を繰り返す。

}

}

public void onHitWall(HitWallEvent e) { // 壁に当たった後の行動。

reverseDirection(); // 下に記述。

}

public void reverseDirection() {

if (movingForward) { // もし、前進でぶつかった場合。

setBack(40000); // 40000px後進する様にSet。

movingForward = false; // movingForward を falseにする。

Page 7: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

7

} else { // もし、後進でぶつかった場合。

setAhead(40000); // 40000px前進する様Set。

movingForward = true; // movingForward を trueにする。

}

}

public void onScannedRobot(ScannedRobotEvent e) { // 敵ロボを見つけたら1の威力で攻撃。

fire(1);

}

public void onHitRobot(HitRobotEvent e) { // 敵ロボに当たった時の行動。

if (e.isMyFault()) { // 自分からぶつかったら

reverseDirection(); // reverseDirectionを実行。(反転する。)

}

}

}

// 八の字に動き回るロボット。なかなか強い。

Page 8: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

8

Fire package sample;

import java.awt.Color;

import robocode.*;

public class Fire extends Robot {

int dist = 50; // int型の変数 dist を作成。50で初期化。

public void run() {

setBodyColor(Color.orange); // ロボの色を設定。

setGunColor(Color.orange);

setRadarColor(Color.red);

setScanColor(Color.red);

setBulletColor(Color.red);

while (true) {

turnGunRight(5); // 5度ずつ砲塔を右回転させる。

}

}

public void onScannedRobot(ScannedRobotEvent e) { //敵ロボを見つけた場合。

if (e.getDistance() < 50 && getEnergy() > 50) { // 距離が50より下 かつ 自分の体力が50より上。

fire(3); // 3の威力で攻撃。

}

else { // 他の場合。

fire(1); //1の威力で攻撃。

}

scan(); // 砲塔が回り始める前にもう一度スキャンする。(これにより連続攻撃が可能。)

}

public void onHitByBullet(HitByBulletEvent e) { //敵ロボの攻撃をくらった場合。

turnRight(normalRelativeAngle(90 - (getHeading() - e.getHeading()))); //

ahead(dist); // dist分だけ前方に移動。

dist *= -1;

scan(); // scan開始。

}

public void onHitRobot(HitRobotEvent e) { // 敵ロボに当たった場合。

double turnGunAmt = normalRelativeAngle(e.getBearing() + getHeading() - getGunHeading());

// 上の記述でdouble型の変数 turnGunAmt にぶつかった敵ロボと自分との相対角度を設定。

turnGunRight(turnGunAmt); // turnGunAmt分だけ右回転。

fire(3); // 3の威力で攻撃。

}

public double normalRelativeAngle(double angle) {

Page 9: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

9

if (angle > -180 && angle <= 180) {

return angle;

}

double fixedAngle = angle;

while (fixedAngle <= -180) {

fixedAngle += 360;

}

while (fixedAngle > 180) {

fixedAngle -= 360;

}

return fixedAngle;

}

}

// 敵の攻撃が当たるまでその場にとどまり攻撃するロボット。

Page 10: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

10

Interactive package sample;

import static java.awt.event.KeyEvent.*;

import static robocode.util.Utils.*;

import java.awt.event.KeyEvent;

import java.awt.event.MouseEvent;

import java.awt.event.MouseWheelEvent;

import java.awt.Color;

import java.awt.Graphics2D;

import robocode.AdvancedRobot;

/* - ↑: 前に動く

* - ↓: 後ろに動く

* - →: 右を向く(右回転)

* - ←: 左を向く(左回転)

* マウス:

* - 上にコロコロ: 前に動く

* - 下にコロコロ: 後ろに動く

* - ボタン 1: 攻撃の威力 = 1

* - ボタン 2: 攻撃の威力 = 2

* - ボタン 3: 攻撃の威力 = 3

*

* 攻撃の威力:

* - 1: Yellow

* - 2: Orange

* - 3: Red

*

*/

public class Interactive extends AdvancedRobot {

int moveDirection;

int turnDirection;

double moveAmount;

int aimX, aimY;

int firePower;

public void run() {

setColors(Color.BLACK, Color.WHITE, Color.RED);

for (;;) { // いろんな行動をSetする。

setAhead(moveAmount * moveDirection);

Page 11: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

11

moveAmount = Math.max(0, moveAmount - 1);

setTurnRight(45 * turnDirection);

double angle = normalAbsoluteAngle(Math.atan2(aimX - getX(), aimY - getY()));

setTurnGunRightRadians(normalRelativeAngle(angle - getGunHeadingRadians()));

if (firePower > 0) {

setFire(firePower);

}

execute(); // ここで上のSetを解放する。

}

}

public void onKeyPressed(KeyEvent e) { // 何かキーを押された時の行動。

switch (e.getKeyCode()) { // スイッチ文で行動を判断する。

case VK_UP:

moveDirection = 1;

moveAmount = Double.POSITIVE_INFINITY;

break;

case VK_DOWN:

moveDirection = -1;

moveAmount = Double.POSITIVE_INFINITY;

break;

case VK_RIGHT:

turnDirection = 1;

break;

case VK_LEFT:

turnDirection = -1;

break;

}

}

public void onKeyReleased(KeyEvent e) { // キーからの入力がない場合

switch (e.getKeyCode()) { // 止まる様に設定。

case VK_UP:

case VK_DOWN:

moveDirection = 0;

break;

case VK_RIGHT:

Page 12: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

12

case VK_LEFT:

turnDirection = 0;

break;

}

}

public void onMouseWheelMoved(MouseWheelEvent e) { // マウスのコロコロによる移動。

moveDirection = (e.getWheelRotation() < 0) ? 1 : -1;

moveAmount += Math.abs(e.getWheelRotation()) * 5;

}

public void onMouseMoved(MouseEvent e) { // マウスによるレーダーの位置設定

aimX = e.getX();

aimY = e.getY();

}

public void onMousePressed(MouseEvent e) { // マウスクリックによる攻撃の設定

if (e.getButton() == MouseEvent.BUTTON3) {

firePower = 3; // ボタン3なら攻撃の威力3。また赤色。

setBulletColor(Color.RED);

} else if (e.getButton() == MouseEvent.BUTTON2) {

firePower = 2; // ボタン2なら攻撃の威力2。またオレンジ。

setBulletColor(Color.ORANGE);

} else {

firePower = 1;// ボタン1なら攻撃の威力1。また黄色。

setBulletColor(Color.YELLOW);

}

}

public void onMouseReleased(MouseEvent e) { // マウスのボタンから手を離すと攻撃やめ。

firePower = 0;

}

public void onPaint(Graphics2D g) {

g.setColor(Color.RED);

g.drawOval(aimX - 15, aimY - 15, 30, 30);

g.drawLine(aimX, aimY - 4, aimX, aimY + 4);

g.drawLine(aimX - 4, aimY, aimX + 4, aimY);

}

}

// 自分で操作するロボット。なので強さは自分による。

Page 13: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

13

RamFire package sample;

import robocode.*;

public class RamFire extends Robot

{

int turnDirection = 1; // int型の関数 turnDirection を作成し、1で初期化。

public void run() {

while (true)

{

turnRight(5 * turnDirection); // turnDirection × 5 だけ右回転する。

}

}

public void onScannedRobot(ScannedRobotEvent e) { // 敵ロボを発見した時の行動。

if (e.getBearing() >= 0) // 敵ロボから攻撃をくらった方向が0度以上なら

turnDirection = 1; // turnDirection に 1を設定。

else // 他の場合

turnDirection = -1; // turnDirection に-1を設定。

turnRight(e.getBearing()); // getBearing分だけ右回転。

ahead(e.getDistance() + 5); // 敵ロボとの距離 + 5 だけ前進。

scan(); // 敵ロボを探す。

}

public void onHitRobot(HitRobotEvent e) { // 敵ロボに激突しにいった後の行動。

if (e.getBearing() >= 0) // 敵ロボから攻撃をくらった方向が0度以上なら

turnDirection = 1; // turnDirection に 1を設定。

else // 他の場合

turnDirection = -1; // turnDirection に-1を設定。

turnRight(e.getBearing()); // getBearing分だけ右回転。

if (e.getEnergy() > 16) // ロボの体力を判断し、攻撃の威力を決める。

fire(3); // 自ら敵ロボに激突したらポイントが入るので

else if (e.getEnergy() > 10) // それのみをねらっている。

fire(2); // よって自分の体力を削らないようにだんだん

else if (e.getEnergy() > 4) // 弱い威力で攻撃するように設定。

fire(1);

else if (e.getEnergy() > 2)

fire(.5);

else if (e.getEnergy() > .4)

fire(.1);

ahead(40); // また激突しにいく。

}

}

// このロボットは激突で敵を倒してもらえるポイントを得るロボット。

// 作戦がせこい。

Page 14: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

14

SittingDuck package sample;

import robocode.*;

import java.io.*;

import java.awt.Color;

public class SittingDuck extends AdvancedRobot

{

static boolean incrementedBattles = false;

public void run() {

setColors(Color.yellow,null,null); // ロボの色を設定。

int roundCount, battleCount; // int型の変数 roundCount battleCountを作成。

try {

BufferedReader r = new BufferedReader(new FileReader(getDataFile("count.dat")));

// カウントをゲット取得する。

roundCount = Integer.parseInt(r.readLine());

battleCount = Integer.parseInt(r.readLine());

} catch (IOException e) { // ファイルの読み込みに失敗したとき

roundCount = 0; // それぞれをリセット。

battleCount = 0;

} catch (NumberFormatException e) { // int型への変換に失敗したとき

roundCount = 0;

battleCount = 0;

}

roundCount++; // roundCountに+1する。(ラウンド数をインクリメント。)

if (!incrementedBattles) { // もしまだバトル数がインクリメントされていなければ

battleCount++; // バトル数をインクリメント。

incrementedBattles = true; // incrementedBattlesにtrueを設定。

}

try { // PrentStreamはプリント中にIOExceptionを投げず、フラグをセットするだけである。ここでチェッ

クを試みる。

PrintStream w = new PrintStream(new RobocodeFileOutputStream(getDataFile("count.dat")));

w.println(roundCount);

w.println(battleCount);

if (w.checkError())

out.println("I could not write the count!");

w.close();

} catch (IOException e) {

out.println("IOException trying to write: " + e);

}

Page 15: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

15

out.println("I have been a sitting duck for " + roundCount + " rounds, in " + battleCount + " battles.");

}

}

// 何もしないロボット。だがプログラムを見てみると、

// 他のファイルからラウンド数とバトル数を取得し、そして更新して書き換えている。

// バトルにはむいていません。

Page 16: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

16

SpinBot package sample;

import robocode.*;

public class SpinBot extends AdvancedRobot {

public void run() {

while (true) {

setTurnRight(10000); // 右にめっさ回転する様にSet

setMaxVelocity(5); // 回転速度を5に設定。

ahead(10000); // 前にめっさ前進と同時にSetのも実行。

}

}

public void onScannedRobot(ScannedRobotEvent e) { // 敵ロボを見つけた時の行動。

fire(3); // 3の威力で攻撃。

}

public void onHitRobot(HitRobotEvent e) { // 敵ロボにぶつかった時の行動。

if (e.getBearing() > -10 && e.getBearing() < 10) // 衝突したロボットが自分の前方20度にいれば

fire(3); // 3の威力で攻撃。

if (e.isMyFault()) // 自分からぶつかったら

turnRight(10); // 10度だけ右回転。

}

}

// 基本的に回り続け敵を見つけしだい打つ。プラスぶつかった敵にも容赦ない攻撃を与える。強~イ。

Page 17: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

17

Target package sample;

import robocode.*;

public class Target extends AdvancedRobot {

int trigger; // int型の関数 trigger を作成。

public void run() {

trigger = 80; // trigger に80を設定。

// Add a custom event named "trigger hit",

// "triggerhit"という名前のカスタムイベントを加えます。

addCustomEvent( // カスタムイベントを加える。

new Condition("triggerhit") { // コンディション triggerhit を作成。

public boolean test() { // エネルギー残量を取りtriggerに設定された値以下なら真を返す。

return (getEnergy() <= trigger);

};

}

);

}

public void onCustomEvent(CustomEvent e){ // カスタムイベントが発生したときの行動。

if (e.getCondition().getName().equals("triggerhit")) {

trigger -= 20; // trigger に-20する。

out.println("Ouch, down to " + (int)(getEnergy()+.5) + " energy.");

// 自分の減ったエネルギーを表示。

turnLeft(65); // 65度左回転。

ahead(100); // 100px前進。

}

}

}

// カスタムイベントを勉強できるロボット。それなのでカス。

Page 18: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

18

Traker package sample;

import robocode.*;

public class Tracker extends Robot

{

int count = 0; // int型の関数 count を作成。0で初期化。

double gunTurnAmt; // double型の関数 gunTurnAmt を作成。

String trackName; // 現在追跡しているロボットの名前を保存するもの。

public void run() {

trackName = null; // trackNameにnullを設定。

// どのロボットも追跡していないように初期化する。

setAdjustGunForRobotTurn(true); // 回転中は大砲を静止させるようにする。

gunTurnAmt = 10; // gunTurnAmtを10に設定。

while (true) {

turnGunRight(gunTurnAmt); // gunTurnAmt分だけ砲塔を右回転。

count++; // countに++する。

if (count > 2) { // もし2ターンの間標的を見つけられなかったら

gunTurnAmt = -10; // gunTurnAmtを-10に設定。

}

if (count > 5) // もし5ターンの間標的を見つけられなかったら

gunTurnAmt = 10; // gunTurnAmtを10に設定。

if (count > 11) // もし10ターンを過ぎても標的を見つけられなかったら

trackName = null; // 別の敵ロボを探す。

}

}

public void onScannedRobot(ScannedRobotEvent e) { // 敵ロボを見つけた時の行動。

if (trackName != null && !e.getName().equals(trackName))

return;

// もし標的があって、このロボットとは別なら、

// 他ののScannedRobotEvent?を起こすようにする。

if (trackName == null) { // もし標的がなかったら

trackName = e.getName(); // このロボットを標的にする。

out.println("Tracking " + trackName); // コメントを表示。

}

count = 0; // countをリセット。

Page 19: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

19

if (e.getDistance() > 150) { // もし敵ロボが遠ければ

gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));

turnGunRight(gunTurnAmt); // 敵ロボの方向に回転する。

turnRight(e.getBearing());

ahead(e.getDistance() - 140); // 敵ロボに向かっていく。

return;

}

gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));

turnGunRight(gunTurnAmt);

fire(3); // 敵ロボが近い場合、威力3で攻撃。

if (e.getDistance() < 100) { // 敵ロボがめっさ近い場合。

if (e.getBearing() > -90 && e.getBearing() <= 90) // もし前にいたら

back(40); // 40px後進。

else // 後ろにいたら

ahead(40); //40px前進。

}

scan();

}

/**

* onHitRobot: Set him as our new target

* onHitRobot: ぶつかったロボットを新しい標的にします。

*/

public void onHitRobot(HitRobotEvent e) { // 敵ロボにぶつかった時の行動。

if (trackName != null && !trackName.equals(e.getName())) { // まだ標的がいない場合

out.println("Tracking " + e.getName() + " due to collision"); // コメントを表示。

}

trackName = e.getName(); // そのロボットを標的にする。

gunTurnAmt = normalRelativeAngle(e.getBearing() + (getHeading() - getRadarHeading()));

turnGunRight(gunTurnAmt); // gunTurnAmt分だけ砲塔を右回転。

fire(3); // 3の威力で攻撃。

back(50); // 50px後進する。

}

public void onWin(WinEvent e) { // 勝利の踊り。無くても良い。

for (int i = 0; i < 50; i++)

{

turnRight(30);

turnLeft(30);

}

}

Page 20: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

20

public double normalRelativeAngle(double angle) { // 角度を-180度から180度の範囲に直したものを返す。

if (angle > -180 && angle <= 180)

return angle;

double fixedAngle = angle;

while (fixedAngle <= -180)

fixedAngle += 360;

while (fixedAngle > 180)

fixedAngle -= 360;

return fixedAngle;

}

}

// ロボットをロックし接近する。近づいたら攻撃。タイマンには強そう。

Page 21: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

21

TrackFire package sample;

import robocode.*;

public class TrackFire extends Robot

public void run() {

while (true)

{

turnGunRight(10); // 砲塔を10度だけ右回転させる。

}

}

public void onScannedRobot(ScannedRobotEvent e) { // 敵ロボを発見した時の行動。

double absoluteBearing = getHeading() + e.getBearing();

// double型の関数 absoluteBearing を作成。

// ロボの方向と敵ロボの攻撃があたった方向をプラスしたものを設定。

double bearingFromGun = normalRelativeAngle(absoluteBearing - getGunHeading());

// double型の関数 bearingFromGun を作成。

// normalRelativeAngleより返された値を保存。

if (Math.abs(bearingFromGun) <= 3) { // もしbearingFromGunの絶対値が3以下なら

turnGunRight(bearingFromGun); // bearingFromGunの分だけ砲塔を右回転させる。

if (getGunHeat() == 0) // もし砲塔の熱さが0なら(0にならないと攻撃できない。)

fire (Math.min(3 - Math.abs(bearingFromGun),getEnergy() - .1));

// 3 - bearingFromGun と getEnergy - .1 を比較し

// どっちか小さい値の威力で攻撃。

}

else { // 他の場合。

turnGunRight(bearingFromGun); // bearingFromGunの分だけ砲塔を右回転させる。

}

if (bearingFromGun == 0) // もしbearingFromGunが0なら

scan(); // 敵を探す。

}

public void onWin(WinEvent e) { // このラウンドに勝った時の行動。

turnRight(36000); // めっさ右回転。

}

public double normalRelativeAngle(double angle) { // 角度を-180度から180度の範囲に直したものを返す。

if (angle > -180 && angle <= 180)

return angle;

double fixedAngle = angle;

while (fixedAngle <= -180)

fixedAngle += 360;

while (fixedAngle > 180)

Page 22: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

22

fixedAngle -= 360;

return fixedAngle;

}

}

// 見つけた敵ロボのうち近い奴を攻撃するロボット。

Page 23: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

23

Walls package sample;

import java.awt.Color;

import robocode.*;

public class Walls extends Robot {

boolean peek; // boolean型の変数 peek を作成。

double moveAmount; // double型の変数 moveAmount を作成。

public void run() {

setBodyColor(Color.black); // ロボの色を設定。

setGunColor(Color.black);

setRadarColor(Color.orange);

setBulletColor(Color.cyan);

setScanColor(Color.cyan);

moveAmount = Math.max(getBattleFieldWidth(), getBattleFieldHeight()); // moveAmountをバトルフィ

ールドでの最大値に設定

peek = false; // peekをfalseに設定 (false:以前の動作が保存されていたら、停止をキャ

ンセル)

turnLeft(getHeading() % 90); // ロボットの現在の向きを90度で割ったあまりの分だけ左に回転。

ahead(moveAmount); // moveAmount分だけ前進 (壁まで前進)。

peek = true; // peekをtrueに設定 (true:以前の動作が保存されていたら、上書き保存)

turnGunRight(90); // 砲塔を90度だけ右回転。

turnRight(90); // ロボを90度だけ左回転。

while (true) {

peek = true; //peekをtrueに設定。

ahead(moveAmount); //壁まで前進。

peek = false; // peekをfalseに設定。

turnRight(90); // ロボを右に90度だけ回転。

}

}

public void onHitRobot(HitRobotEvent e) { // ロボが敵ロボにぶつかった時の行動。

if (e.getBearing() > -90 && e.getBearing() < 90) { // もし衝突した敵ロボが-90°~ 90°にいるなら

back(100); // 100pxだけ後退。

}

else { // 他の場合。

ahead(100); // 100pxだけ前進。

}

}

Page 24: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

24

public void onScannedRobot(ScannedRobotEvent e) { //敵ロボを発見した時の行動。

fire(2); // 2の威力で攻撃

if (peek) {

scan(); // もしpeekがtrueなら敵ロボを探す。

}

}

}

// 隅に引っ付きグルグル回るロボット。多分1番強い。

Page 25: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

25

[2]各ロボット同士のタイマンによる結果

Cor Cra Fir Int Ram Sit Spi Tar Tra TrF Wal

Cor Non ● ● ○ ○ ○ ● ○ ● ● ●

Cra ○ Non ○ ○ ● ○ ● ○ ● ● ●

Fir ○ ● Non ○ ○ ○ ● ○ ● ● ●

Int ● ● ● Non ● ○ ● ○ ● ● ●

Ram ● ○ ● ○ Non ○ ● ○ ● ● ●

Sit ● ● ● ● ● Non ● ○ ● ● ●

Spi ○ ○ ○ ○ ○ ○ Non ○ ○ ○ ●

Tar ● ● ● ● ● ● ● Non ● ● ●

Tra ○ ○ ○ ○ ○ ○ ● ○ non ● ●

TrF ○ ○ ○ ○ ○ ○ ● ○ ● non ●

Wal ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ non

対戦の条件 : (1) 1 対 1

(2) 5ラウンド

(3) Interctiveは自分で操作。

(4) 戦場は 800×600

表の見方は行のロボットを主として見る。○ = 勝ち ● = 敗け

【考察】

Corner - 止まっているロボットには強いが、動いている敵に対しては弱い。

Crazy - めっちゃ動いているので止まってスキャンしてくる敵の攻撃はあまり当たらない。

追っかけてくるロボットには弱い。

Fire - 止まってグルグルスキャンして攻撃するのみなので、Corner等にしか勝てない。

Interactive - 操縦者がクソだったので、ほとんど負けw 操作がうまくなれば無敵かも。

RamFire - 敵を追っかけていくのでCrazyにかなり有効。それ以外の敵には攻撃の威力で負ける。

SittingDuck - 何もしないので弱い。

SpinBot - 追っかけてくるRamFireには苦戦。しかし攻撃の威力が強いためかなり上位にいる。

Target - 何もしないので弱い。

Tracker - 追っかけていって攻撃も強いので止まってる敵にはめっぽう強い。

動く敵にもまぁまぁ対応できるが、速いと全然ダメ。

TrackFire - 基本タイマンには強い。攻撃の威力が強いし、スキャンが速いため。

が、同じ動きを繰り返す敵には苦戦する。攻撃が追いつかないためだな。

Walls - 最強でした。まず敵の攻撃が当たらない。それでいて中心にスキャンをかけて

攻撃するのみなので体力もへらんし、攻撃の当たる範囲も大きい。

Page 26: プログラミング2 【ロボコード】e075713/reports/prog2-2.pdf · 2007. 11. 29. · 9. Tracker ・・・ 18 ̃ 20 P 10.TrackFire ・・・ 21 ̃ 22 P 11.Walls ・・・ 23

26

[3]感想

JAVAのことを楽しみながら勉強できた。

この課題をやっていると色々できそうだなぁと考えてしまう。

面白かった~。

参考HP

Robocode(ロボコード)日本語ドキュメント URL : http://www.geocities.co.jp/SiliconValley/9155/

Robocode API詳細解説 URL : http://www.yuge.ac.jp/home/̃nagao/teaching/RoboCode/docs/detail_API/index.html