Sabreur/Code

From Robowiki
Jump to navigation Jump to search
/*
Sabreur v1.1.2 by Sheldor.  05/27/2013
A NanoBot with multimode movement and linear targeting.
Codesize: 245 Bytes with three colors.

Sabre is one of the three forms of modern sport fencing,
along with Epee and Foil.  http://en.wikipedia.org/wiki/Sabre_%28fencing%29

Credits:
Thanks go to the authors of the following bots: 
oog.nano.Caligula, mz.NanoDeath, dz.MostlyHarmlessNano, gh.micro.GrubbmThree.
Also, a general thanks to all open source bot authors and contributors to the RoboWiki.

Sabreur is open source and released under the terms of the RoboWiki Public Code License (RWPCL) - Version 1.1.
see license here: http://robowiki.net/wiki/RWPCL
*/

package sheldor.nano;

import robocode.*;
import robocode.util.Utils;
import java.awt.Color;

public class Sabreur extends AdvancedRobot
{
	//Global variables
	static double direction;
	static double enemyEnergy;
	static int    deathCount;
		
	//En garde!
	public void run()
	{
		//Set the bot's colors.
		setColors(Color.white, Color.black, Color.white);
		
		//Start spinning radar and initialize movement direction.
		setTurnRadarRightRadians(direction = 100000);
	}

	public void onScannedRobot(ScannedRobotEvent e)
	{
		//Local variables
		double absoluteBearing;
		double bearing;
		double lead;	
		
		//Linear targeting
		setTurnGunRightRadians(Utils.normalRelativeAngle((absoluteBearing = getHeadingRadians() + (bearing = e.getBearingRadians())) +
			(lead = Math.asin(e.getVelocity() / 14 * Math.sin(e.getHeadingRadians() - absoluteBearing))) - getGunHeadingRadians()));
								
		//One-way orbit/Oscillating movement
		//These modes alternate when the bot dies.
		if(enemyEnergy > (enemyEnergy = e.getEnergy()) && (deathCount % 2) != 0)
		{
			onHitWall(null);
		}
		setAhead(direction);
		
		//Stay mostly perpendicular to the enemy, but try to maintain a distance of 160 pixels.
		//The absolute bearing variable is re-used here to represent the enemy distance.  This saves one byte.
		setTurnRightRadians(Math.cos(bearing - ((absoluteBearing = e.getDistance()) - 160) * (direction / 35000000)));
				
		//If the bot has died more than four times in the first twelve rounds, switch to ramming the enemy.
		//Notice that I use the same linear lead for ramming as I use in the gun code.
		if (deathCount > 3)
		{
			setTurnRightRadians(Math.tan(bearing += lead));
			setAhead(Math.cos(bearing) / 0);
		}
		
		//Fire medium power bullets most of the time, but use full power at very close range.
		//If the enemy is weak, fire the minimum power needed to destroy them.
		setFire(Math.min(2 + (100 / (int)absoluteBearing), enemyEnergy / 4));
	
		//Pseudo-infinite radar lock
		setTurnRadarLeftRadians(getRadarTurnRemaining());
	}

	public void onBulletHit (BulletHitEvent e)
	{
		//Adjust enemy energy variable when the bot hits the enemy.
		//This makes a big difference against linear targeting.
		enemyEnergy -= 10;
	}

	public void onDeath(DeathEvent e)
	{
		//If the bot dies in the first twelve rounds, increment the deathCount variable.
		if (getRoundNum() < 12)
		{
			deathCount++;
		}
	}
	
	public void onHitWall(HitWallEvent e)
	{
		//Reverse movement direction when the bot hits a wall.
		direction = -direction;
	}
}