Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import static java.lang.StrictMath.PI;
- //import java.util.logging.Logger;
- import model.Bonus;
- import model.BonusType;
- import model.FireType;
- import model.Move;
- //import model.Obstacle;
- import model.Obstacle;
- import model.Shell;
- import model.ShellType;
- import model.Tank;
- import model.TankType;
- import model.World;
- public final class MyStrategy implements Strategy {
- private static enum Bound {
- bottom, left, none, right, top
- }
- private static enum DriveSE {
- ds_dodge_bomb, ds_drive_bonus, ds_drive_closer, ds_drive_corner, ds_drive_far, ds_drive_strafe, ds_help_rotate_turret, ds_hiding, ds_stick_leader, ds_hunting, ds_resurrect, ds_rotate_to_enemy, ds_stand, ds_died
- }
- private static enum helping {
- assist_me_please, no_thanks, resurrect_me_please
- }
- private static enum WhyTarget {
- target_me_in_closer_range, help_assist, low_hp, closer_range, target_me, closer_visible, lower_hp, assist_leader, no_target, turned_to_me, last
- }
- private static final class Point {
- public double x, y;
- }
- private static enum role {
- leader, unit
- }
- private static enum Rotate {
- left, none, right
- }
- private static final class TankCoords {
- public double Vx, Vy, sinA, cosA, X, Y, H, W, A, Xl, Yl, Xlb, Ylb, Xlf,
- Ylf, Xb, Yb, Xf, Yf, Xrb, Yrb, Xr, Yr, Xrf, Yrf;
- /*
- * lb==l===lf tank! ||======|| b===0====f ==> ||======|| rb==r===rf
- */
- TankCoords(model.Unit tank) {
- X = tank.getX();
- Y = tank.getY();
- H = tank.getHeight();
- W = tank.getWidth();
- A = tank.getAngle();
- sinA = Math.sin(A);
- cosA = Math.cos(A);
- double prjWx = (W / 2) * cosA;
- double prjWy = (W / 2) * sinA;
- double prjHx = (H / 2) * sinA;
- double prjHy = (H / 2) * cosA;
- Xf = X + prjWx;
- Yf = Y + prjWy;
- Xl = X + prjHx;
- Yl = Y - prjHy;
- Xb = X - prjWx;
- Yb = Y - prjWy;
- Xr = X - prjHx;
- Yr = Y + prjHy;
- Xrf = Xf + (Xr - X);
- Yrf = Yf + (Yr - Y);
- Xlf = Xf + (Xl - X);
- Ylf = Yf + (Yl - Y);
- Xlb = Xb + (Xl - X);
- Ylb = Yb + (Yl - Y);
- Xrb = Xb + (Xr - X);
- Yrb = Yb + (Yr - Y);
- Vx = tank.getSpeedX();
- Vy = tank.getSpeedY();
- }
- TankCoords(model.Unit tank, double x, double y) {
- X = x;
- Y = y;
- H = tank.getHeight();
- W = tank.getWidth();
- A = tank.getAngle();
- sinA = Math.sin(A);
- cosA = Math.cos(A);
- double prjWx = (W / 2) * cosA;
- double prjWy = (W / 2) * sinA;
- double prjHx = (H / 2) * sinA;
- double prjHy = (H / 2) * cosA;
- Xf = X + prjWx;
- Yf = Y + prjWy;
- Xl = X + prjHx;
- Yl = Y - prjHy;
- Xb = X - prjWx;
- Yb = Y - prjWy;
- Xr = X - prjHx;
- Yr = Y + prjHy;
- Xrf = Xf + (Xr - X);
- Yrf = Yf + (Yr - Y);
- Xlf = Xf + (Xl - X);
- Ylf = Yf + (Yl - Y);
- Xlb = Xb + (Xl - X);
- Ylb = Yb + (Yl - Y);
- Xrb = Xb + (Xr - X);
- Yrb = Yb + (Yr - Y);
- Vx = tank.getSpeedX();
- Vy = tank.getSpeedY();
- }
- public double getVelocityAbs() {
- return Math.sqrt(Vx * Vx + Vy * Vy);
- }
- public double getVelocityForward() {
- return getVelocityAbs()
- * Math.cos(getVectorAngle(Vx, cosA, Vy, sinA));
- }
- }
- public static int _can_shoot_time = 0;
- public static long[] _enemy;
- public static long[] _ids;
- public static int _team_healthy_tanks = 0,_team_premium_count=0;
- public static boolean _team_ready_for_shoot = false;
- public static int _team_shoots_count = 0;
- public static long _leader_current_enemy_id = -1;
- public static boolean _team_rush = false;
- public static boolean _team_need_retarget = true;
- private static final double AIMING__ACCURACY = 3; // part
- // enemy
- // tank
- // 1/3
- // more
- // ->
- // better
- private static final double AIMING__PREMIUM_EXCEED_LIMIT = 2;
- private static final double AIMING__PREMIUM_FIRE_DISTANCE = 500;
- private static final double AIMING__PREMIUM_FIRE_DISTANCE_MORE = 900;
- private static final double AIMING__STOP_DRIVE_TO_SHOOT_TIME = 40;
- private static final double BONUS__AMMO_MAX_DIST_EXTRA_SUPER_LOW_HP = 200;
- private static final double BONUS__DRIVE_POINT_RADIUS = 60;
- private static final double BONUS__HP_DIST_EXTRA_SUPER_LOW_HP = 300;
- private static final double BONUS__NEED_ARMOR_PRECENT = 0.65;
- private static final double BONUS__NEED_ARMOR_PRECENT_EXTRA = 0.4;
- private static final double BONUS__NEED_ARMOR_PRECENT_EXTRA_SUPER = 0.2;
- private static final double BONUS__NEED_HEALTH_PRECENT = 0.65;
- private static final double BONUS__NEED_HEALTH_PRECENT_EXTRA = 0.4;
- private static final double BONUS__NEED_HEALTH_PRECENT_EXTRA_SUPER = 0.2;
- private static final double BULLET__AERO_COEFF_PREMIUM = 0.30;
- private static final double BULLET__AERO_COEFF_REGULAR = 0.18;
- private static final double BULLET__PREMIUM_DAMAGE = 40;
- private static final double BULLET__REGULAR_DAMAGE = 25;
- private static final double BULLET__SPEED = 23;
- private static final double CONFIG__MY_MAX_ARM = 200;
- private static final double CONFIG__MY_MAX_HP = 100;
- private static final double CONFIG__MY_WIDTH = 90;
- private static final double CONFIG__WORLD_BOUND_WIDTH = 5;
- private static final double CONFIG__WORLD_HEIGHT = 800;
- private static final double CONFIG__WORLD_WIDTH = 1280;
- private static final double CONFIG__BULLET_SIZE = 11;
- private static final double CORNER__BOUNDS_WIDTH = 45;
- private static final double CORNER__DRIVE_POINT_RADIUS = 60;
- private static final double CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS = 400;
- private static final double CORNER__PLAYER_RADAR_RADIUS = 700;
- private static final double CORNER__POINT_DIST = 80;
- private static final double CORNER__POINT_RADIUS = 500;
- private static final int corners_count = 14; // dont
- // change
- // this
- private static final double DODGE__ACTIVE_DEFENCE_FROM_BOMB_MAX_DISTANCE = 400;
- private static final double DODGE__ACTIVE_DEFENCE_FROM_BOMB_MIN_DISTANCE = 45;
- private static final double DODGE__ADJUST_DRIVE_BACK_COEFF = 0.75;
- private static final double DODGE__ADJUST_SMALL_VELOCITY = 1;
- private static final double DODGE__ADJUST_VELOCITY_COEFF = 15;
- private static final double DODGE__MAX_DISTANCE_TO_AVOID_BY_TURNING = 300;
- private static final double DODGE__MAX_DV_DT_FORWARD = 0.15;
- private static final double DODGE__MAX_DV_DT_zBACK = -0.75
- * DODGE__MAX_DV_DT_FORWARD;
- private static final double DODGE__MIN_ESCAPE_ANGLE = PI / 5;
- private static final double DODGE__RICOCHETE_ANGLE = PI / 6.2;
- private static final double DODGE__TURN_ANGLE_DELTA = 0.5 * PI / 180;
- private static final double DODGE__TURN_DODGE_ANGLE_ACCURACY_DELTA = PI / 4000; // radian
- private static final double DRIVE__ADJUST_MAX_DISTANCE = 3000;
- private static final double DRIVE__ADJUST_MIN_DISTANCE = 100;
- private static final double DRIVE__ADJUST_TURN_DIFFERENCE_MAX = 0.75;
- private static final double DRIVE__MAX_DISTANCE_RIDE_ANGLE_INCREASED = 200;
- private static final double DRIVE__MAX_RIDE_ANGLE = PI / 4;
- private static final double DRIVE__MIN_DISTANCE_RIDE_ANGLE_INCREASED = 100;
- private static final double DRIVE__PATH_POINT_ACCURACY = 5;
- private static final double HIDING__DRIVE_POINT_RADIUS = 70;
- private static final double HUNT__DRIVE_POINT_RADIUS = 70;
- private static final double RANGING__CLOSER_RANGE = 250;
- private static final double RANGING__DRIVE_POINT_RADIUS = 70;
- private static final int TACTIC__MAX_ENEMIES_TO_DRIVE = 2;
- private static final double TEAM__CLOSER_ENEMY_ASSIST_RANGE = 400;
- private static final double TEAM__HELP_RESURRECT_DISTANCE_TO_BONUS = 100;
- private static final double TEAM__HELP_RESURRECT_DISTANCE_TO_DEAD_MAX = 200;
- private static final double TEAM__SHOOT_TIME_DELTA = 5;
- public static helping[] team_help;
- public static role[] team_roles;
- public static boolean[] team_shoot_ready;
- public static DriveSE[] team_state;
- public static WhyTarget[] team_why_targets;
- private static final double TURNING__ANGLE_ACCURACY = 15 * PI / 180; // 5
- // deg
- private static final double TURNING__CLOSER_MAX_DISTANCE = 500;
- private static final double TURNING__MIN_TURN_TO_ENEMY_ANGLE = PI / 5;
- private static final double TURNING__MIN_TURN_TO_ENEMY_ANGLE_ON_DIST = PI / 2.01;
- public static String team_1_name = "",
- team_2_name = "";
- public static int team_1_alive_count = 0,
- team_2_alive_count = 0, teams_count = 0,enemy_premium_count=0;
- public static int _team_leader_corner = -1;
- public static double enemy_sum_hp_arm = 0;
- private static final double driveCoeff(final double d) {
- if (d <= DRIVE__ADJUST_MIN_DISTANCE)
- return -1;
- else
- return -1 + (d - DRIVE__ADJUST_MIN_DISTANCE) * 2
- / (DRIVE__ADJUST_MAX_DISTANCE - DRIVE__ADJUST_MIN_DISTANCE);
- }
- private static final Bound getBound(final double X, final double Y,
- final double R) {
- if (X < CONFIG__WORLD_BOUND_WIDTH + R)
- return Bound.left;
- else
- if (X > CONFIG__WORLD_WIDTH - CONFIG__WORLD_BOUND_WIDTH - R)
- return Bound.right;
- else
- if (Y < CONFIG__WORLD_BOUND_WIDTH + R)
- return Bound.bottom;
- else
- if (Y > CONFIG__WORLD_HEIGHT - CONFIG__WORLD_BOUND_WIDTH
- - R)
- return Bound.top;
- else
- return Bound.none;
- }
- private static final Tank getClosestTankToPoint(Tank[] tanks,
- final double Px, final double Py, final double Radius) {
- int tc = tanks.length;
- double min_radius = Radius;
- int selected_tank = tc;
- for (int i = 0; i < tc; i++) {
- Tank tank = tanks[i];
- if (tank.getCrewHealth() == 0 || tank.getHullDurability() == 0)
- continue;
- double d = tank.getDistanceTo(Px, Py);
- if (d < min_radius) {
- d = min_radius;
- selected_tank = i;
- }
- }
- if (selected_tank < tc)
- return tanks[selected_tank];
- else
- return null;
- }
- private static final double getDistancePointToLine(final double PLx,
- final double PLy, final double VLx, final double VLy,
- final double Px, final double Py) {
- double VPLPx = Px - PLx;
- double VPLPy = Py - PLy;
- double D = Math.sqrt(VPLPy * VPLPy + VPLPx * VPLPx);
- double fi = getVectorAngle(VLx, VPLPx, VLy, VPLPy);
- return Math.abs(D * Math.sin(fi));
- }
- private static final double getMaxAngleOfUnitOnDist(final double myX,
- final double myY, model.Unit target, final double X, final double Y) {
- double Xb, Yb, Xa, Ya, Xc, Yc, Xd, Yd;
- double a1, a2, a3, a4;
- TankCoords tank_coords = new TankCoords(target, X, Y);
- Xa = tank_coords.Xlf;
- Ya = tank_coords.Ylf;
- Xb = tank_coords.Xrf;
- Yb = tank_coords.Yrf;
- Xd = tank_coords.Xrb;
- Yd = tank_coords.Yrb;
- Xc = tank_coords.Xlb;
- Yc = tank_coords.Ylb;// target corners
- double vx = X - myX;
- double vy = Y - myY;
- double vxa = Xa - myX;
- double vya = Ya - myY;
- double vxb = Xb - myX;
- double vyb = Yb - myY;
- double vxc = Xc - myX;
- double vyc = Yc - myY;
- double vxd = Xd - myX;
- double vyd = Yd - myY;
- double ABSva = Math.sqrt(vxa * vxa + vya * vya);
- double ABSvb = Math.sqrt(vxb * vxb + vyb * vyb);
- double ABSvc = Math.sqrt(vxc * vxc + vyc * vyc);
- double ABSvd = Math.sqrt(vxd * vxd + vyd * vyd);
- double ABSv = Math.sqrt(vx * vx + vy * vy);
- double cosa1 = (vx * vxa + vy * vya) / (ABSv * ABSva);
- if (cosa1 > 1 || cosa1 < -1)
- cosa1 = 1;
- a1 = Math.acos(cosa1);
- double cosa2 = (vx * vxb + vy * vyb) / (ABSv * ABSvb);
- if (cosa2 > 1 || cosa2 < -1)
- cosa2 = 1;
- a2 = Math.acos(cosa2);
- double cosa3 = (vx * vxc + vy * vyc) / (ABSv * ABSvc);
- if (cosa3 > 1 || cosa3 < -1)
- cosa3 = 1;
- a3 = Math.acos(cosa3);
- double cosa4 = (vx * vxd + vy * vyd) / (ABSv * ABSvd);
- if (cosa4 > 1 || cosa4 < -1)
- cosa4 = 1;
- a4 = Math.acos(cosa4);
- return Math.max(Math.max(a1, a2), Math.max(a3, a4));
- }
- private static final double getObjAngleOnDistance(final double dist,
- final double objH) {
- return 2 * Math.atan((objH / 2) / dist);
- }
- /**
- * 0..PI/2 from tank vector to line <0 if rotate right >0 if rotate left
- *
- * @param tank
- * @param VLx
- * @param VLy
- * @return
- */
- private static final double getTankAngleToLine(final Tank tank,
- final double VLx, final double VLy) {
- /*
- * ^ VRL | bc==c===ac <---TANK! ||======|| b===0====a ==> -->VT
- * ||======|| bd==d===ad
- */
- double A = tank.getAngle();
- double VTx = Math.cos(A);
- double VTy = Math.sin(A);
- double VRLx = VTy;
- double VRLy = -VTx;// f2->f1
- double fiT = -PI / 2 + getVectorAngle(VRLx, VLx, VRLy, VLy);
- double fiRL = -PI / 2 + getVectorAngle(VTx, VLx, VTy, VLy);
- if (fiRL * fiT < 0) {// check
- return -Math.abs(fiT);
- } else {
- return +Math.abs(fiT);
- }
- }
- private static final Rotate getTankOnBoundRotation(final double X,
- final double Y, final double R, final Tank t) {
- Bound b = getBound(X, Y, R);
- double VLx = 0, VLy = 0;
- switch (b) {
- case none:
- return Rotate.none;
- case bottom:
- case top:
- VLx = 1;
- VLy = 0;
- break;
- case left:
- case right:
- VLx = 0;
- VLy = 1;
- }
- double a = getTankAngleToLine(t, VLx, VLy);
- if (a < 0)
- return Rotate.right;
- else
- return Rotate.left;
- }
- private static final double getVectorAngle(final double vx1,
- final double vx2, final double vy1, final double vy2) {
- double cosa = (vx1 * vx2 + vy1 * vy2)
- / (Math.sqrt(vx1 * vx1 + vy1 * vy1) * Math.sqrt(vx2 * vx2 + vy2
- * vy2));
- if (cosa > 1 || cosa < -1)
- cosa = 1;
- return Math.acos(cosa);
- }
- /**
- * <0 rotate left from v to v2
- *
- * @param vx
- * first vector x
- * @param vx2
- * second vector x
- * @param vy
- * first vector y
- * @param vy2
- * second vector y
- * @return angle from v to v2
- */
- private static final double getVectorAngleWithSign(final double vx,
- final double vx2, final double vy, final double vy2) {
- double cosa = (vx * vx2 + vy * vy2)
- / (Math.sqrt(vx * vx + vy * vy) * Math.sqrt(vx2 * vx2 + vy2
- * vy2));
- if (cosa > 1 || cosa < -1)
- cosa = 1;
- double fi = Math.acos(cosa);
- double sgn = Math.signum(vx * vy2 - vx2 * vy);
- return fi * sgn;
- }
- private static final boolean isBombForTank(final model.Unit me,
- final Shell bomb, final double X, final double Y) {
- double bombX = bomb.getX();
- double bombY = bomb.getY();
- double BTx = X - bombX;
- double BTy = Y - bombY;
- double Bvx = bomb.getSpeedX();
- double Bvy = bomb.getSpeedY();
- double absBT = Math.sqrt(BTx * BTx + BTy * BTy);
- double absBv = Math.sqrt(Bvx * Bvx + Bvy * Bvy);
- double cosa = (BTx * Bvx + BTy * Bvy) / (absBT * absBv);
- if (cosa > 1 || cosa < -1)
- cosa = 1;
- double fi = Math.acos(cosa);
- double dist = me.getDistanceTo(bomb);
- if (fi >= PI / 2 && dist > 60)
- return false;
- /*
- * bc==c===ac tank! ||======|| b===0====a ==> ||======|| bd==d===ad
- */
- TankCoords tc = new TankCoords(me, X, Y);
- double Badx = tc.Xrf - bombX;
- double Bady = tc.Yrf - bombY;
- double Bbcx = tc.Xlb - bombX;
- double Bbcy = tc.Ylb - bombY;
- double Bacx = tc.Xlf - bombX;
- double Bacy = tc.Ylf - bombY;
- double Bbdx = tc.Xrb - bombX;
- double Bbdy = tc.Yrb - bombY;
- double absBad = Math.sqrt(Badx * Badx + Bady * Bady);
- double absBbc = Math.sqrt(Bbcx * Bbcx + Bbcy * Bbcy);
- double absBac = Math.sqrt(Bacx * Bacx + Bacy * Bacy);
- double absBbd = Math.sqrt(Bbdx * Bbdx + Bbdy * Bbdy);
- double cosa1 = (BTx * Badx + BTy * Bady) / (absBT * absBad);
- if (cosa1 > 1 || cosa1 < -1)
- cosa1 = 1;
- double a1 = Math.acos(cosa1);
- double cosa2 = (BTx * Bbcx + BTy * Bbcy) / (absBT * absBbc);
- if (cosa2 > 1 || cosa2 < -1)
- cosa2 = 1;
- double a2 = Math.acos(cosa2);
- double cosa3 = (BTx * Bacx + BTy * Bacy) / (absBT * absBac);
- if (cosa3 > 1 || cosa3 < -1)
- cosa3 = 1;
- double a3 = Math.acos(cosa3);
- double cosa4 = (BTx * Bbdx + BTy * Bbdy) / (absBT * absBbd);
- if (cosa4 > 1 || cosa4 < -1)
- cosa4 = 1;
- double a4 = Math.acos(cosa4);
- double maxa = Math.max(Math.max(a1, a2), Math.max(a3, a4));
- if (maxa >= PI / 2 && dist > 60)
- return false;
- double bullet_angle = getObjAngleOnDistance(dist, bomb.getWidth());
- boolean result = fi <= maxa + bullet_angle;
- return result;
- }
- private static final boolean isClearOfTanksSector(Tank me, final double X,
- final double Y, World world, final double Radius) {
- if (isOutWorldPointRadius(X, Y, Radius / 2))
- return false;
- Tank[] tanks = world.getTanks();
- int tc = tanks.length;
- for (int i = 0; i < tc; i++) {
- if (isSameTank(tanks[i], me))
- continue;
- double tdist = tanks[i].getDistanceTo(X, Y);
- if (tdist < tanks[i].getWidth() / 2 + Radius) {
- return false;
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- for (int i = 0; i < oc; i++) {
- double tdist = obst[i].getDistanceTo(X, Y);
- if (tdist < obst[i].getWidth() / 2 + Radius) {
- return false;
- }
- }
- return true;
- }
- private static final boolean isClearToDriveSector(final double X,
- final double Y, World world) {
- if (isOutWorldPointRadius(X, Y, 0))
- return false;
- Tank[] tanks = world.getTanks();
- int tc = tanks.length;
- for (int i = 0; i < tc; i++) {
- double tdist = tanks[i].getDistanceTo(X, Y);
- if (tdist < 15)
- continue;
- if (tdist < tanks[i].getWidth() / 2) {
- return false;
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- for (int i = 0; i < oc; i++) {
- double tdist = obst[i].getDistanceTo(X, Y);
- if (tdist < obst[i].getWidth() / 2) {
- return false;
- }
- }
- return true;
- }
- private static final boolean isOnCorner(final double X, final double Y) {
- if (X < CORNER__BOUNDS_WIDTH
- || X > CONFIG__WORLD_WIDTH - CORNER__BOUNDS_WIDTH
- || Y < CORNER__BOUNDS_WIDTH
- || Y > CONFIG__WORLD_HEIGHT - CORNER__BOUNDS_WIDTH)
- return true;
- return false;
- }
- private static final boolean isOutWorldPointRadius(final double X,
- final double Y, final double R) {
- if (X < CONFIG__WORLD_BOUND_WIDTH + R
- || X > CONFIG__WORLD_WIDTH - CONFIG__WORLD_BOUND_WIDTH - R
- || Y < CONFIG__WORLD_BOUND_WIDTH + R
- || Y > CONFIG__WORLD_HEIGHT - CONFIG__WORLD_BOUND_WIDTH - R)
- return true;
- else
- return false;
- }
- private static final boolean isSameTank(Tank tank1, Tank tank2) {
- try {
- return tank1.getId() == tank2.getId();
- } catch (Exception e) {
- return false;
- }
- }
- private static final boolean wayIsClear(final double dist, final double pX,
- final double pY, final double myX, final double myY, World world) {
- if (dist < 45)
- return true;
- double pvx = pX - myX, pvy = pY - myY;
- double a_target = getObjAngleOnDistance(dist, 110);
- Tank[] tanks = world.getTanks();
- int tc = tanks.length;
- for (int i = 0; i < tc; i++) {
- Tank obj = tanks[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- if (a_OMP <= a_obj + a_target) {
- return false;
- }
- }
- Bonus[] gifts = world.getBonuses();
- tc = gifts.length;
- for (int i = 0; i < tc; i++) {
- Bonus obj = gifts[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- if (a_OMP <= a_obj + a_target) {
- return false;
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- for (int i = 0; i < oc; i++) {
- Obstacle obj = obst[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- if (a_OMP <= a_obj + a_target) {
- return false;
- }
- }
- return true;
- }
- private static final boolean wayIsClearForShoot(final double dist,
- final double pX, final double pY, final double myX,
- final double myY, World world) {
- if (dist < 30)
- return true;
- double pvx = pX - myX, pvy = pY - myY;
- Tank[] tanks = world.getTanks();
- int tc = tanks.length;
- for (int i = 0; i < tc; i++) {
- Tank obj = tanks[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- if (obj.getCrewHealth() > 0 && obj.getHullDurability() > 0
- && !obj.isTeammate())
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- double a_bullet = getObjAngleOnDistance(odist, CONFIG__BULLET_SIZE);
- if (a_bullet >= a_OMP - a_obj) {
- return false;
- }
- }
- Bonus[] gifts = world.getBonuses();
- tc = gifts.length;
- for (int i = 0; i < tc; i++) {
- Bonus obj = gifts[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- double a_bullet = getObjAngleOnDistance(odist, CONFIG__BULLET_SIZE);
- if (a_bullet >= a_OMP - a_obj) {
- return false;
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- for (int i = 0; i < oc; i++) {
- Obstacle obj = obst[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- double a_bullet = getObjAngleOnDistance(odist, CONFIG__BULLET_SIZE);
- if (a_bullet >= a_OMP - a_obj) {
- return false;
- }
- }
- return true;
- }
- private static final boolean wayIsClearForShootObst(final double dist,
- final double pX, final double pY, final double myX,
- final double myY, World world) {
- if (dist < 30)
- return true;
- double pvx = pX - myX, pvy = pY - myY;
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- for (int i = 0; i < oc; i++) {
- Obstacle obj = obst[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- double a_bullet = getObjAngleOnDistance(odist, CONFIG__BULLET_SIZE);
- if (a_bullet >= a_OMP - a_obj) {
- return false;
- }
- }
- return true;
- }
- private static final boolean wayIsClearForTargeting(model.Unit u_target,
- final double dist, final double pX, final double pY,
- final double myX, final double myY, World world) {
- if (dist < 30)
- return true;
- double pvx = pX - myX, pvy = pY - myY;
- Tank[] tanks = world.getTanks();
- int tc = tanks.length;
- for (int i = 0; i < tc; i++) {
- Tank obj = tanks[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- if (obj.getCrewHealth() == 0 || obj.getHullDurability() == 0)
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- double a_bullet = getObjAngleOnDistance(odist, CONFIG__BULLET_SIZE);
- if (a_bullet >= a_OMP - a_obj) {
- return false;
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- for (int i = 0; i < oc; i++) {
- Obstacle obj = obst[i];
- double odist = obj.getDistanceTo(myX, myY);
- if ((odist + 15 >= dist) || (odist < 15))
- continue;
- double oX = obj.getX() + obj.getSpeedX();
- double oY = obj.getY() + obj.getSpeedY();
- double ovx = oX - myX;
- double ovy = oY - myY;
- double a_OMP = getVectorAngle(pvx, ovx, pvy, ovy);
- double a_obj = getMaxAngleOfUnitOnDist(myX, myY, obj, obj.getX(),
- obj.getY());
- double a_bullet = getObjAngleOnDistance(odist, CONFIG__BULLET_SIZE);
- if (a_bullet >= a_OMP - a_obj) {
- return false;
- }
- }
- return true;
- }
- private double _corner_x = 0, _corner_y = 0;
- private Point[] _corners = new Point[corners_count];
- private double _drive_target_H = 30;
- private double _dv_dt_x = 0, _dv_dt_y = 0;
- private boolean _enemy_changed = true;
- private long _last_enemy_id = -1;
- private int _enemy_healthy_tanks = 0;
- private double _enemy_last_v_x = 0, _enemy_last_v_y = 0;
- private double _hp = 0, _armor = 0,
- _premium_count = 0;
- private int _i;
- private boolean _i_can_shoot = false;
- public DriveSE _last_drive_state;
- private double _last_v_x = 0, _last_v_y = 0;
- private double _next_x = 0, _next_y = 0;
- private Point[] _path = new Point[4];
- private int _path_current = 0;
- private double _tik = 0;
- private double _tik_strafe = 0;
- private double _x = 0, _y = 0;
- private double _vx = 0, _vy = 0;
- // private double eNX=0,eNY=0,bft=0;//TODO
- private boolean _leader_enemy_teams_counted = false;
- private boolean b_i_am_do_manevr = false;
- private boolean b_i_need_ammo = false;
- private boolean b_i_need_armor = false;
- private boolean b_i_need_armor_extra = false;
- private boolean b_i_need_armor_extra_super = false;
- private boolean b_i_need_health = false;
- private boolean b_i_need_health_extra = false;
- private boolean b_i_need_health_extra_super = false;
- private boolean b_im_avoiding_bomb = false;
- private boolean b_im_drive_to_corner = false;
- @SuppressWarnings("unused")
- private boolean b_im_drive_to_path_point = false;
- private boolean b_im_escape_for_range = false;
- private boolean b_im_goto_bonus = false;
- private boolean b_im_goto_min_dist = false;
- private boolean b_im_hiding = false;
- private boolean b_im_hunting;
- private boolean b_im_turn_to_enemy = false;
- private boolean b_im_turning_to_help_turn_turret = false;
- private boolean b_it_is_a_first_tick = true;
- private boolean b_it_is_a_time_to_drive = false;
- private void aiDefineBonusPrioritets() {
- b_i_need_health = CONFIG__MY_MAX_HP * BONUS__NEED_HEALTH_PRECENT > _hp;
- b_i_need_health_extra = CONFIG__MY_MAX_HP
- * BONUS__NEED_HEALTH_PRECENT_EXTRA > _hp;
- b_i_need_health_extra_super = CONFIG__MY_MAX_HP
- * BONUS__NEED_HEALTH_PRECENT_EXTRA_SUPER > _hp;
- b_i_need_armor = CONFIG__MY_MAX_ARM * BONUS__NEED_ARMOR_PRECENT > _armor;
- b_i_need_armor_extra = CONFIG__MY_MAX_ARM
- * BONUS__NEED_ARMOR_PRECENT_EXTRA > _armor;
- b_i_need_armor_extra_super = CONFIG__MY_MAX_ARM
- * BONUS__NEED_ARMOR_PRECENT_EXTRA_SUPER > _armor;
- b_i_need_ammo = _premium_count < 1;
- }
- private boolean aiDodgeBomb(Tank self, World world, Move move) {
- boolean im_do_avoid = false;
- Shell killer_bomba = getBulletFlyToTank(world, self);
- if (killer_bomba != null) {
- double distance_to_bomb = self.getDistanceTo(killer_bomba);
- doDodge(killer_bomba, self, move, world);// DODGE!
- im_do_avoid = true;
- MyStrategy.team_state[_i] = DriveSE.ds_dodge_bomb;
- /*
- * dont change current enemy while dodge! but... wtf!
- */
- if (distance_to_bomb < DODGE__ACTIVE_DEFENCE_FROM_BOMB_MAX_DISTANCE) {
- double bombNextX = killer_bomba.getX()
- + killer_bomba.getSpeedX();
- double bombNextY = killer_bomba.getY()
- + killer_bomba.getSpeedY();
- if ((self.getRemainingReloadingTime() == 0)
- && distance_to_bomb > DODGE__ACTIVE_DEFENCE_FROM_BOMB_MIN_DISTANCE
- && (Math.abs(self
- .getTurretAngleTo(bombNextX, bombNextY)) < getObjAngleOnDistance(
- distance_to_bomb, killer_bomba.getHeight()))
- && wayIsClearForShoot(distance_to_bomb,
- killer_bomba.getX(), killer_bomba.getY(), _x,
- _y, world)
- ) {
- move.setFireType(FireType.REGULAR);// kill BOMB!!!
- }
- }
- }
- return im_do_avoid;
- }
- private void aiDoResurrectTeammate(World world, Tank me) {
- boolean resurrect_success = false;
- for (int k = 0; k < MyStrategy.team_help.length; k++) {
- if (k == _i)
- continue;
- if (MyStrategy.team_help[k] == helping.resurrect_me_please) {
- Tank[] tanks = world.getTanks();
- for (int j = 0; j < tanks.length; j++) {
- if (tanks[j].getId() == MyStrategy._ids[k]) {
- if (me.getDistanceTo(tanks[j]) > TEAM__HELP_RESURRECT_DISTANCE_TO_DEAD_MAX)
- continue;
- double died_x = tanks[j].getX();
- double died_y = tanks[j].getY();
- Bonus[] bonuses = world.getBonuses();
- for (int o = 0; o < bonuses.length; o++) {
- if (tanks[j].getCrewHealth() > 0
- && bonuses[o].getType() == BonusType.MEDIKIT)
- continue;
- if (tanks[j].getHullDurability() > 0
- && bonuses[o].getType() == BonusType.REPAIR_KIT)
- continue;
- if (bonuses[o].getType() == BonusType.AMMO_CRATE)
- continue;
- double dist = tanks[j].getDistanceTo(bonuses[o]);
- if (dist < TEAM__HELP_RESURRECT_DISTANCE_TO_BONUS) {
- // help
- double bonus_x = bonuses[o].getX();
- double bonus_y = bonuses[o].getY();
- if (!wayIsClear(dist, bonus_x, bonus_y, died_x,
- died_y, world))
- continue;
- double BTx = died_x - bonus_x;
- double BTy = died_y - bonus_y;
- double norma = Math.sqrt(BTx * BTx + BTy * BTy);
- BTx = BTx * 100 / norma;
- BTy = BTy * 100 / norma;
- double Nx = died_x + BTx;
- double Ny = died_y + BTy;
- if (isClearOfTanksSector(me, Nx, Ny, world, 10)) {
- _path[0].x = Nx;
- _path[0].y = Ny;
- if (me.getDistanceTo(Nx, Ny) < DRIVE__PATH_POINT_ACCURACY + 15) {
- _path[0].x = bonus_x;// nneds angle
- _path[0].y = bonus_y;
- }
- _drive_target_H = 15;
- MyStrategy.team_state[_i] = DriveSE.ds_resurrect;
- resurrect_success = true;
- break;
- }
- }
- }
- break;
- }
- }
- break;
- }
- }
- if (!resurrect_success
- && MyStrategy.team_state[_i] == DriveSE.ds_resurrect)
- MyStrategy.team_state[_i] = DriveSE.ds_stand;
- }
- private boolean aiDoShootAndManevr(Tank self, World world,
- final int selected_tank, Move move) {
- boolean result_i_am_do_something = false;
- Tank[] all_tanks = world.getTanks();
- if (selected_tank == all_tanks.length || selected_tank == -1)
- return false;
- Tank enemyTank = all_tanks[selected_tank];
- if (_enemy_changed) {
- this._enemy_last_v_x = enemyTank.getSpeedX();
- this._enemy_last_v_y = enemyTank.getSpeedY();
- }
- double enemyDist = self.getDistanceTo(enemyTank);
- double Cx = BULLET__AERO_COEFF_REGULAR;
- double d_allowed_premium = AIMING__PREMIUM_FIRE_DISTANCE;
- boolean b_shoot_premium = self.getPremiumShellCount() > 0
- && enemyDist < d_allowed_premium;
- boolean turned_to_me = MyStrategy.team_why_targets[_i] == WhyTarget.turned_to_me;
- boolean low_hp_enemy = MyStrategy.team_why_targets[_i] == WhyTarget.low_hp;
- if (turned_to_me)
- b_shoot_premium = self.getPremiumShellCount() > 0;
- if (b_shoot_premium)
- Cx = BULLET__AERO_COEFF_PREMIUM;
- double dVdD = Cx * Math.sqrt(enemyDist);
- if (dVdD >= BULLET__SPEED)
- dVdD = BULLET__SPEED - 1;
- double bombFlyTime = enemyDist / (BULLET__SPEED - dVdD);
- double evx = enemyTank.getSpeedX();
- double evy = enemyTank.getSpeedY();
- double dxv = evx * bombFlyTime;
- double dyv = evy * bombFlyTime;
- double ax = evx - _enemy_last_v_x;
- double ay = evy - _enemy_last_v_y;
- double lastv = Math.sqrt(_enemy_last_v_x * _enemy_last_v_x
- + _enemy_last_v_y * _enemy_last_v_y);
- double v = Math.sqrt(evx * evx + evy * evy);
- double a = v - lastv;
- double dxa = bombFlyTime * bombFlyTime * ax / 2;
- double dya = bombFlyTime * bombFlyTime * ay / 2;
- double S = Math.abs(v * bombFlyTime);
- double Sa = Math.abs(bombFlyTime * bombFlyTime * a / 2);
- double SMALL_DISTANCE = 90;
- boolean start_driving = S < SMALL_DISTANCE && a >= 0;
- boolean stop_driving = S < SMALL_DISTANCE && a < 0;
- boolean decrease_speed = S > SMALL_DISTANCE && a < 0;
- boolean increase_speed = S > SMALL_DISTANCE && a >= 0;
- boolean strafe = start_driving || stop_driving;// drive slowly -> strafe
- _i_can_shoot = increase_speed || start_driving || stop_driving
- || enemyDist < 650 || turned_to_me || low_hp_enemy;
- if (start_driving) {
- dxv /= 3;
- dyv /= 3;
- dxa /= 10;
- dya /= 10;
- }
- if (stop_driving) {
- dxv /= 10;
- dyv /= 10;
- dxa /= 10;
- dya /= 10;
- }
- double enemyNextX = enemyTank.getX() + dxv + dxa;
- double enemyNextY = enemyTank.getY() + dyv + dya;
- if (!isClearOfTanksSector(enemyTank, enemyNextX, enemyNextY, world, 45)) {
- enemyNextX = enemyTank.getX() + (dxv + dxa) / 3;
- enemyNextY = enemyTank.getY() + (dyv + dya) / 3;
- }
- // what our target point?
- boolean way_is_clear_for_shoot = true;
- TankCoords target = new TankCoords(enemyTank, enemyNextX, enemyNextY);
- if (turned_to_me) {
- enemyNextX = target.Xb;
- enemyNextY = target.Yb;
- if (self.getDistanceTo(target.Xf, target.Yf) < self.getDistanceTo(
- enemyNextX, enemyNextY)) {
- enemyNextX = target.Xf;
- enemyNextY = target.Yf;
- }
- }
- if (!wayIsClearForShoot(enemyDist, enemyNextX, enemyNextY, _x, _y,
- world)) {
- if (enemyDist > 350) {
- way_is_clear_for_shoot = false;
- } else {
- enemyNextX = target.Xf;
- enemyNextY = target.Yf;
- if (!wayIsClearForShoot(enemyDist, enemyNextX, enemyNextY, _x,
- _y, world)) {
- enemyNextX = target.Xb;
- enemyNextY = target.Yb;
- if (!wayIsClearForShoot(enemyDist, enemyNextX, enemyNextY,
- _x, _y, world)) {
- enemyNextX = target.X;
- enemyNextY = target.Y;
- way_is_clear_for_shoot = false;
- }
- }
- }
- }
- // ngc.drawCircle(enemyNextX, enemyNextY,
- // 45);ngc.drawString(Integer.toString(_i), enemyNextX+_i*10,
- // enemyNextY);
- // if(start_driving) ngc.drawString("start", enemyNextX,
- // enemyNextY);if(stop_driving)ngc.drawString("stop", enemyNextX,
- // enemyNextY);
- // if
- // (self.getRemainingReloadingTime()<self.getReloadingTime()-bombFlyTime
- // ){ eNX = enemyNextX;eNY = enemyNextY;bft=bombFlyTime;
- // ngc.setColor("white"); ngc.drawLine(_x, _y, eNX, eNY);
- // ngc.drawCircle(eNX, eNY, 45); ngc.setColor("red"); }else{
- // ngc.drawString(Double.toString(bft), eNX, eNY); bft--;
- // ngc.drawLine(_x, _y, eNX, eNY); ngc.drawCircle(eNX, eNY, 45); }
- // AI_FIND_SAFE_OF_TARGETING_POINT_ON_MAP
- b_im_hiding = false;
- b_im_goto_min_dist = false;
- double earm = enemyTank.getHullDurability();
- double ehp = enemyTank.getCrewHealth();
- if (!b_im_avoiding_bomb
- /* && b_it_is_a_time_to_drive */
- && (!b_im_goto_bonus && !b_im_drive_to_corner || (MyStrategy._team_rush && !(b_im_goto_bonus && (b_i_need_ammo
- || b_i_need_armor || b_i_need_health)))))
- if (_enemy_healthy_tanks == 1
- && enemyTank.getPremiumShellCount() <= self
- .getPremiumShellCount()
- && _hp * _armor > ehp * earm || MyStrategy._team_rush) {
- if (enemyDist > RANGING__CLOSER_RANGE)
- b_im_goto_min_dist = aiGotoMinDist(enemyTank, self, world);
- } else
- if (!b_im_hunting && way_is_clear_for_shoot
- /* && (_enemy_healthy_tanks >= _team_healthy_tanks) */
- /* && (b_i_need_armor || b_i_need_health || enemyDist < 500) */) {
- b_im_hiding = aiGotoSafePoint(all_tanks, self, world,
- enemyTank);
- }
- double turret_angle_to_enemy = self.getTurretAngleTo(enemyNextX,
- enemyNextY);
- boolean b_im_doing_extra_things = b_im_avoiding_bomb;
- boolean b_im_driving_for_profit = (b_im_goto_bonus || b_im_hiding
- || b_im_escape_for_range);
- boolean b_its_time_to_aim_and_shoot = (self.getRemainingReloadingTime() < AIMING__STOP_DRIVE_TO_SHOOT_TIME
- && !((b_i_need_armor_extra || b_i_need_health_extra) && b_im_driving_for_profit));
- double attack_angle = getMaxAngleOfUnitOnDist(_x, _y, enemyTank,
- enemyNextX, enemyNextY);
- boolean b_my_turret_in_very_wrong_direction = (Math
- .abs(turret_angle_to_enemy) > 3 * PI / 180
- + Math.abs(attack_angle / AIMING__ACCURACY));
- b_im_turning_to_help_turn_turret = way_is_clear_for_shoot
- && (!b_im_doing_extra_things && (b_its_time_to_aim_and_shoot && b_my_turret_in_very_wrong_direction));
- if (b_im_turning_to_help_turn_turret) {
- MyStrategy.team_state[_i] = DriveSE.ds_help_rotate_turret;
- // ngc.drawString("turn", _x, _y);
- }
- // Tank who_targets_my_enemy = getCloserOfTargetingTankEnemy(enemyTank,
- // world, WORLD_WIDTH);
- if (turret_angle_to_enemy >= attack_angle / AIMING__ACCURACY) {
- move.setTurretTurn(1.0);
- if (b_im_turning_to_help_turn_turret)
- doTurnRightMax(move);
- } else
- if (turret_angle_to_enemy <= -attack_angle / AIMING__ACCURACY) {
- move.setTurretTurn(-1.0);
- if (b_im_turning_to_help_turn_turret)
- doTurnLeftMax(move);
- } else
- if (way_is_clear_for_shoot && _i_can_shoot) {
- b_im_hunting = false;
- if (b_shoot_premium)
- move.setFireType(FireType.PREMIUM_PREFERRED);
- else
- move.setFireType(FireType.REGULAR);
- }
- // AI_HUNT
- if (!way_is_clear_for_shoot
- && (self.getRemainingReloadingTime() < AIMING__STOP_DRIVE_TO_SHOOT_TIME)
- && !b_im_avoiding_bomb && !b_im_goto_bonus
- && !b_im_drive_to_corner && !b_im_goto_min_dist
- && !(b_i_need_health_extra_super || b_i_need_armor_extra_super)
- && !b_im_turning_to_help_turn_turret)
- b_im_hunting = aiGotoHunt(self, world, enemyTank, enemyNextX,
- enemyNextY);
- // AI_TURN_TO_ENEMY
- if (!b_im_avoiding_bomb && !b_im_goto_bonus && !b_im_hiding
- && !b_im_goto_min_dist && !b_im_escape_for_range
- && !b_im_turning_to_help_turn_turret /* && !b_im_hunting */
- && !b_im_drive_to_corner) {
- b_im_turn_to_enemy = aiTurnToEnemy(self, enemyTank, move);
- } else
- b_im_turn_to_enemy = false;
- _enemy_last_v_x = enemyTank.getSpeedX();
- _enemy_last_v_y = enemyTank.getSpeedY();
- result_i_am_do_something = b_im_turn_to_enemy
- || b_im_turning_to_help_turn_turret;
- return result_i_am_do_something;
- }
- private boolean aiDrivePath(Tank self, Move move, World world) {
- boolean result_i_drive = false;
- if (_path[_path_current].x != -1
- && MyStrategy.team_state[_i] != DriveSE.ds_stand) {
- if (self.getDistanceTo(_path[_path_current].x,
- _path[_path_current].y) >= DRIVE__PATH_POINT_ACCURACY
- + _drive_target_H / 2) {
- driveToPoint(_path[_path_current].x, _path[_path_current].y,
- move, self, _drive_target_H, world);
- result_i_drive = true;
- } else {
- _path[_path_current].x = -1;
- _path_current++;
- if (_path_current >= _path.length)
- _path_current = 0;
- if (_path[_path_current].x == -1) {
- // miss path
- int s = _path_current;
- for (s = _path_current; s < _path.length; s++)
- if (_path[s].x != -1) {
- _path_current = s;
- break;
- }
- if (s == _path.length)
- _path_current = 0;
- }
- }
- } else {
- double v = Math.sqrt(_vx * _vx + _vy * _vy);
- if (v < 10) {
- if (_tik_strafe > 50)
- _tik_strafe = 0;
- if (_tik_strafe <= 20)
- doMoveForward(move);
- else
- doMoveBack(move);
- _tik_strafe++;
- } else
- _tik_strafe = 0;
- MyStrategy.team_state[_i] = DriveSE.ds_drive_strafe;
- }
- // ngc.drawCircle(_path[_path_current].x, _path[_path_current].y,
- // DRIVE__PATH_POINT_ACCURACY + _drive_target_H / 2 - 2);
- // ngc.drawString(Integer.toString(_i),
- // _path[_path_current].x+_i*10, _path[_path_current].y);
- // ngc.drawString(MyStrategy.team_state[_i].toString(),
- // _x, _y);
- return result_i_drive;
- }
- private boolean aiGotoBonus(World world, Tank self) {
- boolean i_drive_to_bonus = false;
- Bonus[] all_bonuses = world.getBonuses();
- int selected_bonus = all_bonuses.length;
- double min_dist_to_bonus = 1E50;
- if ((MyStrategy._team_rush)) {
- min_dist_to_bonus = 300;
- }
- if (b_i_need_health_extra_super || b_i_need_armor_extra_super)
- min_dist_to_bonus = BONUS__AMMO_MAX_DIST_EXTRA_SUPER_LOW_HP;
- if (b_i_need_ammo)
- for (int i = 0; i < all_bonuses.length; i++) {
- Bonus bonus = all_bonuses[i];
- if (bonus.getType() != BonusType.AMMO_CRATE)
- continue;
- double dist_to_bonus = self.getDistanceTo(bonus);
- double corner_dist = bonus.getDistanceTo(_corner_x, _corner_y);
- if ((!b_it_is_a_time_to_drive)
- && (corner_dist > (CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS)))
- continue;
- if (dist_to_bonus < min_dist_to_bonus) {
- Tank closest_tank = getClosestTankToPoint(world.getTanks(),
- bonus.getX(), bonus.getY(),
- CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS);
- if (closest_tank != null
- && !isSameTank(closest_tank, self)
- && (dist_to_bonus > CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS))
- continue;
- min_dist_to_bonus = dist_to_bonus;
- selected_bonus = i;
- }
- }
- if (b_i_need_armor_extra)
- min_dist_to_bonus = BONUS__HP_DIST_EXTRA_SUPER_LOW_HP;
- if (b_i_need_armor || b_i_need_armor_extra
- || b_i_need_armor_extra_super)
- for (int i = 0; i < all_bonuses.length; i++) {
- Bonus bonus = all_bonuses[i];
- if (bonus.getType() != BonusType.REPAIR_KIT)
- continue;
- double dist_to_bonus = self.getDistanceTo(bonus);
- double corner_dist = bonus.getDistanceTo(_corner_x, _corner_y);
- if ((!b_i_need_armor_extra)
- && ((!b_it_is_a_time_to_drive) && (corner_dist > (CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS))))
- continue;
- if (dist_to_bonus < min_dist_to_bonus) {
- Tank closest_tank = getClosestTankToPoint(world.getTanks(),
- bonus.getX(), bonus.getY(),
- CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS);
- if (closest_tank != null
- && !isSameTank(closest_tank, self)
- && (dist_to_bonus > CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS))
- continue;
- min_dist_to_bonus = dist_to_bonus;
- selected_bonus = i;
- }
- }
- if (b_i_need_health_extra)
- min_dist_to_bonus = BONUS__HP_DIST_EXTRA_SUPER_LOW_HP;
- if (b_i_need_health || b_i_need_health_extra
- || b_i_need_health_extra_super)
- for (int i = 0; i < all_bonuses.length; i++) {
- Bonus bonus = all_bonuses[i];
- if (bonus.getType() != BonusType.MEDIKIT)
- continue;
- double dist_to_bonus = self.getDistanceTo(bonus);
- double corner_dist = bonus.getDistanceTo(_corner_x, _corner_y);
- if ((!b_i_need_health_extra)
- && ((!b_it_is_a_time_to_drive) && (corner_dist > (CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS))))
- continue;
- if (dist_to_bonus < min_dist_to_bonus) {
- Tank closest_tank = getClosestTankToPoint(world.getTanks(),
- bonus.getX(), bonus.getY(),
- CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS);
- if (closest_tank != null
- && !isSameTank(closest_tank, self)
- && (dist_to_bonus > CORNER__MAX_ALLOWED_DISTANCE_TO_BONUS))
- continue;
- min_dist_to_bonus = dist_to_bonus;
- selected_bonus = i;
- }
- }
- if (selected_bonus != all_bonuses.length) {
- i_drive_to_bonus = true;
- _drive_target_H = BONUS__DRIVE_POINT_RADIUS;
- /*
- * ngc.setColor("red"); if (MyStrategy.team_roles[_i]==role.leader)
- * ngc.drawCircle(all_bonuses[selected_bonus].getX(),
- * all_bonuses[selected_bonus].getY(), _drive_target_H);
- * ngc.drawCircle(all_bonuses[selected_bonus].getX(),
- * all_bonuses[selected_bonus].getY(), _drive_target_H-2);
- * ngc.setColor("red");
- */
- MyStrategy.team_state[_i] = DriveSE.ds_drive_bonus;
- createPathToPoint(all_bonuses[selected_bonus].getX(),
- all_bonuses[selected_bonus].getY(), world, self);
- }
- return i_drive_to_bonus;
- }
- private boolean aiGotoHunt(Tank self, World world, Tank enemyTank,
- final double enemyNextX, final double enemyNextY) {
- boolean result_i_drive_for_hunt = false;
- double mdX = -1, mdY = -1;
- double myAngle = self.getAngle();
- double max_dist = CONFIG__WORLD_WIDTH;
- double min_dist_to_enemy = 0;
- double angle = 30;
- if (!b_it_is_a_time_to_drive && !MyStrategy._team_rush) {
- max_dist = 500;
- angle = 10;
- // min_dist_to_enemy=700;
- }
- for (double dist = CONFIG__MY_WIDTH * 2.5; dist < max_dist; dist = dist
- + CONFIG__MY_WIDTH) {
- double dfi = 0.25 * getObjAngleOnDistance(dist, CONFIG__MY_WIDTH)
- * 180 / PI;
- for (double fi = 0; fi < 360; fi = fi + dfi) {
- if (fi > angle && fi < 180 - angle || fi > 180 + angle
- && fi < 360 - angle)
- continue;
- double x = _x + dist * Math.cos((fi + myAngle) * PI / 180);
- double y = _y + dist * Math.sin((fi + myAngle) * PI / 180);
- if (min_dist_to_enemy > 0
- && isEnemiesInPoint(world.getTanks(), x, y,
- min_dist_to_enemy))
- continue;
- double enemyDist = enemyTank.getDistanceTo(x, y);
- if (!isOnCorner(x, y)
- && wayIsClearForShoot(enemyDist, enemyNextX,
- enemyNextY, x, y, world)
- && isClearToDriveSector(x, y, world)) {
- mdX = x;
- mdY = y;
- result_i_drive_for_hunt = true;
- break;
- }
- }
- if (result_i_drive_for_hunt)
- break;
- }
- if (result_i_drive_for_hunt) {
- createPathToPoint(mdX, mdY, world, self); // NO DANGER POINT
- _drive_target_H = HUNT__DRIVE_POINT_RADIUS;
- /*
- * ngc.setColor("yellow"); if
- * (MyStrategy.team_roles[_i]==role.leader) ngc.drawCircle(mdX, mdY,
- * _drive_target_H); ngc.drawCircle(mdX, mdY, _drive_target_H-2);
- * ngc.setColor("red");
- */
- MyStrategy.team_state[_i] = DriveSE.ds_hunting;
- }
- return result_i_drive_for_hunt;
- }
- private boolean aiGotoMinDist(Tank enemyTank, Tank self, World world) {
- boolean result_i_goto_min_dist = false;
- // goto_min_dist
- // double RANGE = RANGING__CLOSER_RANGE;
- double rmdX = -1, rmdY = -1;
- TankCoords t_c = new TankCoords(enemyTank);
- double p1x = t_c.Xr;
- double p1y = t_c.Yr;
- double d1 = self.getDistanceTo(p1x, p1y);
- double p2x = t_c.Xl;
- double p2y = t_c.Yl;
- double d2 = self.getDistanceTo(p2x, p2y);
- if (isOutWorldPointRadius(p1x, p1y, 10)) {
- d1 = -1;// no p1
- }
- if (isOutWorldPointRadius(p2x, p2y, 10)) {
- d2 = -1;// no p2
- }
- if (d1 < d2 && d1 > 0 || d2 < 0 && d1 > 0) {
- rmdX = p1x;
- rmdY = p1y;
- result_i_goto_min_dist = true;
- }
- if (d2 < d1 && d2 > 0 || d1 < 0 && d2 > 0) {
- rmdX = p2x;
- rmdY = p2y;
- result_i_goto_min_dist = true;
- }
- if (result_i_goto_min_dist) {
- createPathToPoint(rmdX, rmdY, world, self);
- _drive_target_H = RANGING__DRIVE_POINT_RADIUS;
- /*
- * ngc.setColor("green"); if
- * (MyStrategy.team_roles[_i]==role.leader) ngc.drawCircle(rmdX,
- * rmdY, _drive_target_H); ngc.drawCircle(rmdX, rmdY,
- * _drive_target_H-2); ngc.setColor("red");
- */
- MyStrategy.team_state[_i] = DriveSE.ds_drive_closer;
- }
- return result_i_goto_min_dist;
- }
- private boolean aiGotoSafePoint(Tank[] all_tanks, Tank self, World world,
- Tank enemyTank) {
- boolean result_i_goto_safe_point = false;
- double mdX = -1, mdY = -1;
- double min_dist = 500;
- double tc = all_tanks.length;
- for (int i = 0; i < tc; i++) {
- Tank ob = all_tanks[i];
- if (isSameTank(ob, self)
- || isSameTank(ob, enemyTank)
- || (ob.getCrewHealth() > 0 && ob.getHullDurability() > 0 && !ob
- .isTeammate()))
- continue;
- double Tx = ob.getX();
- double Ty = ob.getY();
- double ETx = Tx - enemyTank.getX();
- double ETy = Ty - enemyTank.getY();
- double normaTE = Math.sqrt(ETx * ETx + ETy * ETy);
- double x = Tx + ob.getWidth() * ETx / normaTE;
- double y = Ty + ob.getWidth() * ETy / normaTE;
- double dist = self.getDistanceTo(x, y);
- if (dist < min_dist && isClearOfTanksSector(self, x, y, world, 0)) {
- min_dist = dist;
- mdX = x;
- mdY = y;
- result_i_goto_safe_point = true;
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- if (min_dist == 500)
- min_dist = 2000;
- for (int i = 0; i < oc; i++) {
- Obstacle ob = obst[i];
- double Tx = ob.getX();
- double Ty = ob.getY();
- double ETx = Tx - enemyTank.getX();
- double ETy = Ty - enemyTank.getY();
- double normaTE = Math.sqrt(ETx * ETx + ETy * ETy);
- double hide_dist = Math.sqrt(ob.getWidth() * ob.getWidth()
- + ob.getHeight() * ob.getHeight())
- + (_i + 1) * self.getWidth() * 2;
- double x = Tx + hide_dist * ETx / normaTE;
- double y = Ty + hide_dist * ETy / normaTE;
- double dist = self.getDistanceTo(x, y);
- if (dist < min_dist && isClearOfTanksSector(self, x, y, world, 0)) {
- min_dist = dist;
- mdX = x;
- mdY = y;
- result_i_goto_safe_point = true;
- }
- }
- if (result_i_goto_safe_point) {
- createPathToPoint(mdX, mdY, world, self); // NO DANGER POINT
- _drive_target_H = HIDING__DRIVE_POINT_RADIUS;
- /*
- * ngc.setColor("blue"); if (MyStrategy.team_roles[_i]==role.leader)
- * ngc.drawCircle(mdX, mdY, _drive_target_H); ngc.drawCircle(mdX,
- * mdY, _drive_target_H-2); ngc.setColor("red");
- */
- MyStrategy.team_state[_i] = DriveSE.ds_hiding;
- }
- return result_i_goto_safe_point;
- }
- private boolean isEnemiesInPoint(Tank[] at, double px, double py, double r) {
- boolean result = false;
- for (int i = 0; i < at.length; i++) {
- Tank t = at[i];
- if (t.isTeammate() || !isTankAlive(t))
- continue;
- if (t.getDistanceTo(px, py) < r + t.getWidth() / 2)
- return false;
- }
- return result;
- }
- private void aiDriveTeammate(Tank self, World world) {
- Tank[] at = world.getTanks();
- int tc = at.length;
- double max_distance_allowed = 400;
- double current_max_distance = 2000;
- double min_distance_allowed = 150;
- int selected_tank = tc;
- // try find closer
- for (int i = 0; i < tc; i++) {
- Tank t = at[i];
- if (!t.isTeammate() || !isTankAlive(t))
- continue;
- double d = self.getDistanceTo(t);
- if (d < max_distance_allowed && d > 15) {
- selected_tank = i;
- max_distance_allowed = d;
- }
- }
- if (selected_tank == tc) {// closer not finded
- for (int i = 0; i < tc; i++) {
- Tank t = at[i];
- if (!t.isTeammate() || !isTankAlive(t))
- continue;
- double d = self.getDistanceTo(t);
- // find closer of ranged
- if (d < current_max_distance && d > 15) {
- current_max_distance = d;
- selected_tank = i;
- }
- }
- if (selected_tank != tc) {
- // finded
- createPathToPoint(at[selected_tank].getX(),
- at[selected_tank].getY(), world, self);
- _drive_target_H = 20;
- MyStrategy.team_state[_i] = DriveSE.ds_drive_corner;
- b_im_drive_to_corner = true;
- _corner_x = at[selected_tank].getX();
- _corner_y = at[selected_tank].getY();
- }
- } else
- if (max_distance_allowed < min_distance_allowed) {// closer finded!
- // drive from it!
- TankCoords _t = new TankCoords(self);
- double p1x = _t.X + _t.W * 2 * _t.cosA;
- double p1y = _t.Y + _t.W * 2 * _t.sinA;
- double p2x = _t.X - _t.W * 2 * _t.cosA;
- double p2y = _t.Y - _t.W * 2 * _t.sinA;
- double px = _t.X, py = _t.Y;
- boolean point_finded = false;
- double d1 = at[selected_tank].getDistanceTo(p1x, p1y);
- double d2 = at[selected_tank].getDistanceTo(p2x, p2y);
- if (d1 > d2) {
- if (isClearToDriveSector(p1x, p1y, world)) {
- px = p1x;
- py = p1y;
- point_finded = true;
- }
- } else
- if (isClearToDriveSector(p2x, p2y, world)) {
- px = p2x;
- py = p2y;
- point_finded = true;
- }
- if (point_finded) {
- // go far
- // ngc.drawCircle(px, py, 45);
- createPathToPoint(px, py, world, self);
- _drive_target_H = 30;
- MyStrategy.team_state[_i] = DriveSE.ds_drive_corner;
- b_im_drive_to_corner = true;
- _corner_x = px;
- _corner_y = py;
- }
- }
- }
- private boolean aiHideInCorner(Tank self, World world) {
- boolean i_drive_to_hide_in_corner = false;
- double minimum_distance = CONFIG__WORLD_WIDTH;// don't go to diagonal
- if (MyStrategy.team_roles[_i] == role.leader)
- _team_leader_corner = _corners.length;
- int selected_corner = _corners.length;
- for (int i = 0; i < _corners.length; i++) {
- double x = _corners[i].x;
- double y = _corners[i].y;
- // ngc.drawCircle(x, y, CORNER__POINT_RADIUS);
- double dist = self.getDistanceTo(x, y);
- if (dist < minimum_distance) {
- if (isEnemiesInPoint(world.getTanks(), x, y,
- CORNER__PLAYER_RADAR_RADIUS))
- continue;// skip stupid corner;
- minimum_distance = dist;
- selected_corner = i;
- }
- }
- if (MyStrategy.team_roles[_i] != role.leader && _team_healthy_tanks > 1)
- ;// selected_corner = _team_leader_corner;// leader choose corner
- else
- _team_leader_corner = selected_corner;
- if (selected_corner != _corners.length) {
- _corner_x = _corners[selected_corner].x;
- _corner_y = _corners[selected_corner].y;
- if (self.getDistanceTo(_corner_x, _corner_y) > CORNER__POINT_RADIUS) {
- createPathToPoint(_corner_x, _corner_y, world, self);
- _drive_target_H = CORNER__DRIVE_POINT_RADIUS;
- // ngc.setColor("blue");
- /*
- * if (MyStrategy.team_roles[_i]==role.leader)
- * ngc.drawCircle(_corner_x, _corner_y, _drive_target_H);
- * ngc.drawCircle(_corner_x, _corner_y, _drive_target_H-2);
- * ngc.setColor("red");
- */
- i_drive_to_hide_in_corner = true;
- MyStrategy.team_state[_i] = DriveSE.ds_drive_corner;
- }
- }
- return i_drive_to_hide_in_corner;
- }
- private static final int countEnemyTeams(Tank[] at) {
- int count = 6;
- for (int i = 0; i < at.length; i++) {
- Tank t = at[i];
- if (t.isTeammate())
- continue;
- if (t.getTeammateIndex() == 2) {
- count = 1;
- break;
- }
- if (t.getTeammateIndex() == 1) {
- count = 2;
- break;
- }
- }
- if (count == 2) {
- for (int i = 0; i < at.length; i++) {
- Tank t = at[i];
- if (t.isTeammate())
- continue;
- String n = t.getPlayerName();
- if (MyStrategy.team_1_name.equals("")) {
- MyStrategy.team_1_name = n;
- } else {
- if (!n.equals(MyStrategy.team_1_name))
- if (MyStrategy.team_2_name.equals("")) {
- MyStrategy.team_2_name = n;
- break;
- }
- }
- }
- }
- return count;
- }
- private void leaderDoCountEnemyTeamAlive(Tank[] at) {// first should run
- // countEnemyTeams
- MyStrategy.team_1_alive_count = 0;
- MyStrategy.team_2_alive_count = 0;
- MyStrategy.enemy_premium_count = 0;
- for (int i = 0; i < at.length; i++) {
- Tank t = at[i];
- if (t.isTeammate())
- continue;
- double hpp = 100 * t.getCrewHealth() / t.getCrewMaxHealth();
- double armp = 100 * t.getHullDurability()
- / t.getHullMaxDurability();
- if (hpp * armp == 0 || hpp < 50 || armp < 50)
- continue;
- String n = t.getPlayerName();
- if (n.equals(MyStrategy.team_1_name)) {
- MyStrategy.team_1_alive_count++;MyStrategy.enemy_premium_count+=t.getPremiumShellCount();
- } else {
- MyStrategy.team_2_alive_count++;MyStrategy.enemy_premium_count+=t.getPremiumShellCount();
- }
- }
- }
- private boolean isMyEnemyVisible(World world, Tank self) {
- boolean result = true;
- Tank[] all_tanks = world.getTanks();
- int tc = all_tanks.length;
- for (int i = 0; i < tc; ++i) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate())
- continue;
- if (MyStrategy._enemy[_i] == -1) {
- return false;
- } else {
- if (tank.getId() == MyStrategy._enemy[_i]) {
- if (!isTankAlive(tank)) {
- return false;
- } else {
- return true;
- }
- }
- }
- }
- return result;
- }
- private int aiSelectEnemy(Tank self, World world) {
- Tank[] all_tanks = world.getTanks();
- int tc = all_tanks.length;
- int result_selected_tank = tc;
- /*
- * check if need assist
- */
- int teamI = 0;
- switch (MyStrategy.team_why_targets[_i]) {
- case closer_range:
- case target_me_in_closer_range:
- MyStrategy.team_help[_i] = helping.assist_me_please;
- break;
- default:
- MyStrategy.team_help[_i] = helping.no_thanks;
- if (MyStrategy.team_roles[_i] == role.leader) {
- teamI = whoNeedsHelpInTeam();
- if (teamI == _i && !isTeamAssistSameTarget())
- ;// MyStrategy.team_help[_i] = helping.assist_me_please;
- }
- break;
- }
- teamI = whoNeedsHelpInTeam();
- if (teamI != _i&& MyStrategy._team_rush) {
- long newI = MyStrategy._enemy[teamI];
- long myI = MyStrategy._enemy[_i];
- if (myI != newI ) {
- MyStrategy._enemy[_i] = newI;// TODO assist
- if (MyStrategy.team_roles[_i] == role.leader)
- MyStrategy.team_why_targets[_i] = WhyTarget.help_assist;
- else
- MyStrategy.team_why_targets[_i] = WhyTarget.assist_leader;
- }
- }
- /*
- * MyStrategy._enemy[_i] must be defined
- */
- double min_distance_to_enemy = 2000;
- for (int i = 0; i < tc; ++i) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate())
- continue;
- if (MyStrategy._enemy[_i] == -1) {
- double d = tank.getDistanceTo(self);
- if (d < min_distance_to_enemy
- && wayIsClearForShoot(d, _next_x, _next_y, tank.getX(),
- tank.getY(), world)) {
- if (tank.getCrewHealth() == 0
- || tank.getHullDurability() == 0)
- continue;
- result_selected_tank = i;
- min_distance_to_enemy = d;// minimize distance
- MyStrategy.team_why_targets[_i] = WhyTarget.closer_visible;
- }
- } else {
- if (tank.getId() == MyStrategy._enemy[_i]) {
- if (tank.getCrewHealth() == 0
- || tank.getHullDurability() == 0) {
- MyStrategy._enemy[_i] = -1;
- } else {
- result_selected_tank = i;
- MyStrategy.team_why_targets[_i] = WhyTarget.last;
- break;
- }
- }
- }
- }
- if (result_selected_tank == all_tanks.length) {
- double max_distance_to_enemy = 2000;
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double d = tank.getDistanceTo(self);
- if (d < max_distance_to_enemy) {
- max_distance_to_enemy = d;
- MyStrategy._enemy[_i] = tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.closer_range;
- }
- }
- }
- /*
- * check if enemy changed
- */
- if (MyStrategy._enemy[_i] != _last_enemy_id) {
- _last_enemy_id = MyStrategy._enemy[_i];
- _enemy_changed = true;
- } else {
- _enemy_changed = false;
- }
- return result_selected_tank;
- }
- private void aiSpotLowHPEnemy(Tank self, World world) {
- double minimum_distance = 2000;// find closer!
- double myDamage;
- Tank[] all_tanks = world.getTanks();
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double d = tank.getDistanceTo(self);
- if (_premium_count > 0 && d < AIMING__PREMIUM_FIRE_DISTANCE
- || _premium_count >= AIMING__PREMIUM_EXCEED_LIMIT
- && d < AIMING__PREMIUM_FIRE_DISTANCE_MORE)
- myDamage = BULLET__PREMIUM_DAMAGE;
- else
- myDamage = BULLET__REGULAR_DAMAGE;
- if ((tank.getCrewHealth() <= myDamage || tank.getHullDurability() <= myDamage)
- && d < minimum_distance
- && (getBulletFlyToTank(world, tank) == null)) {
- minimum_distance = d;
- MyStrategy._enemy[_i] = tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.low_hp;
- }
- }
- }
- private void aiSpotLowerHPEnemy(Tank self, World world) {
- double minimum_distance = 2000;// find closer!
- Tank[] all_tanks = world.getTanks();
- /*
- * and no visible enemies
- */
- // no visible tanks -> select somebody other with minimum hp!
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double hp = 100 * tank.getCrewHealth() / tank.getCrewMaxHealth();
- double arm = 100 * tank.getHullDurability()
- / tank.getHullMaxDurability();
- double d = tank.getDistanceTo(self);
- if (d < minimum_distance && (hp < 60 || arm < 60)) {
- minimum_distance = d;
- MyStrategy._enemy[_i] = tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.lower_hp;
- }
- }
- }
- private static final boolean isTankAlive(Tank t) {
- return t.getCrewHealth() > 0 && t.getHullDurability() > 0;
- }
- private void aiSpotCloserVisible(Tank self, World world) {
- Tank[] all_tanks = world.getTanks();
- double max_distance_to_enemy = 2000;
- // check distance to current enemy
- if (MyStrategy._enemy[_i] != -1)
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- if (MyStrategy._enemy[_i] == tank.getId()) {
- max_distance_to_enemy = tank.getDistanceTo(self);
- break;
- }
- }
- // find closer visible
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double d = tank.getDistanceTo(self);
- if (d < max_distance_to_enemy
- && wayIsClearForShoot(d, tank.getX(), tank.getY(),
- self.getX(), self.getY(), world)) {
- max_distance_to_enemy = d;
- MyStrategy._enemy[_i] = tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.closer_visible;
- }
- }
- }
- private void aiSpotCloserEnemy(Tank self, World world) {
- double max_distance_to_enemy = 450;
- if (!isMyEnemyVisible(world, self)) {
- max_distance_to_enemy = 2000;
- }
- Tank[] all_tanks = world.getTanks();
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double d = tank.getDistanceTo(self);
- if (d < max_distance_to_enemy
- && wayIsClearForShoot(d, tank.getX(), tank.getY(),
- self.getX(), self.getY(), world)) {
- max_distance_to_enemy = d;
- MyStrategy._enemy[_i] = tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.closer_range;
- }
- }
- }
- private void aiSpotTargetingMeEnemy(Tank self, World world) {
- double max_distance_to_enemy = TEAM__CLOSER_ENEMY_ASSIST_RANGE;
- /*
- * find targeting enemy if my enemy not shooting me or far than other
- * targeting get distance of current enemy if he targets me
- */
- if (MyStrategy._enemy[_i] != -1) {
- Tank[] all_tanks = world.getTanks();
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- if (MyStrategy._enemy[_i] == tank.getId()) {
- double a = Math.abs(tank.getTurretAngleTo(self));
- double d = tank.getDistanceTo(self);
- double maxa_ = getObjAngleOnDistance(d, CONFIG__MY_WIDTH);
- if (a < maxa_
- && wayIsClearForTargeting(self, d, _next_x,
- _next_y, tank.getX(), tank.getY(), world)
- && d < max_distance_to_enemy)
- max_distance_to_enemy = d; //
- }
- }
- }
- /*
- * select other targeting
- */
- Tank targeting_tank = getCloserOfTargetingTankEnemy(self, world,
- max_distance_to_enemy);
- if (targeting_tank != null) {
- max_distance_to_enemy = self.getDistanceTo(targeting_tank);
- MyStrategy._enemy[_i] = targeting_tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.target_me;
- }
- if (max_distance_to_enemy < TEAM__CLOSER_ENEMY_ASSIST_RANGE) {
- MyStrategy.team_why_targets[_i] = WhyTarget.target_me_in_closer_range;
- }
- }
- private static final boolean is_angle_sharp(final double alfa) {
- double a = Math.abs(alfa);
- if (a > PI / 5 && a < (PI - PI / 5))
- return false;
- return true;
- }
- private void aiSpotRotatedToMeEnemy(Tank self, World world) {
- double max_distance_to_enemy = 2000;
- Tank[] all_tanks = world.getTanks();
- for (int i = 0; i < all_tanks.length; i++) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double a = tank.getAngleTo(self);
- double d = tank.getDistanceTo(self);
- if (is_angle_sharp(a)
- && d < max_distance_to_enemy
- && wayIsClearForShootObst(d, tank.getX(), tank.getY(),
- self.getX(), self.getY(), world)) {
- max_distance_to_enemy = d;
- MyStrategy._enemy[_i] = tank.getId();
- MyStrategy.team_why_targets[_i] = WhyTarget.turned_to_me;
- }
- }
- }
- private boolean aiTurnToEnemy(Tank self, Tank enemyTank, Move move) {
- boolean result_im_turn = false;
- double angle_to_enemy = self.getAngleTo(enemyTank);
- double turn_angle;
- double enemyDist = self.getDistanceTo(enemyTank);
- if (enemyDist < TURNING__CLOSER_MAX_DISTANCE)
- turn_angle = TURNING__MIN_TURN_TO_ENEMY_ANGLE;
- else
- turn_angle = TURNING__MIN_TURN_TO_ENEMY_ANGLE_ON_DIST;
- if ((angle_to_enemy > 0 && angle_to_enemy > turn_angle)
- || (angle_to_enemy < 0 && angle_to_enemy > -turn_angle
- + TURNING__ANGLE_ACCURACY)
- ) {
- doTurnRightMax(move);
- result_im_turn = true;
- } else
- if ((angle_to_enemy > 0 && angle_to_enemy < turn_angle
- - TURNING__ANGLE_ACCURACY)
- || (angle_to_enemy < 0 && angle_to_enemy < -turn_angle)) {
- doTurnLeftMax(move);
- result_im_turn = true;
- }
- if (result_im_turn)
- MyStrategy.team_state[_i] = DriveSE.ds_rotate_to_enemy;
- // ngc.drawString("rotate", _x, _y);
- return result_im_turn;
- }
- private void createPathToPoint(final double pX, final double pY,
- World world, Tank self) {
- double myX = self.getX();
- double myY = self.getY();
- double vx = pX - myX;
- double vy = pY - myY;
- double dist = self.getDistanceTo(pX, pY);
- Tank[] tanks = world.getTanks();
- int tc = tanks.length;
- double min_dist = 2000;
- boolean sectorFinded = false;
- double distance = 80;
- double newPx = -1, newPy = -1;
- for (int i = 0; i < tc; i++) {
- double tdist = self.getDistanceTo(tanks[i]);
- if (tdist >= dist - 15 || tdist < 15)
- continue;
- double gamma = getObjAngleOnDistance(tdist - CONFIG__MY_WIDTH / 2,
- CONFIG__MY_WIDTH / 2);
- double tX = tanks[i].getX();
- double tY = tanks[i].getY();
- double fi = getMaxAngleOfUnitOnDist(myX, myY, tanks[i], tX, tY);
- double vxt = tX - myX;
- double vyt = tY - myY;
- double alfa = getVectorAngle(vx, vxt, vy, vyt);
- if (alfa - fi <= gamma && tdist < min_dist) {
- double tank_dist = self.getDistanceTo(tanks[i]);
- double newPointDist = tank_dist - distance;
- double VTx = tX - myX;
- double VTy = tY - myY;
- double sgn_alfa = getVectorAngleWithSign(vx, VTx, vy, VTy);
- double normaVT = Math.sqrt(VTx * VTx + VTy * VTy);
- double newPointVx = VTx * newPointDist / normaVT;
- double newPointVy = VTy * newPointDist / normaVT;
- double newPointX = myX + newPointVx;
- double newPointY = myY + newPointVy;
- // left vector
- double ortoLeftX = VTy * distance / normaVT;
- double ortoLeftY = -VTx * distance / normaVT;
- // right vector
- double ortoRightX = -VTy * distance / normaVT;
- double ortoRightY = VTx * distance / normaVT;
- // left point
- double leftPointX = newPointX + ortoLeftX;
- double leftPointY = newPointY + ortoLeftY;
- // right point
- double rightPointX = newPointX + ortoRightX;
- double rightPointY = newPointY + ortoRightY;
- if (sgn_alfa > 0
- && isClearOfTanksSector(self, leftPointX, leftPointY,
- world, 0)) {
- newPx = leftPointX;
- newPy = leftPointY;
- sectorFinded = true;
- } else
- if (isClearOfTanksSector(self, rightPointX, rightPointY,
- world, 0)) {
- newPx = rightPointX;
- newPy = rightPointY;
- sectorFinded = true;
- }
- if (sectorFinded) {
- _path[0].x = newPx;
- _path[0].y = newPy;
- min_dist = tdist;
- }
- }
- }
- Obstacle[] obst = world.getObstacles();
- int oc = obst.length;
- distance = 150;// TODO 150
- newPx = -1;// TODO sector2_finded=false;
- newPy = -1;
- boolean sector2Finded = false;
- for (int i = 0; i < oc; i++) {
- double tdist = self.getDistanceTo(obst[i]);
- if (tdist >= dist - 15 || tdist < 15)
- continue;
- double gamma = getObjAngleOnDistance(tdist - CONFIG__MY_WIDTH / 2,
- CONFIG__MY_WIDTH / 2);
- double tX = obst[i].getX();
- double tY = obst[i].getY();
- double fi = getMaxAngleOfUnitOnDist(myX, myY, obst[i], tX, tY);
- double vxt = tX - myX;
- double vyt = tY - myY;
- double alfa = getVectorAngle(vx, vxt, vy, vyt);
- if (alfa - fi <= gamma && tdist < min_dist) {
- double tank_dist = self.getDistanceTo(obst[i]);
- double newPointDist = tank_dist - distance;
- double VTx = tX - myX;
- double VTy = tY - myY;
- double sgn_alfa = getVectorAngleWithSign(vx, VTx, vy, VTy);
- double normaVT = Math.sqrt(VTx * VTx + VTy * VTy);
- double newPointVx = VTx * newPointDist / normaVT;
- double newPointVy = VTy * newPointDist / normaVT;
- double newPointX = myX + newPointVx;
- double newPointY = myY + newPointVy;
- // left vector
- double ortoLeftX = VTy * distance / normaVT;
- double ortoLeftY = -VTx * distance / normaVT;
- // right vector
- double ortoRightX = -VTy * distance / normaVT;
- double ortoRightY = VTx * distance / normaVT;
- // left point
- double leftPointX = newPointX + ortoLeftX;
- double leftPointY = newPointY + ortoLeftY;
- // right point
- double rightPointX = newPointX + ortoRightX;
- double rightPointY = newPointY + ortoRightY;
- if (sgn_alfa > 0
- && isClearOfTanksSector(self, leftPointX, leftPointY,
- world, 0)) {
- newPx = leftPointX;
- newPy = leftPointY;
- sector2Finded = true;
- } else
- if (isClearOfTanksSector(self, rightPointX, rightPointY,
- world, 0)) {
- newPx = rightPointX;
- newPy = rightPointY;
- sector2Finded = true;
- }
- if (sector2Finded) {
- _path[0].x = newPx;
- _path[0].y = newPy;
- min_dist = tdist;
- }
- }
- }
- if (!(sectorFinded || sector2Finded)) {
- _path[0].x = pX;
- _path[0].y = pY;
- }
- }
- private void doCalcCoordinates(Tank self, World world) {
- _hp = self.getCrewHealth();
- _armor = self.getHullDurability();
- _x = self.getX();
- _y = self.getY();
- _vx = self.getSpeedX();
- _vy = self.getSpeedY();
- _dv_dt_x = _vx - _last_v_x;
- _dv_dt_y = _vy - _last_v_y;
- _last_v_x = _vx;
- _last_v_y = _vy;
- _next_x = _x + _vx + _dv_dt_x;
- _next_y = _y + _vy + _dv_dt_y;
- _premium_count = self.getPremiumShellCount();
- _tik = world.getTick();
- doCountHealthyTanks(world.getTanks());
- MyStrategy.team_shoot_ready[_i] = self.getRemainingReloadingTime() == 0;
- if (self.getRemainingReloadingTime() == self.getReloadingTime() - 1)
- MyStrategy._team_shoots_count++;// shoot happens :)
- if (!(MyStrategy.team_state[_i] == DriveSE.ds_resurrect))
- MyStrategy.team_state[_i] = DriveSE.ds_stand;
- if (MyStrategy.team_roles[_i] == role.leader) {
- if (!_leader_enemy_teams_counted) {
- teams_count = countEnemyTeams(world.getTanks());
- _leader_enemy_teams_counted = true;
- }
- leaderDoCountEnemyTeamAlive(world.getTanks());
- MyStrategy._can_shoot_time++;
- doCountHealthyTeamTanks(world.getTanks());
- if (MyStrategy.team_1_alive_count < 2
- && MyStrategy.team_2_alive_count < 2
- && MyStrategy._team_healthy_tanks > 1
- || MyStrategy._team_healthy_tanks > MyStrategy.team_1_alive_count
- + MyStrategy.team_2_alive_count)
- MyStrategy._team_rush = true;
- else
- MyStrategy._team_rush = false;
- if (!MyStrategy._team_rush) {
- MyStrategy._team_rush = isEnemiesInPoint(world.getTanks(),
- self.getX(), self.getY(), 400)||
- (MyStrategy._team_premium_count>MyStrategy.enemy_premium_count&&MyStrategy._team_healthy_tanks >= MyStrategy.team_1_alive_count
- + MyStrategy.team_2_alive_count);
- }
- MyStrategy._team_ready_for_shoot = true;
- if (MyStrategy._team_shoots_count >= MyStrategy._team_healthy_tanks) {
- MyStrategy._team_shoots_count = 0;
- // N shoots happend - > wait for other reloading
- }
- if (MyStrategy._team_shoots_count == 0) {
- for (int o = 0; o < MyStrategy.team_shoot_ready.length; o++) {
- if (MyStrategy.team_shoot_ready[o] != true) {
- MyStrategy._team_ready_for_shoot = false;
- break;
- }
- }
- }
- if (MyStrategy._can_shoot_time > MyStrategy._team_healthy_tanks
- * TEAM__SHOOT_TIME_DELTA)
- MyStrategy._can_shoot_time = 0;
- }
- if (_hp * _armor == 0) {
- if (MyStrategy.team_roles[_i] == role.leader) {
- MyStrategy.team_roles[_i] = role.unit;
- MyStrategy.team_roles[teamGetFirstAliveMemberIndex()] = role.leader;
- }
- MyStrategy.team_shoot_ready[_i] = true;
- MyStrategy.team_state[_i] = DriveSE.ds_died;
- double died_x = _x;
- double died_y = _y;
- boolean sector_finded = false;
- Bonus[] bonuses = world.getBonuses();
- for (int o = 0; o < bonuses.length; o++) {
- if (_hp > 0 && bonuses[o].getType() == BonusType.MEDIKIT)
- continue;
- if (_armor > 0 && bonuses[o].getType() == BonusType.REPAIR_KIT)
- continue;
- if (bonuses[o].getType() == BonusType.AMMO_CRATE)
- continue;
- double dist = self.getDistanceTo(bonuses[o]);
- if (dist < TEAM__HELP_RESURRECT_DISTANCE_TO_BONUS) {
- // help
- double bonus_x = bonuses[o].getX();
- double bonus_y = bonuses[o].getY();
- if (!wayIsClear(dist, bonus_x, bonus_y, died_x, died_y,
- world))
- continue;
- double BTx = died_x - bonus_x;
- double BTy = died_y - bonus_y;
- double norma = Math.sqrt(BTx * BTx + BTy * BTy);
- BTx = BTx * 90 / norma;
- BTy = BTy * 90 / norma;
- double Nx = died_x + BTx;
- double Ny = died_y + BTy;
- if (!isOutWorldPointRadius(Nx, Ny, 20)) {
- sector_finded = true;
- break;
- }
- }
- }
- if (sector_finded)
- MyStrategy.team_help[_i] = helping.resurrect_me_please;
- else
- MyStrategy.team_help[_i] = helping.no_thanks;
- }
- else
- if (MyStrategy.team_help[_i] == helping.resurrect_me_please)
- MyStrategy.team_help[_i] = helping.no_thanks;
- /*
- * else{ if (MyStrategy.team_roles[_i] == role.leader)
- * MyStrategy.team_help[_i] = helping.assist_me_please; }
- */
- if (MyStrategy._team_healthy_tanks > 1)
- _i_can_shoot = MyStrategy._can_shoot_time > TEAM__SHOOT_TIME_DELTA
- * _i
- && MyStrategy._can_shoot_time < TEAM__SHOOT_TIME_DELTA
- * (_i + 1);
- else
- _i_can_shoot = true;
- MyStrategy._team_ready_for_shoot = true;
- _i_can_shoot = MyStrategy._team_ready_for_shoot && _i_can_shoot;
- }
- private void doCatchBomb(Move move, double fi, Tank tank, Shell bomb) {
- /*
- * bc==c===ac tank! ||======|| b===0====a ==> ||======|| bd==d===ad
- */
- double BVx = bomb.getSpeedX();
- double BVy = bomb.getSpeedY();
- double myVx = tank.getSpeedX();
- double myVy = tank.getSpeedY();
- double myV = Math.sqrt(myVx * myVx + myVy * myVy);
- if (myV > DODGE__ADJUST_SMALL_VELOCITY) {
- double BmyVa = PI / 2 - getVectorAngle(BVx, myVx, BVy, myVy);
- if (BmyVa > 0)
- doMoveBack(move);
- else
- doMoveForward(move);
- } else {
- double A = tank.getAngle();
- double tVx = Math.cos(A);
- double tVy = Math.sin(A);
- double BTa = PI / 2 - getVectorAngle(BVx, tVx, BVy, tVy);
- if (BTa > 0)
- doMoveBack(move);
- else
- doMoveForward(move);
- }
- }
- private void doCountHealthyTanks(Tank[] all_tanks) {
- _enemy_healthy_tanks = 0;
- for (int i = 0; i < all_tanks.length; ++i) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate())
- continue;
- if (tank.getCrewHealth() > 0 && tank.getHullDurability() > 0)
- _enemy_healthy_tanks++;
- }
- }
- private void doCountHealthyTeamTanks(Tank[] all_tanks) {
- MyStrategy._team_healthy_tanks = 0;
- MyStrategy._team_premium_count = 0;
- for (int i = 0; i < all_tanks.length; ++i) {
- if (all_tanks[i].isTeammate()
- && (all_tanks[i].getCrewHealth() > 0/*
- * CONFIG__MY_MAX_HP
- * BONUS__NEED_HEALTH_PRECENT_EXTRA_SUPER
- */&& all_tanks[i]
- .getHullDurability() > 0/*
- * CONFIG__MY_MAX_ARM
- * BONUS__NEED_ARMOR_PRECENT_EXTRA_SUPER
- */)) {
- MyStrategy._team_healthy_tanks++;MyStrategy._team_premium_count+=all_tanks[i].getPremiumShellCount();
- }
- }
- }
- private void doDodge(Shell bomb, Tank me, Move move, World world) {
- double H = 10;
- double Bx = bomb.getX();
- double By = bomb.getY();
- double BVx = bomb.getSpeedX();
- double BVy = bomb.getSpeedY();
- double Tx = me.getX();
- double Ty = me.getY();
- double DIST = getDistancePointToLine(Bx, By, BVx, BVy, Tx, Ty);
- double BD = bomb.getHeight() / 2;
- double D = Math.abs(DIST - BD);
- double fi = getTankAngleToLine(me, BVx, BVy);
- double bomb_dist = me.getDistanceTo(bomb);
- double myX = me.getX();
- double myY = me.getY();
- if (isOnCorner(myX, myY)) {
- doDodgeEscape(move, fi, me, bomb, world);
- } else {
- if (Math.abs(fi) > DODGE__RICOCHETE_ANGLE + DODGE__TURN_ANGLE_DELTA) {
- if (D > H
- && bomb_dist < DODGE__MAX_DISTANCE_TO_AVOID_BY_TURNING
- && Math.abs(fi) < DODGE__MIN_ESCAPE_ANGLE) {
- doTurnDodge(move, fi);
- } else {
- doDodgeEscape(move, fi, me, bomb, world);
- }
- } else {
- if (Math.abs(fi) > DODGE__RICOCHETE_ANGLE) {
- doTurnDodge(move, fi);
- } else {
- /*
- * some mathematics...
- */
- double BV = Math.sqrt(BVx * BVx + BVy * BVy);
- double b_fly_t = bomb_dist / BV;
- TankCoords t_c = new TankCoords(me);
- double TVx = t_c.cosA;
- double TVy = t_c.sinA;
- double fi_TB = getVectorAngle(TVx, BVx, TVy, BVy);
- boolean bomb_from_forward = (fi_TB > PI / 2);
- double my_velocity = t_c.getVelocityForward();
- double my_dV_dt;
- double left_corner_x, left_corner_y, right_corner_x, right_corner_y;
- if (bomb_from_forward) {
- my_dV_dt = DODGE__MAX_DV_DT_FORWARD;
- left_corner_x = t_c.Xlf;
- left_corner_y = t_c.Ylf;
- right_corner_x = t_c.Xrf;
- right_corner_y = t_c.Yrf;
- } else {
- my_dV_dt = DODGE__MAX_DV_DT_zBACK;
- left_corner_x = t_c.Xrb;
- left_corner_y = t_c.Yrb;
- right_corner_x = t_c.Xlb;
- right_corner_y = t_c.Ylb;
- }
- boolean bomb_from_left_side = fi > 0;
- boolean bomb_from_right_side = !bomb_from_left_side;
- double dist_to_drive = my_velocity * b_fly_t + my_dV_dt
- * b_fly_t * b_fly_t / 2;
- double my_corner_x, my_corner_y;
- if (bomb_from_left_side) {
- my_corner_x = left_corner_x + TVx * dist_to_drive;
- my_corner_y = left_corner_y + TVy * dist_to_drive;
- } else {
- my_corner_x = right_corner_x + TVx * dist_to_drive;
- my_corner_y = right_corner_y + TVy * dist_to_drive;
- }
- double BVCx = my_corner_x - Bx;
- double BVCy = my_corner_y - By;
- double bullet_angle_to_corner = getVectorAngleWithSign(BVx,
- BVCx, BVy, BVCy);
- boolean corner_in_left_side_of_bullet = (bullet_angle_to_corner < 0);
- boolean corner_in_right_side_of_bullet = !corner_in_left_side_of_bullet;
- boolean i_can_catch_this_bomb = ((bomb_from_left_side && corner_in_left_side_of_bullet) || (bomb_from_right_side && corner_in_right_side_of_bullet));
- /*
- * mathematics ends! ^_^
- */
- if (
- bomb.getType() != ShellType.PREMIUM
- && i_can_catch_this_bomb
- )
- doCatchBomb(move, fi, me, bomb);
- else
- if (Math.abs(fi) > DODGE__MIN_ESCAPE_ANGLE) {
- doDodgeEscape(move, fi, me, bomb, world);
- } else {
- doTurnToDodgeEscape(move, fi);
- }
- }
- }
- }
- }
- private void doDodgeEscape(Move move, final double fi, Tank tank,
- Shell bomb, World world) {
- /*
- * bc==c===ac tank! ||======|| b===0====a ==> ||======|| bd==d===ad
- */
- TankCoords tank_coords = new TankCoords(tank);
- double W = tank_coords.W;
- double tVx = tank_coords.cosA;
- double tVy = tank_coords.sinA;
- double Xa = tank_coords.Xf;
- double Ya = tank_coords.Yf;
- double Xb = tank_coords.Xb;
- double Yb = tank_coords.Yb;
- double dVx = tank.getSpeedX();
- double dVy = tank.getSpeedY();
- double dVa = getVectorAngle(dVx, tVx, dVy, tVy);
- double dV = Math.sqrt(dVx * dVx + dVy * dVy) * Math.cos(dVa);
- double Da = DODGE__ADJUST_VELOCITY_COEFF
- * dV
- + getDistancePointToLine(bomb.getX(), bomb.getY(),
- bomb.getSpeedX(), bomb.getSpeedY(), Xa, Ya);
- double Db = DODGE__ADJUST_DRIVE_BACK_COEFF
- * getDistancePointToLine(bomb.getX(), bomb.getY(),
- bomb.getSpeedX(), bomb.getSpeedY(), Xb, Yb);
- if (Da > Db) {
- double nextx = Xa + (W / 5) * tVx;
- double nexty = Ya + (W / 5) * tVy;
- if (isClearToDriveSector(nextx, nexty, world))
- doMoveForward(move);
- else {
- doMoveBack(move);
- }
- } else {
- double nextx = Xb - (W / 5) * tVx;
- double nexty = Yb - (W / 5) * tVy;
- if (isClearToDriveSector(nextx, nexty, world))
- doMoveBack(move);
- else {
- doMoveForward(move);
- }
- }
- }
- private void doDriveRoundLeftBack(Move move, final double d) {
- move.setRightTrackPower(-1);
- if (d < DRIVE__ADJUST_MIN_DISTANCE)
- move.setLeftTrackPower(DRIVE__ADJUST_TURN_DIFFERENCE_MAX);
- else
- move.setLeftTrackPower(-driveCoeff(d)/**
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * DRIVE_ADJUST_TURN_DIFFERENCE_MAX
- */
- );
- }
- private void doDriveRoundLeftForward(Move move, final double d) {
- move.setRightTrackPower(1);
- if (d < DRIVE__ADJUST_MIN_DISTANCE)
- move.setLeftTrackPower(-1);
- else
- move.setLeftTrackPower(driveCoeff(d));
- }
- private void doDriveRoundRightBack(Move move, final double d) {
- move.setLeftTrackPower(-1);
- if (d < DRIVE__ADJUST_MIN_DISTANCE)
- move.setRightTrackPower(DRIVE__ADJUST_TURN_DIFFERENCE_MAX);
- else
- move.setRightTrackPower(-driveCoeff(d)/**
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- * DRIVE_ADJUST_TURN_DIFFERENCE_MAX
- */
- );
- }
- private void doDriveRoundRightForward(Move move, final double d) {
- move.setLeftTrackPower(1);
- if (d < DRIVE__ADJUST_MIN_DISTANCE)
- move.setRightTrackPower(-1);
- else
- move.setRightTrackPower(driveCoeff(d));
- }
- private void doMoveBack(Move move) {
- move.setLeftTrackPower(-1);
- move.setRightTrackPower(-1);
- }
- private void doMoveForward(Move move) {
- move.setLeftTrackPower(1);
- move.setRightTrackPower(1);
- }
- private void doTurnDodge(Move move, final double fi) {
- if (fi > DODGE__TURN_DODGE_ANGLE_ACCURACY_DELTA)
- doTurnLeftMax(move);
- else
- if (fi < -DODGE__TURN_DODGE_ANGLE_ACCURACY_DELTA)
- doTurnRightMax(move);
- }
- private void doTurnLeftBackZero(Move move) {
- move.setLeftTrackPower(-1);
- move.setRightTrackPower(0);
- }
- private void doTurnLeftForwardZero(Move move) {
- move.setLeftTrackPower(0);
- move.setRightTrackPower(1);
- }
- private void doTurnLeftMax(Move move) {
- move.setLeftTrackPower(-1);
- move.setRightTrackPower(1);
- }
- private void doTurnRightBackZero(Move move) {
- move.setLeftTrackPower(0);
- move.setRightTrackPower(-1);
- }
- private void doTurnRightForwardZero(Move move) {
- move.setLeftTrackPower(1);
- move.setRightTrackPower(0);
- }
- private void doTurnRightMax(Move move) {
- move.setLeftTrackPower(1);
- move.setRightTrackPower(-1);
- }
- private void doTurnToDodgeEscape(Move move, final double fi) {
- if (fi > 0)
- doTurnRightMax(move);
- else
- doTurnLeftMax(move);
- }
- private void driveToPoint(final double pX, final double pY, Move move,
- Tank me, final double objH, World world) {
- double angleToPoint = me.getAngleTo(pX, pY);
- TankCoords t_c = new TankCoords(me);
- double myForwardX = t_c.Xf;
- double myForwardY = t_c.Yf;
- double myBackX = t_c.Xb;
- double myBackY = t_c.Yb;
- boolean isForwardClear = !isOutWorldPointRadius(myForwardX, myForwardY,
- 20);
- boolean isBackClear = !isOutWorldPointRadius(myBackX, myBackY, 20);
- double distp = me.getDistanceTo(pX, pY);
- double obj_angle = getObjAngleOnDistance(distp, objH);
- double ride_angle;
- if (distp <= DRIVE__MIN_DISTANCE_RIDE_ANGLE_INCREASED)
- ride_angle = obj_angle;
- else
- if (distp <= DRIVE__MAX_DISTANCE_RIDE_ANGLE_INCREASED)
- ride_angle = obj_angle
- + (distp - DRIVE__MIN_DISTANCE_RIDE_ANGLE_INCREASED)
- * (DRIVE__MAX_RIDE_ANGLE - obj_angle)
- / (DRIVE__MAX_DISTANCE_RIDE_ANGLE_INCREASED - DRIVE__MIN_DISTANCE_RIDE_ANGLE_INCREASED);
- else
- ride_angle = DRIVE__MAX_RIDE_ANGLE;
- double fi_forward = PI / 2;
- Rotate r = Rotate.none;
- if ((angleToPoint > fi_forward) || (angleToPoint < -fi_forward)) {
- if (!isBackClear)
- r = getTankOnBoundRotation(myBackX, myBackY, 100, me);
- } else
- if (!isForwardClear)
- r = getTankOnBoundRotation(myForwardX, myForwardY, 100, me);
- switch (r) {
- case left:
- if (!isBackClear)
- doTurnLeftForwardZero(move);
- if (!isForwardClear)
- doTurnLeftBackZero(move);
- break;
- case right:
- if (!isBackClear)
- doTurnRightForwardZero(move);
- if (!isForwardClear)
- doTurnRightBackZero(move);
- break;
- case none:
- if (angleToPoint > ride_angle && angleToPoint < PI - ride_angle
- // || !(isForwardClear && isBackClear)
- ) {
- // turn!
- // on right side
- if (angleToPoint > fi_forward) {
- // move back
- doDriveRoundRightBack(move, distp);
- } else {
- // move forward
- doDriveRoundRightForward(move, distp);
- }
- } else
- if ((angleToPoint < -ride_angle)
- && (angleToPoint > -PI + ride_angle)) {
- // turn!
- // on left side
- if (angleToPoint < -fi_forward) {
- // move back
- doDriveRoundLeftBack(move, distp);
- } else {
- // move forward
- doDriveRoundLeftForward(move, distp);
- }
- } else {
- // move!
- // log.info("move!!");
- if ((angleToPoint > fi_forward)
- || (angleToPoint < -fi_forward)) {
- // move back
- doMoveBack(move);
- } else {
- // move forward
- doMoveForward(move);
- }
- }
- }
- }
- private Shell getBulletFlyToTank(World world, Tank self) {
- double min_distance = 2000;
- Shell[] bombs = world.getShells();
- int selected_bomb = bombs.length;
- int countBombs = bombs.length;
- for (int j = 0; j < countBombs; j++) {
- // if (bombs[j].getPlayerName().equals(self.getPlayerName()))
- // continue;
- double distance_to_bomb = self.getDistanceTo(bombs[j]);
- // double bomb_Vx = bombs[j].getSpeedX();
- // double bomb_Vy = bombs[j].getSpeedY();
- // double bomb_speed = Math
- // .sqrt(bomb_Vx * bomb_Vx + bomb_Vy * bomb_Vy);
- // double time_bomb_to_fly = distance_to_bomb / bomb_speed;
- double myNextX = self.getX();// + self.getSpeedX() *
- // time_bomb_to_fly
- // + 0.5 * time_bomb_to_fly * time_bomb_to_fly * _dv_dt_x;
- double myNextY = self.getY();// + self.getSpeedY() *
- // time_bomb_to_fly
- // + 0.5 * time_bomb_to_fly * time_bomb_to_fly * _dv_dt_y;
- if ((distance_to_bomb < min_distance)
- && isBombForTank(self, bombs[j], myNextX, myNextY)) {
- min_distance = distance_to_bomb;
- selected_bomb = j;
- }
- }
- if (selected_bomb != bombs.length)
- return bombs[selected_bomb];
- else
- return null;
- }
- private Tank getCloserOfTargetingTankEnemy(Tank self, World world,
- final double max_distance_to_enemy) {
- Tank[] all_tanks = world.getTanks();
- double d_max = max_distance_to_enemy;
- int selected_tank = all_tanks.length;
- for (int i = 0; i < all_tanks.length; ++i) {
- Tank tank = all_tanks[i];
- if (tank.isTeammate() || !isTankAlive(tank))
- continue;
- double a = Math.abs(tank.getTurretAngleTo(self));
- double d = tank.getDistanceTo(self);
- double maxa_ = getObjAngleOnDistance(d, CONFIG__MY_WIDTH);
- if (a < maxa_ && d < d_max) {
- d_max = d;// find closer!
- selected_tank = i;
- }
- }
- if (selected_tank != all_tanks.length)
- return all_tanks[selected_tank];
- else
- return null;
- }
- private void initPathArr() {
- for (int l = 0; l < this._path.length; l++) {
- this._path[l] = new Point();
- this._path[l].x = -1;
- }
- for (int l = 0; l < _corners.length; l++) {
- this._corners[l] = new Point();
- }
- // bottom right
- this._corners[0].x = CONFIG__WORLD_WIDTH - 2 * CORNER__POINT_DIST;
- this._corners[0].y = CONFIG__WORLD_HEIGHT - CORNER__POINT_DIST;
- // bottom left
- this._corners[1].x = 2 * CORNER__POINT_DIST;
- this._corners[1].y = CONFIG__WORLD_HEIGHT - CORNER__POINT_DIST;
- // bottom 1
- this._corners[2].x = CONFIG__WORLD_WIDTH - 4 * CORNER__POINT_DIST;
- this._corners[2].y = CONFIG__WORLD_HEIGHT - CORNER__POINT_DIST;
- // bottom 2
- this._corners[3].x = 4 * CORNER__POINT_DIST;// 4
- this._corners[3].y = CONFIG__WORLD_HEIGHT - CORNER__POINT_DIST;
- // bottom 3
- this._corners[4].x = 6 * CORNER__POINT_DIST;// 6
- this._corners[4].y = CONFIG__WORLD_HEIGHT - CORNER__POINT_DIST;
- // top right
- this._corners[5].x = CONFIG__WORLD_WIDTH - 2 * CORNER__POINT_DIST;
- this._corners[5].y = CORNER__POINT_DIST;
- // top left
- this._corners[6].x = 2 * CORNER__POINT_DIST;
- this._corners[6].y = CORNER__POINT_DIST;
- // top 1
- this._corners[7].x = CONFIG__WORLD_WIDTH - 4 * CORNER__POINT_DIST;
- this._corners[7].y = CORNER__POINT_DIST;
- // top 2
- this._corners[8].x = 4 * CORNER__POINT_DIST;// 4
- this._corners[8].y = CORNER__POINT_DIST;
- // top 3
- this._corners[9].x = 6 * CORNER__POINT_DIST;// 6
- this._corners[9].y = CORNER__POINT_DIST;
- // right up1
- this._corners[10].x = CONFIG__WORLD_WIDTH - CORNER__POINT_DIST;
- this._corners[10].y = 3 * CORNER__POINT_DIST;
- // right down2
- this._corners[11].x = CONFIG__WORLD_WIDTH - CORNER__POINT_DIST;
- this._corners[11].y = CONFIG__WORLD_HEIGHT - 3 * CORNER__POINT_DIST;
- // left up1
- this._corners[12].x = CORNER__POINT_DIST;
- this._corners[12].y = 3 * CORNER__POINT_DIST;
- // left down2
- this._corners[13].x = CORNER__POINT_DIST;
- this._corners[13].y = CONFIG__WORLD_HEIGHT - 3 * CORNER__POINT_DIST;
- }
- private boolean isTeamAssistSameTarget() {
- long target = MyStrategy._enemy[_i];
- if (target == -1)
- return false;
- for (int k = 0; k < MyStrategy._enemy.length; k++) {
- if (MyStrategy._enemy[k] != target)
- return false;
- }
- return true;
- }
- private int teamGetFirstAliveMemberIndex() {
- for (int k = 0; k < MyStrategy.team_state.length; k++) {
- if (MyStrategy.team_state[k] != DriveSE.ds_died)
- return k;
- }
- return -1;
- }
- @Override
- public void move(Tank self, World world, Move move) {
- // ngc.update(world);
- doCalcCoordinates(self, world);
- if (_hp * _armor == 0)
- return;
- if (b_it_is_a_first_tick) {
- b_it_is_a_first_tick = _tik < 100;
- MyStrategy._ids[_i] = self.getId();
- }
- b_im_avoiding_bomb = aiDodgeBomb(self, world, move);
- if (!b_it_is_a_time_to_drive) {
- b_it_is_a_time_to_drive = _enemy_healthy_tanks <= TACTIC__MAX_ENEMIES_TO_DRIVE;
- if (!(b_im_avoiding_bomb || MyStrategy.team_state[_i] == DriveSE.ds_resurrect))
- b_im_drive_to_corner = aiHideInCorner(self, world);
- } else
- b_im_drive_to_corner = false;
- if (!MyStrategy._team_rush)
- aiDriveTeammate(self, world);
- aiDefineBonusPrioritets();
- if (!(b_im_avoiding_bomb))
- b_im_goto_bonus = aiGotoBonus(world, self);
- else
- b_im_goto_bonus = false;
- aiSpotRotatedToMeEnemy(self, world);// can change MyEnemy variable
- aiSpotLowerHPEnemy(self, world);// can change MyEnemy variable
- aiSpotLowHPEnemy(self, world);// can change MyEnemy variable
- aiSpotTargetingMeEnemy(self, world);// can change MyEnemy variable
- aiSpotCloserVisible(self, world);// can change MyEnemy variable
- aiSpotCloserEnemy(self, world);// can change MyEnemy variable
- int selected_tank = aiSelectEnemy(self, world);
- b_i_am_do_manevr = aiDoShootAndManevr(self, world, selected_tank, move);
- aiDoResurrectTeammate(world, self);
- if (!b_im_avoiding_bomb
- && (!b_i_am_do_manevr || MyStrategy.team_state[_i] == DriveSE.ds_resurrect))
- b_im_drive_to_path_point = aiDrivePath(self, move, world);
- else
- b_im_drive_to_path_point = false;
- _last_drive_state = MyStrategy.team_state[_i];
- /*
- * if (MyStrategy.team_help[_i] == helping.assist_me_please)
- * ngc.drawString("assist", _x-30, _y-30);
- * ngc.drawString(MyStrategy.team_why_targets[_i].toString(), _x-10,
- * _y-10);
- */
- }
- // public static NetGraphClient ngc;
- @Override
- public TankType selectTank(int tankIndex, int teamSize) {
- // ngc = new NetGraphClient("localhost", 8888);
- initPathArr();
- _i = tankIndex;
- if (MyStrategy.team_state == null) {
- MyStrategy.team_state = new DriveSE[teamSize];
- MyStrategy.team_why_targets = new WhyTarget[teamSize];
- MyStrategy.team_help = new helping[teamSize];
- MyStrategy.team_roles = new role[teamSize];
- MyStrategy.team_shoot_ready = new boolean[teamSize];
- MyStrategy._enemy = new long[teamSize];
- for (int i = 0; i < MyStrategy._enemy.length; i++)
- MyStrategy._enemy[i] = -1;
- for (int i = 0; i < MyStrategy.team_why_targets.length; i++)
- MyStrategy.team_why_targets[i] = WhyTarget.no_target;;
- MyStrategy._ids = new long[teamSize];
- MyStrategy.team_roles[_i] = role.leader;
- } else {
- MyStrategy.team_roles[_i] = role.unit;
- }
- return TankType.MEDIUM;
- }
- private int whoNeedsHelpInTeam() {
- for (int k = 0; k < MyStrategy.team_help.length; k++)
- if (MyStrategy.team_help[k] == helping.assist_me_please)
- return k;
- return _i;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement