Difference between revisions of "Enemy Dodging Movement"
Jump to navigation
Jump to search
(Movement method description) |
(use <syntaxhighlight>) |
||
(One intermediate revision by one other user not shown) | |||
Line 1: | Line 1: | ||
− | |||
A method for avoiding collisions with enemies. | A method for avoiding collisions with enemies. | ||
− | == How it | + | == How's it work? == |
− | General idea is: in Enemy Dodging Movement (EDM) you're | + | General idea is: in Enemy Dodging Movement (EDM), you're generating set of points around your robot, calculate average distance to enemies for each point and go to point with minimal value. |
=== Graphical demonstration === | === Graphical demonstration === | ||
− | [[File: | + | [[File:Edm demo.GIF]] |
− | + | ; red squares | |
− | + | : known enemies positions | |
− | + | ; blue circle | |
− | + | : danger area (enemies outside this area are ignored) | |
− | + | ; red/white points around the EDMRobot | |
− | + | : destination point set. White points is good, red is bad. | |
+ | ; bold white point | ||
+ | : destination point, i.e. the point which is the furthest from enemies in the blue circle. | ||
=== Implementation === | === Implementation === | ||
− | < | + | <syntaxhighlight> |
/** | /** | ||
* This class is implement Enemy dodging movement method | * This class is implement Enemy dodging movement method | ||
Line 152: | Line 153: | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
− | < | + | <syntaxhighlight> |
/** | /** | ||
* Class to represent Point in EDM method. Externds Point2D.Double and adds field <code>avgDistance</code>, | * Class to represent Point in EDM method. Externds Point2D.Double and adds field <code>avgDistance</code>, | ||
Line 162: | Line 163: | ||
*/ | */ | ||
public class EDMPoint extends Point2D.Double { | public class EDMPoint extends Point2D.Double { | ||
− | |||
public double avgDistance; | public double avgDistance; | ||
− | |||
public EDMPoint(double x, double y) { | public EDMPoint(double x, double y) { | ||
super(x, y); | super(x, y); | ||
} | } | ||
} | } | ||
− | </ | + | </syntaxhighlight> |
== Advantages == | == Advantages == | ||
− | * Easy to implement | + | * Easy to implement. |
− | * | + | * If possible, this method will give you a point where you will not hit any enemies. |
== Disadvantages == | == Disadvantages == | ||
− | * It's clear tactical "method", so it must be combined with any "strategical" method, for example [[ | + | * It's clear tactical "method", so it must be combined with any "strategical" method, for example [[Minimum Risk Movement]] |
− | |||
[[Category:Movement]] | [[Category:Movement]] | ||
+ | [[Category:Code Snippets]] |
Latest revision as of 07:21, 1 July 2010
A method for avoiding collisions with enemies.
Contents
How's it work?
General idea is: in Enemy Dodging Movement (EDM), you're generating set of points around your robot, calculate average distance to enemies for each point and go to point with minimal value.
Graphical demonstration
- red squares
- known enemies positions
- blue circle
- danger area (enemies outside this area are ignored)
- red/white points around the EDMRobot
- destination point set. White points is good, red is bad.
- bold white point
- destination point, i.e. the point which is the furthest from enemies in the blue circle.
Implementation
/**
* This class is implement Enemy dodging movement method
*
* @author jdev
*/
public class EnemyDodgingMovement {
private static final int ACTIVITY_AREA_MARGIN = 20;
private static final int FIELD_OF_VISION = 50;
private static final int DANGER_DISTANCE = FIELD_OF_VISION * 3;
private final Robot robot;
private final Rectangle activityArea;
public EnemyDodgingMovement(Robot robot) {
this.robot = robot;
activityArea = new Rectangle(ACTIVITY_AREA_MARGIN, ACTIVITY_AREA_MARGIN,
(int)robot.getBattleFieldWidth() - ACTIVITY_AREA_MARGIN * 2,
(int)robot.getBattleFieldHeight() - ACTIVITY_AREA_MARGIN * 2);
}
/**
* Method to calculate farest point from enemies
* @param enemies position of enemies
* @return farest point from enemies
*/
public Point2D.Double getDestination(Collection<Point2D.Double> enemies) {
final Collection<EDMPoint> points = getPoints(FIELD_OF_VISION, enemies);
double maxAvgDist = 0;
EDMPoint destination = null;
for (EDMPoint p : points) {
double avgDist = calculateAvgDistance(p, enemies);
if (avgDist > maxAvgDist) {
maxAvgDist = avgDist;
destination = p;
}
}
return destination;
}
/**
* Returns the collection of points, which are located on circle with radius = <code>dist</code> and with center
* in [<code>robot.getX()</code>, <code>robot.getY()</code>]
* @param dist distance to probably destination points from robot
* @param enemies enemies positions
* @return Returns the collection of points
*/
private Collection<EDMPoint> getPoints(double dist, Collection<Point2D.Double> enemies) {
final Collection<EDMPoint> points = new LinkedList<EDMPoint>();
final Point2D.Double myPos = new Point2D.Double(robot.getX(), robot.getY());
for (double angle = 0; angle < PI * 2; angle += PI / 9) {
final EDMPoint p = new EDMPoint(myPos.x + sin(angle) * dist,
myPos.y + cos(angle) * dist);
if (!activityArea.contains(p)) {
continue;
}
p.avgDistance = calculateAvgDistance(p, enemies);
points.add(p);
}
return points;
}
/**
* Calculates avarenge distance from point <code>point</code> to enemies in <code>enemies</code>
* @param point point to calculate averenge distance
* @param enemies enemies positions
* @return averenge distance
*/
private double calculateAvgDistance(Point2D.Double point, Collection<Point2D.Double> enemies) {
double distanceSum = 0;
int closeEnemyCount = 0;
for (Point2D.Double p : enemies) {
final double distance = p.distance(point);
if (p.distance(robot.getX(), robot.getY()) > DANGER_DISTANCE) {
continue;
}
distanceSum += distance;
closeEnemyCount++;
}
return distanceSum / (double)(closeEnemyCount > 0 ? closeEnemyCount : 1);
}
/**
* Paints a EDM's model
* @param g graphics to paint
* @param enemies enemies positions
*/
public void paint(Graphics2D g, Collection<Point2D.Double> enemies) {
g.setColor(Color.WHITE);
final Collection<EDMPoint> points = getPoints(FIELD_OF_VISION, enemies);
double maxAvgDist = 0;
double minAvgDist = Double.MAX_VALUE;
for (EDMPoint p : points) {
if (p.avgDistance < minAvgDist) {
minAvgDist = p.avgDistance;
}
if (p.avgDistance > maxAvgDist) {
maxAvgDist = p.avgDistance;
}
}
for (EDMPoint rp : points) {
int radius = 4;
int gb = (int) (255 * (rp.avgDistance - minAvgDist) / (maxAvgDist - minAvgDist));
if (gb < 0) {
gb = 0;
} else if (gb > 255) {
gb = 255;
}
g.setColor(new Color(255, gb, gb));
g.fillOval((int) Math.round(rp.x - radius / 2), (int) Math.round(rp.y - radius / 2), radius, radius);
if (rp.avgDistance == maxAvgDist) {
radius = 6;
g.drawOval((int) Math.round(rp.x - radius / 2), (int) Math.round(rp.y - radius / 2), radius, radius);
}
}
g.setColor(Color.BLUE);
final int fieldOfVisionRadius = DANGER_DISTANCE * 2;
g.drawOval((int)robot.getX() - fieldOfVisionRadius / 2, (int)robot.getY() - fieldOfVisionRadius / 2,
fieldOfVisionRadius, fieldOfVisionRadius);
}
}
/**
* Class to represent Point in EDM method. Externds Point2D.Double and adds field <code>avgDistance</code>,
* which means averegene distance to enemies in EDM
*
* @author jdev
*/
public class EDMPoint extends Point2D.Double {
public double avgDistance;
public EDMPoint(double x, double y) {
super(x, y);
}
}
Advantages
- Easy to implement.
- If possible, this method will give you a point where you will not hit any enemies.
Disadvantages
- It's clear tactical "method", so it must be combined with any "strategical" method, for example Minimum Risk Movement