[Home]Smoke/Source

Robo Home | Smoke | Changes | Preferences | AllPages

Difference (from prior major revision) (no other diffs)

Changed: 276c276,278
PEZ was right, and i don't care whether waves(j) have hit the opponent, i just care waves(i). Do you know my meanning? I just need waves(j)'s compareValue, and compareValue is not relative to whether it have hit opponent, but startPosition does.(startPosition.x was the hit angle when the wave have hit opponent) -- iiley
PEZ was right, and i don't care whether waves(j) have hit the opponent, i just care waves(i). Do you know my meanning? I just need waves(j)'s compareValue, and compareValue is not relative to whether it have hit opponent, but startPosition does.(startPosition.x was the hit angle when the wave have hit opponent) -- iiley

ok, so the 71 is optimised/fixed for standard RR battles. As 0 <= j <= 70, i-j are always 'older' waves which must have past the opponent. I will rewrite this code in Mega bot size ;) without all the reuse of variables, just for my own understanding. --Loki


package cx.micro;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import robocode.AdvancedRobot;
import robocode.Condition;
import robocode.DeathEvent;
import robocode.ScannedRobotEvent;
import robocode.util.Utils;
/**
 *-----------------------------------------------------------------
 * @author:iiley (iiley@hotmail.com)
 * http://www.robochina.org
 * Smoke:use MicroWave to do pattern analyzer and random movement
 *--------------------version 0.5 2003.1.5--------------
 * 0.5:Can only fire 3 power because MicroWave,so may west much power.(codesize 737)
 *--------------------version 0.55 2003.1.5--------------               
 * 0.55:improved movement a little.(codesize 749)
 *--------------------version 0.60 2003.1.8--------------
 * 0.60:changed a movement.it does better.(codesize 748)
 *--------------------version 0.70 2003.1.25-------------
 * 0.70:changed a movement similar to the new verion of Cigaret. (codesize 742)
 *--------------------version 0.80 2003.2.3-------------
 * 0.80:Squeezed much(MicroWave squeezed too) so added some in aim. (codesize 749)
 *--------------------version 0.82 2003.2.5-------------
 * 0.82:Squeezed again,added a judge to aim prediction points only in battle feild.
 *      and can set one color now(but have not set).(codesize 740)
  *--------------------version 0.91 2003.7.12-------------
 * 0.91:Squeezed again,tweaked movement as experience from Spark.(codesize 742)
  *--------------------version 0.95 2003.9.12-------------
 * 0.95:Squeezed again,can fire different power bullet and can fight in different battle fileds now.(codesize 748)
  *--------------------version 0.96 2004.10.24-------------
 * 0.96:Squeezed again,then add a trick to HOT bot, tweaked a little.(codesize 748)
 *-------------------------------------------------------
 * future:Squeeze so that i can do more and get my whole colors back.
 */
public class Smoke extends AdvancedRobot {
	
	private static final double BATTLE_WIDTH = 800;
	private static final double BATTLE_HEIGHT = 600;

	/**
	 * my usual fire power
	 */
	private static final double POWER = 3d;
	private static final double BULLET_VELOCITY = 20d - 3d * POWER;

	/**
	 * ESCPAE_ANGLE should be Math.asin(8/(enemy_bullet_velocity))*2; if enemy
	 * fire 3 power bullet, it should be 1.6286798842530508 but here i use 1.5
	 */
	private static final double ESCPAE_ANGLE = 1.5;

	private static ArrayList waves = new ArrayList();
	
	private static double enemyEnergy;

	/**
	 * a trick to HOT, first it be 0, see the movement, it just move + dirction
	 * It is not very useful i am thinking to remove it next version
	 */
	private static double HOT_Trick;

	/**
	 * enemy's current position
	 */
	private static Point2D.Double enemyPosition;

	public void run() {

		setAdjustGunForRobotTurn(true);
		setAdjustRadarForGunTurn(true);

		do {
			turnRadarRightRadians(1);
		} while (true);
	}

