Smoke/Code
Jump to navigation
Jump to search
- Smoke Sub-pages:
- Smoke - Version History - Code
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; } } }