Robocode

Aprendendo a guerrear em java

PET Teleinformática @ 2015

http://www.peteti.ufc.br

Agenda

  • zz

Indo além de simples robôs

  • Robôs basicos
public class Freyja extends Robot {
  • Robôs avançados
public class Freyja extends AdvancedRobot {

Indo além de simples robôs

Realizando Ações Simultâneas

  • AdvancedRobot
  • Possibilidade de realizar ações em cada turno
  • Blocking Methods não nos dá o poder de controlar
  • Turno no robocode é chamado de pulso
  • Note que AdvancedRobot é na verdade uma subclasse de Robot

Realizando Ações Simultâneas

  • E como controlamos o robô durante um pulso?
  • Primeiro, devemos realizar que todos os métodos utilizados até agora são Blocking Methods
  • Agora, como Freyja é uma subclasse de AdvancedRobot 
    nós podemos utilizar os novos tipos de métodos, os 
    Non-Blocking

Realizando Ações Simultâneas

Realizando Ações Simultâneas

public class Freyja extends AdvancedRobot {

        ...
        public void run() {
        ...
            setTurnRight(fullTurn);
            setAhead(veryFar);
            setTurnGunLeft(fullTurn);
        }

Realizando Ações Simultâneas

  • Non-Blocking Methods não retornam o poder para o Robocode
  • Necessidade de um blocking-method ou execute()

Realizando Ações Simultâneas

public class Freyja extends AdvancedRobot {

        ...
        public void run() {
        ...
            setTurnRight(fullTurn);
            setAhead(veryFar);
            setTurnGunLeft(fullTurn);
            execute()
        }

Realizando Ações Simultâneas

public class Freyja extends AdvancedRobot {

      ...
      public void run() {
      ...
          while(true) {
             waitFor(new TurnCompleteCondition(this));
             toggleDirection();
          }
      }

Realizando Ações Simultâneas

public class Freyja extends AdvancedRobot {

   private void toggleDirection() {
     if (clockwise) {
       setTurnLeft(fullTurn);
       setBack(veryFar);
       setTurnGunRight(fullTurn);
     } else {
       setTurnRight(fullTurn);
       setAhead(veryFar);
       setTurnGunLeft(fullTurn);
     }
       clockwise = ! clockwise;
   }

Eventos Customizados

  • Observações:
  1. heading : ângulo absoluto com 0º apontado para cima   0 <= heading <= 360
  2. bearing: ângulo relativo à algum objeto que o robô está observando ~ -180 <= bearing <= 180
  3. Todas as coordenadas são expressas em (x,y)
  4. Todas as coordenadas são positivas
  5. A origem (0,0) é no canto inferior esquerdo
  6. X é positivo para direita
  7. Y é positivo para cima

Eventos Customizados

  • Exemplo:
public void onHitByBullet (HitByBulletEvent e) {
    turnLeft(90 - e.getBearing());
}
  • Acesso à documentação:
  • Help -> Robocode API

Eventos Customizados

  • Eventos conhecidos:
  • onBulletHit()
  • onBulletHitBullet()
  • onBulletMissed()
  • onDeath()
  • onHitByBullet()
  • onHitWall()
  • onRobotDeath()
  • onScannedRobot()
  • onWin()

Eventos Customizados

  • centerRobot()
public void onHitWall(HitWallEvent ev) {
    centerRobot();
}

private void centerRobot() {
    double width, height, x, y;

    height= this.getBattleFieldHeight();
    width = this.getBattleFieldWidth();
    y = this.getY();
    x = this.getX();
    if (x > width/2)
      turnRight(threeQuarterTurn - getHeading());
    else
      turnRight(quarterTurn - getHeading());
    ahead(Math.abs(width/2 - x));
    if (y < height/2)
      turnLeft(getHeading());
    else
      turnRight(halfTurn - getHeading());
    ahead(Math.abs(height/2 - y));
}

Localização do Alvo

  • Os  três principais novos recursos providos por AdvancedRobot são:
  • Carregar múltiplos movimentos simultaneamente
  • Decidir a ação do robô ou estratégia em tempo real
  • Definir e lidar com eventos customizados

Interfaces e Classes Internas

Localização do Alvo

Interfaces e Classes Internas

public class DuckSeekerBot extends AdvancedRobot implements DuckConstants
{
    boolean targetLocked = false;
    Target curTarget = null;