	/**
	 * when i am dead, i think enemy is not a HOT bot, so i will only move one
	 * direction
	 */
	public void onDeath(DeathEvent event) {
		HOT_Trick = ESCPAE_ANGLE / 2;
	}

	// -------------------- function for event handle ---------------
	public void onScannedRobot(ScannedRobotEvent e) {
		double absBearing;
		double distanceToEnemy;
		double moveDistance;
		double moveAngle;
		Point2D.Double myPosition;

		enemyPosition = nextPoint(myPosition = new Point2D.Double(getX(),
				getY()), absBearing = e.getBearingRadians()
				+ getHeadingRadians(), moveDistance = distanceToEnemy = e
				.getDistance());
		// Radar turn grabed from David Alves.
		setTurnRadarRightRadians(Math
				.sin(absBearing - getRadarHeadingRadians()));

		//fire
		double power = Math.min(POWER, enemyEnergy / 5d);
		if (getEnergy() > power)
			setFire(power);

		//--------------movement---------------------

		//if enemy fired, and my last move will finish, start a new move
		if (enemyEnergy != (enemyEnergy = e.getEnergy())
				&& Math.abs(getDistanceRemaining()) < 53d) {
			Point2D.Double destination;

			//random find a destination, random for the hit angle
			while (distanceToWall(destination = nextPoint(enemyPosition,
					absBearing
							+ (moveAngle = Math.random() * ESCPAE_ANGLE
									- HOT_Trick), -(moveDistance -= 10d)
							/ Math.cos(moveAngle))) < 24d);
			//thanks to David Alves and Dummy for this small code to find which
			// direction is shortest to our next destination
			//Thanx DrLoco of this usage
			//set move to the destination
			setAhead(((moveAngle = Utils.normalRelativeAngle(getAngle(
					destination, myPosition)
					- getHeadingRadians())) == (moveDistance = Math.atan(Math
					.tan(moveAngle))) ? 1 : -1)
					* myPosition.distance(destination)); //move towards point
			setTurnRightRadians(moveDistance);
		}

		//-----------------pattern analyser--------------------
		int size;
		size = waves.size();

		MicroWave wave;
		waves.add(wave = new MicroWave());
		wave.absBearing = moveDistance = absBearing;
		
		//patterns into compareValue, compareValue.x be the distance,
		// compareValue.y be the lateralVelocity
		wave.compareValue = new Point2D.Double(distanceToEnemy / 64d, e
				.getVelocity()
				* Math.sin(e.getHeadingRadians() - absBearing));
		wave.startPosition = myPosition;

		addCustomEvent(wave);

		if (getGunHeat() < 0.4d) {
			//pattern analyser, find the most matching pattern
			//seach rang is from 4500 before to current
			for (int i = Math.max(71, size - 4500); i < size; i++) {
				//is a hitted wave
				if ((wave = (MicroWave) waves.get(i)).startPosition.x < 10) {
					int j = 0;
					double div = 0;
					double comVal = 0;
					//compare 10 waves step 7.
					do {
						comVal += ((MicroWave) waves.get(size - j)).compareValue
								.distanceSq(((MicroWave) waves.get(i - j)).compareValue)
								/ (div = div * 2 + 1);
					} while ((j += 7) < 71);

					//find the most matched wave,distanceToEnemy is matchValue now
					if (comVal <= distanceToEnemy 
							&& distanceToWall(nextPoint(
									myPosition,
									moveAngle = absBearing
											+ Math.asin(Math.sin(wave.startPosition.x) / ((20d - power * 3d) / BULLET_VELOCITY)),
									wave.startPosition.y)) > 17) {
						//record the hit angle
						//moveDistance is shoot bearing now,distanceToEnemy is matchValue now
						moveDistance = moveAngle;
						distanceToEnemy = comVal;
					}
				}
			}
		}
		//turn gun
		setTurnGunLeftRadians(Utils.normalRelativeAngle(getGunHeadingRadians()
				- moveDistance));

		scan();
	}

