Module/Movement/Random

From Robowiki
< Module‎ | Movement
Revision as of 09:29, 1 July 2010 by RednaxelaBot (talk | contribs) (Using <syntaxhighlight>.)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
package jab.movement;

import java.awt.geom.Point2D;
import java.awt.geom.RoundRectangle2D;

import robocode.util.Utils;

import jab.Module;
import jab.Movement;


/**
 * Credits
 * This code is released under the RoboWiki Public Code License (RWPCL),
 * RandomMovementBot, by PEZ. Demonstrating a simple, extensible
 * way to go about random 1v1 movement.
 */
public class Random extends Movement {

	public Random(Module bot) {
		super(bot);
	}

	private static final double MAX_VELOCITY = 8;
	private static final double WALL_MARGIN = 25;
	private double movementLateralAngle = 0.2;

	public void move() {
		considerChangingDirection();
		Point2D robotDestination = null;
		double tries = 0;
		do {
			robotDestination = vectorToLocation(absoluteBearing(
					new Point2D.Double(bot.enemy.x, bot.enemy.y),
					new Point2D.Double(bot.getX(), bot.getY()))
					+ movementLateralAngle, bot.enemy.distance
					* (1.1 - tries / 100.0), new Point2D.Double(bot.enemy.x,
					bot.enemy.y));
			tries++;
		} while (tries < 100
				&& !fieldRectangle(WALL_MARGIN).contains(robotDestination));
		goTo(robotDestination);
	}

	private void considerChangingDirection() {
		// Change lateral direction at random
		// Tweak this to go for flat movement
		double flattenerFactor = 0.05;
		if (Math.random() < flattenerFactor) {
			movementLateralAngle *= -1;
		}
	}

	private RoundRectangle2D fieldRectangle(double margin) {
		return new RoundRectangle2D.Double(margin, margin, bot
				.getBattleFieldWidth()
				- margin * 2, bot.getBattleFieldHeight() - margin * 2, 75, 75);
	}

	private void goTo(Point2D destination) {
		double angle = Utils.normalRelativeAngle(absoluteBearing(
				new Point2D.Double(bot.getX(), bot.getY()), destination)
				- bot.getHeadingRadians());
		double turnAngle = Math.atan(Math.tan(angle));
		bot.setTurnRightRadians(turnAngle);
		bot.setAhead(new Point2D.Double(bot.getX(), bot.getY())
				.distance(destination)
				* (angle == turnAngle ? 1 : -1));
		// Hit the brake pedal hard if we need to turn sharply
		bot.setMaxVelocity(Math.abs(bot.getTurnRemaining()) > 33 ? 0
				: MAX_VELOCITY);
	}

	private static Point2D vectorToLocation(double angle, double length,
			Point2D sourceLocation) {
		return vectorToLocation(angle, length, sourceLocation,
				new Point2D.Double());
	}

	private static Point2D vectorToLocation(double angle, double length,
			Point2D sourceLocation, Point2D targetLocation) {
		targetLocation.setLocation(sourceLocation.getX() + Math.sin(angle)
				* length, sourceLocation.getY() + Math.cos(angle) * length);
		return targetLocation;
	}

	private static double absoluteBearing(Point2D source, Point2D target) {
		return Math.atan2(target.getX() - source.getX(), target.getY()
				- source.getY());
	}

}