	public void run() {

	  setColors(Color.red,Color.green,Color.red);
          setTurnRadarRight(oneRev);

	  while(true) {
            if (curTarget != null) {
              if (curTarget.isAlive() && curTarget.isLocked()) {
                fire(2);
              }
            }
          execute();
       }
}

Localização do Alvo

Interfaces e Classes Internas

class Target {
  ...
  public Target(String inname, boolean inalive, boolean inlocked) {
  ...
   }
  public boolean isAlive() {
  ...
   }
  public boolean isLocked() {
   ...
   }
  ...
}

Localização do Alvo

Interfaces e Classes Internas

stop();
    turnRight(evt.getBearing());
    if (evt.getDistance() > safeDistance)
      ahead(evt.getDistance() - safeDistance);
    if(curTarget != null) {
       if (curTarget.getName().equals(evt.getName()))
          return;
    }
    curTarget = new Target(evt.getName(), true, true);

Localização do Alvo

Interfaces e Classes Internas

class Target {
  private String name = null;
  private  boolean locked = false;
  private  boolean alive = false;
  public Target(String inname, boolean inalive, boolean inlocked) {
     setName(inname);
     setAlive(inalive);
     setLocked(inlocked);
  }
  public boolean isAlive() {
     return alive;
  }
  public boolean isLocked() {
     return locked;
  }
  public void setAlive( boolean inalive) {
     alive = inalive;
     }
     public void setLocked( boolean inlocked) {
      locked = inlocked;
      }
      public String getName() {
      return name;
      }
      public void setName(String inName) {
      name = inName;
      }
      }

}

Robôs Já Conhecidos

Crazy

public class Crazy extends AdvancedRobot {
	boolean movingForward;

	public void run() {
		// Set colors
		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));

		// Loop forever
		while (true) {
			// Tell the game we will want to move ahead 40000 -- some large number
			setAhead(40000);
			movingForward = true;
			// Tell the game we will want to turn right 90
			setTurnRight(90);
			waitFor(new TurnCompleteCondition(this));
			// Note:  We are still moving ahead now, but the turn is complete.
			// Now we'll turn the other way...
			setTurnLeft(180);
			// ... and wait for the turn to finish ...
			waitFor(new TurnCompleteCondition(this));
			// ... then the other way ...
			setTurnRight(180);
			// .. and wait for that turn to finish.
			waitFor(new TurnCompleteCondition(this));
			// then back to the top to do it all again
		}
	}

Robôs Já Conhecidos

Crazy

	public void onHitWall(HitWallEvent e) {
		// Bounce off!
		reverseDirection();
	}

	/**
	 * reverseDirection:  Switch from ahead to back & vice versa
	 */
	public void reverseDirection() {
		if (movingForward) {
			setBack(40000);
			movingForward = false;
		} else {
			setAhead(40000);
			movingForward = true;
		}
	}

	public void onScannedRobot(ScannedRobotEvent e) {
		fire(1);
	}

	public void onHitRobot(HitRobotEvent e) {
		// If we're moving the other robot, reverse!
		if (e.isMyFault()) {
			reverseDirection();
		}
	}
}

Robôs Já Conhecidos

Walls

public class Walls extends Robot {

	boolean peek; // Don't turn if there's a robot there
	double moveAmount; // How much to move

	/**
	 * run: Move around the walls
	 */
	public void run() {
		...

Robôs Já Conhecidos

Walls

	public void run() {
		// Set colors
		setBodyColor(Color.black);
		setGunColor(Color.black);
		setRadarColor(Color.orange);
		setBulletColor(Color.cyan);
		setScanColor(Color.cyan);

		// Initialize moveAmount to the maximum possible for this battlefield.
		moveAmount = Math.max(getBattleFieldWidth(), getBattleFieldHeight());
		// Initialize peek to false
		peek = false;

		// turnLeft to face a wall.
		// getHeading() % 90 means the remainder of
		// getHeading() divided by 90.
		turnLeft(getHeading() % 90);
		ahead(moveAmount);
		// Turn the gun to turn right 90 degrees.
		peek = true;
		turnGunRight(90);
		turnRight(90);

		while (true) {
			// Look before we turn when ahead() completes.
			peek = true;
			// Move up the wall
			ahead(moveAmount);
			// Don't look now
			peek = false;
			// Turn to the next wall
			turnRight(90);
		}
	}

Robôs Já Conhecidos

Walls

	public void onHitRobot(HitRobotEvent e) {
		// If he's in front of us, set back up a bit.
		if (e.getBearing() > -90 && e.getBearing() < 90) {
			back(100);
		} // else he's in back of us, so set ahead a bit.
		else {
			ahead(100);
		}
	}

	public void onScannedRobot(ScannedRobotEvent e) {
		fire(2);
		// Note that scan is called automatically when the robot is moving.
		// By calling it manually here, we make sure we generate another scan event if there's a robot on the next
		// wall, so that we do not start moving up it until it's gone.
		if (peek) {
			scan();
		}
	}
}

Robôs Já Conhecidos

Tracker

public class Tracker extends Robot {
	int count = 0; // Keeps track of how long we've
	// been searching for our target
	double gunTurnAmt; // How much to turn our gun when searching
	String trackName; // Name of the robot we're currently tracking

