|
|
Line 1: |
Line 1: |
− | {{Navbox small
| |
− | | title = Smoke Sub-pages
| |
− | | parent = Smoke
| |
− | | page1 = Version History
| |
− | | page2 = Code
| |
− | }}
| |
− | ----
| |
− | <syntaxhighlight>
| |
− | 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;
| |
− | }
| |
− | }
| |
− |
| |
− | }
| |
− | </syntaxhighlight>
| |
− | [[Category:Source Code]]
| |