Difference between revisions of "Enemy Dodging Movement"
Jump to navigation
Jump to search
(Movement method description) |
m (cleanup) |
||
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 === | ||
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); | ||
Line 172: | Line 171: | ||
== 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]] |
Revision as of 03:30, 26 October 2009
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