	public void run() {
		...

Robôs Já Conhecidos

Tracker

public void run() {
		// Set colors
		setBodyColor(new Color(128, 128, 50));
		setGunColor(new Color(50, 50, 20));
		setRadarColor(new Color(200, 200, 70));
		setScanColor(Color.white);
		setBulletColor(Color.blue);

		// Prepare gun
		trackName = null; // Initialize to not tracking anyone
		setAdjustGunForRobotTurn(true); // Keep the gun still when we turn
		gunTurnAmt = 10; // Initialize gunTurn to 10

		// Loop forever
		while (true) {
			// turn the Gun (looks for enemy)
			turnGunRight(gunTurnAmt);
			// Keep track of how long we've been looking
			count++;
			// If we've haven't seen our target for 2 turns, look left
			if (count > 2) {
				gunTurnAmt = -10;
			}
			// If we still haven't seen our target for 5 turns, look right
			if (count > 5) {
				gunTurnAmt = 10;
			}
			// If we *still* haven't seen our target after 10 turns, find another target
			if (count > 11) {
				trackName = null;
			}
		}
	}

Robôs Já Conhecidos

Tracker

	public void onScannedRobot(ScannedRobotEvent e) {

		// If we have a target, and this isn't it, return immediately
		// so we can get more ScannedRobotEvents.
		if (trackName != null && !e.getName().equals(trackName)) {
			return;
		}

		// If we don't have a target, well, now we do!
		if (trackName == null) {
			trackName = e.getName();
			out.println("Tracking " + trackName);
		}
		// This is our target.  Reset count (see the run method)
		count = 0;
		// If our target is too far away, turn and move toward it.
		if (e.getDistance() > 150) {
			gunTurnAmt = normalRelativeAngleDegrees(e.getBearing() + (getHeading() - getRadarHeading()));

			turnGunRight(gunTurnAmt); // Try changing these to setTurnGunRight,
			turnRight(e.getBearing()); // and see how much Tracker improves...
			// (you'll have to make Tracker an AdvancedRobot)
			ahead(e.getDistance() - 140);
			return;
		}

		// Our target is close.
		gunTurnAmt = normalRelativeAngleDegrees(e.getBearing() + (getHeading() - getRadarHeading()));
		turnGunRight(gunTurnAmt);
		fire(3);

		// Our target is too close!  Back up.
		if (e.getDistance() < 100) {
			if (e.getBearing() > -90 && e.getBearing() <= 90) {
				back(40);
			} else {
				ahead(40);
			}
		}
		scan();
	}

Robôs Já Conhecidos

Tracker

	public void onHitRobot(HitRobotEvent e) {
		// Only print if he's not already our target.
		if (trackName != null && !trackName.equals(e.getName())) {
			out.println("Tracking " + e.getName() + " due to collision");
		}
		// Set the target
		trackName = e.getName();
		// Back up a bit.
		// Note:  We won't get scan events while we're doing this!
		// An AdvancedRobot might use setBack(); execute();
		gunTurnAmt = normalRelativeAngleDegrees(e.getBearing() + (getHeading() - getRadarHeading()));
		turnGunRight(gunTurnAmt);
		fire(3);
		back(50);
	}

Robôs Já Conhecidos

Corners

public class Corners extends Robot {
	int others; // Number of other robots in the game
	static int corner = 0; // Which corner we are currently using
	// static so that it keeps it between rounds.
	boolean stopWhenSeeRobot = false; // See goCorner()

	public void run() {

		// Save # of other bots
		others = getOthers();

		// Move to a corner
		goCorner();

		// Initialize gun turn speed to 3
		int gunIncrement = 3;

		// Spin gun back and forth
		while (true) {
			for (int i = 0; i < 30; i++) {
				turnGunLeft(gunIncrement);
			}
			gunIncrement *= -1;
		}
	}

Robôs Já Conhecidos

Corners

	/**
	 * goCorner:  A very inefficient way to get to a corner.  Can you do better?
	 */
	public void goCorner() {
		// We don't want to stop when we're just turning...
		stopWhenSeeRobot = false;
		// turn to face the wall to the "right" of our desired corner.
		turnRight(normalRelativeAngleDegrees(corner - getHeading()));
		// Ok, now we don't want to crash into any robot in our way...
		stopWhenSeeRobot = true;
		// Move to that wall
		ahead(5000);
		// Turn to face the corner
		turnLeft(90);
		// Move to the corner
		ahead(5000);
		// Turn gun to starting point
		turnGunLeft(90);
	}

Robôs Já Conhecidos

Corners

	public void onScannedRobot(ScannedRobotEvent e) {
		// Should we stop, or just fire?
		if (stopWhenSeeRobot) {
			// Stop everything!  You can safely call stop multiple times.
			stop();
			// Call our custom firing method
			smartFire(e.getDistance());
			// Look for another robot.
			// NOTE:  If you call scan() inside onScannedRobot, and it sees a robot,
			// the game will interrupt the event handler and start it over
			scan();
			// We won't get here if we saw another robot.
			// Okay, we didn't see another robot... start moving or turning again.
			resume();
		} else {
			smartFire(e.getDistance());
		}
	}

	/**
	 * smartFire:  Custom fire method that determines firepower based on distance.
	 *
	 * @param robotDistance the distance to the robot to fire at
	 */
	public void smartFire(double robotDistance) {
		if (robotDistance > 200 || getEnergy() < 15) {
			fire(1);
		} else if (robotDistance > 50) {
			fire(2);
		} else {
			fire(3);
		}
	}

}

Robocode @ 2015 (#001)

By Alexandre Barroso

Robocode @ 2015 (#001)

[AVANÇADO] --

  • 712