Robocode Tank AI 实例

最近公司流行玩Robocode,这是一个坦克机器人战斗仿真引擎,里面可以写一些自己的Tank来互相战斗。

主要是使用了躲避子弹和避墙的思想

package azrael;

import robocode.*;
//import java.awt.Color;

// API help : http://robocode.sourceforge.net/docs/robocode/robocode/Robot.html

/**
 * Aldis - a robot by (your name here)
 */
public class Aldis extends AdvancedRobot {
    double previousEnergy = 100;
    int movementDirection = 1;
    int gunDirection = 1;
    int direction = 1;

    /**
     * run: Aldis's default behavior
     */
    public void run() {
        while (true) {
            setTurnRightRadiansOptimal(adjustHeadingForWalls(0));
            setAhead(100);
            execute();
        }
    }

    private static final double DOUBLE_PI = (Math.PI * 2);
    private static final double HALF_PI = (Math.PI / 2);
    private static final double WALL_AVOID_INTERVAL = 10;
    private static final double WALL_AVOID_FACTORS = 20;
    private static final double WALL_AVOID_DISTANCE = (WALL_AVOID_INTERVAL * WALL_AVOID_FACTORS);
    
    public double calculateBearingToXYRadians(double sourceX, double sourceY,
            double sourceHeading, double targetX, double targetY) {
                return normalizeRelativeAngleRadians(
                   Math.atan2((targetX - sourceX), (targetY - sourceY)) -
                       sourceHeading);
            }
        public double normalizeAbsoluteAngleRadians(double angle) {
           if (angle < 0) {
                return (DOUBLE_PI + (angle % DOUBLE_PI));
            } else {
                return (angle % DOUBLE_PI);
            }
        }
        public static double normalizeRelativeAngleRadians(double angle) {
            double trimmedAngle = (angle % DOUBLE_PI);
            if (trimmedAngle > Math.PI) {
                return -(Math.PI - (trimmedAngle % Math.PI));
            } else if (trimmedAngle < -Math.PI) {
                return (Math.PI + (trimmedAngle % Math.PI));
            } else {
                return trimmedAngle;
            }
        }
        
    private double adjustHeadingForWalls(double heading) {
        double fieldHeight = getBattleFieldHeight();
        double fieldWidth = getBattleFieldWidth();
        double centerX = (fieldWidth / 2);
        double centerY = (fieldHeight / 2);
        double currentHeading = getRelativeHeadingRadians();
        double x = getX();
        double y = getY();
        boolean nearWall = false;
        double desiredX;
        double desiredY;
        // If we are too close to a wall, calculate a course toward
        // the center of the battlefield.
        if ((y < WALL_AVOID_DISTANCE)
                || ((fieldHeight - y) < WALL_AVOID_DISTANCE)) {
            desiredY = centerY;
            nearWall = true;
        } else {
            desiredY = y;
        }
        if ((x < WALL_AVOID_DISTANCE)
                || ((fieldWidth - x) < WALL_AVOID_DISTANCE)) {
            desiredX = centerX;
            nearWall = true;
        } else {
            desiredX = x;
        }
        // Determine the safe heading and factor it in with the desired
        // heading if the bot is near a wall
        if (nearWall) {
            double desiredBearing = calculateBearingToXYRadians(x, y,
                    currentHeading, desiredX, desiredY);
            double distanceToWall = Math.min(Math.min(x, (fieldWidth - x)),
                    Math.min(y, (fieldHeight - y)));
            int wallFactor = (int) Math.min(
                    (distanceToWall / WALL_AVOID_INTERVAL), WALL_AVOID_FACTORS);
            return ((((WALL_AVOID_FACTORS - wallFactor) * desiredBearing) + (wallFactor * heading)) / WALL_AVOID_FACTORS);
        } else {
            return heading;
        }
    }

    public double getRelativeHeadingRadians() {
        double relativeHeading = getHeadingRadians();
        if (direction < 1) {
            relativeHeading = normalizeAbsoluteAngleRadians(relativeHeading
                    + Math.PI);
        }
        return relativeHeading;
    }

    public void reverseDirection() {
        double distance = (getDistanceRemaining() * direction);
        direction *= -1;
        setAhead(distance);
    }

    public void setAhead(double distance) {
        double relativeDistance = (distance * direction);
        super.setAhead(relativeDistance);
        if (distance < 0) {
            direction *= -1;
        }
    }

    public void setBack(double distance) {
        double relativeDistance = (distance * direction);
        super.setBack(relativeDistance);
        if (distance > 0) {
            direction *= -1;
        }
    }

    public void setTurnLeftRadiansOptimal(double angle) {
        double turn = normalizeRelativeAngleRadians(angle);
        if (Math.abs(turn) > HALF_PI) {
            reverseDirection();
            if (turn < 0) {
                turn = (HALF_PI + (turn % HALF_PI));
            } else if (turn > 0) {
                turn = -(HALF_PI - (turn % HALF_PI));
            }
        }
        setTurnLeftRadians(turn);
    }

    public void setTurnRightRadiansOptimal(double angle) {
        double turn = normalizeRelativeAngleRadians(angle);
        if (Math.abs(turn) > HALF_PI) {
            reverseDirection();
            if (turn < 0) {
                turn = (HALF_PI + (turn % HALF_PI));
            } else if (turn > 0) {
                turn = -(HALF_PI - (turn % HALF_PI));
            }
        }
        setTurnRightRadians(turn);
    }

    /**
     * onScannedRobot: What to do when you see another robot
     */
    public void onScannedRobot(ScannedRobotEvent e) {
        // Stay at right angles to the opponent
        fire(2);
        setTurnRight(e.getBearing() + 90 - 30 * movementDirection);

        // If the bot has small energy drop,
        // assume it fired
        double changeInEnergy = previousEnergy - e.getEnergy();
        if (changeInEnergy > 0 && changeInEnergy <= 3) {
            // Dodge!
            movementDirection = -movementDirection;
            setAhead((e.getDistance() / 4 + 25) * movementDirection);
        }
        // When a bot is spotted,
        // sweep the gun and radar
        gunDirection = -gunDirection;
        setTurnGunRight(99999 * gunDirection);

        // Fire directly at target
        // fire( 2 ) ;

        // Track the energy level
        previousEnergy = e.getEnergy();
    }
}


你可能感兴趣的:(Robocode Tank AI 实例)