Smoke/Code
< Smoke
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;
}
}
}