	/**
	 * return the next point from originPoint's certain angle certan distance
	 */
	public static Point2D.Double nextPoint(Point2D.Double originPoint, double angle, double distance) {
		return new Point2D.Double(originPoint.x + Math.sin(angle) * distance,
				originPoint.y + Math.cos(angle) * distance);
	}

	/**
	 * return the angle from p1 to p2
	 */
	public static double getAngle(Point2D.Double p2, Point2D.Double p1) {
		return Math.atan2(p2.x - p1.x, p2.y - p1.y);
	}

	public static double distanceToWall(Point2D.Double p) {
		return Math.min(Math.min(p.x, BATTLE_WIDTH - p.x), Math.min(p.y, BATTLE_HEIGHT - p.y));
	}

	class MicroWave extends Condition {
		//-------comparable varialbles
		Point2D.Double compareValue;

		/**
		 * when wave started, this is the start position but after the wave hit
		 * enemy, this is the hit angle and hit distance
		 */
		Point2D.Double startPosition;

		double absBearing;

		double traveledDistance;

		public boolean test() {
			traveledDistance += BULLET_VELOCITY;

			//if the wave hit the enemy
			//when the wave hit enemy, record the angle and the distance into
			// startPosition
			if (traveledDistance > enemyPosition.distance(startPosition) - 18) {
				startPosition = new Point2D.Double(getAngle(enemyPosition, startPosition) - absBearing,
						traveledDistance);
				removeCustomEvent(this);
			}
			return false;
		}
	}

}


iiley, two questions:
1) why do you compare waves that are separated by '7' in your 'wavelist'? Is this the result of an empirical test?
2) how are you certain that the waves you compare with also have hit?
Thanks! --Loki

for questions 1: Yes it is a empirical test, but i still have a reason, a bot want to accclerate to max velocity must need 8 ticks, In old version Smoke, I use 8, but then i use 7 for careful pattern(I think less than 8 should be alright).
for questions 2: Sorry that i don't understand you from my English, It's a long complex sentence, can you split the sentence for me ~:} Oh, just so sorry.

-- iiley

For questions 2: I am guessing are you talking about this:

 				//is a hitted wave
				if ((wave = (MicroWave) waves.get(i)).startPosition.x < 10) {
-- iiley

Hi iiley, please don't apologise for your English, i think it's a problem of my english! In my second question i was referring to this part

						comVal += ((MicroWave) waves.get(size - j)).compareValue
								.distanceSq(((MicroWave) waves.get(i - j)).compareValue)
								/ (div = div * 2 + 1);
You compare wave(i) with other waves(j). How do you know these waves(j) have hit the opponent? I think if they have not hit, your calculation of the best value goes wrong. Because the values of compareValue for these waves that have not hit are meaningless as they still contain the initial values. Or do i understand this part wrong? --Loki

comVal is incremented inside this loop:

			for (int i = Math.max(71, size - 4500); i < size; i++) {
In a 800x600 battle field any wave has hit after 71 ticks.

-- PEZ

PEZ was right, and i don't care whether waves(j) have hit the opponent, i just care waves(i). Do you know my meanning? I just need waves(j)'s compareValue, and compareValue is not relative to whether it have hit opponent, but startPosition does.(startPosition.x was the hit angle when the wave have hit opponent) -- iiley

ok, so the 71 is optimised/fixed for standard RR battles. As 0 <= j <= 70, i-j are always 'older' waves which must have past the opponent. I will rewrite this code in Mega bot size ;) without all the reuse of variables, just for my own understanding. --Loki


Robo Home | Smoke | Changes | Preferences | AllPages
Edit text of this page | View other revisions
Last edited October 28, 2004 14:18 EST by Loki (diff)
Search: