import com.ibm.rally.Car; import com.ibm.rally.ICar; import com.ibm.rally.*; import java.awt.geom.AffineTransform; import java.awt.Shape; /** * This is the class that you must implement to enable your car within * the CodeRally track. Adding code to these methods will give your car * it's personality and allow it to compete. */ public class RallyCar extends Car { protected class FieldPoint implements IObject { public FieldPoint(double x, double y) { this.x = x; this.y = y; } public FieldPoint(IObject obj) { this.x = obj.getX(); this.y = obj.getY(); } public double getX() { return x; } public double getY() { return y; } public double getDistanceTo(IObject obj) { return getDistanceTo(obj.getX(), obj.getY()); } public double getDistanceTo(double xx, double yy) { double dx = xx - x; double dy = yy - y; return Math.sqrt(dx * dx + dy * dy); } public int getBearing(double dx, double dy) { double d = Math.atan2(dx, dy); return 180 - (int)(d * 57.295779512999999D); } public int getHeadingTo(IObject obj) { return getBearing(obj.getX() - x, obj.getY() - y); } public int getHeadingTo(double xx, double yy) { return getBearing(xx - x, yy - y); } public double x, y; } FieldPoint points[] = new FieldPoint [120]; double [][] route_rating = null; boolean infinite_fuel; int checknum, checkpointsNum, first_used_defined_point, desired_point; int flags, iter1, bad_target_cnt = 0; IObject target; int state, strategy_state; double speedsum = 0; int speedn = 0; double x1, y1; //utilitary variables int curCheckpoint, curGasDepot; /** * @see com.ibm.rally.Car#getName() */ public String getName() { return "AI"; } /** * @see com.ibm.rally.Car#getSchoolName() */ public String getSchoolName() { return "IFMO #1"; } /** * @see com.ibm.rally.Car#getColor() */ public byte getColor() { return CAR_BLUE; } public double getDistToSegment(IObject car, IObject p1, IObject p2) { double a = p1.getDistanceTo(p2); double b = p1.getDistanceTo(car); double c = p2.getDistanceTo(car); double dist; dist = (b 0.01 && a > 0.01) { double cs = (a*a + b*b - c*c)/2/a/b; if (cs > 0.01 && cs*b 0.001) { p.x /= l; p.y /= l; } } public int correctAngle(int angle) { while (angle <= -180) angle += 360; while (angle > 180) angle -= 360; return angle; } public int getRelativeAngle(double x, double y) { int h = getHeadingTo(x, y); int m = getHeading(); return correctAngle(h - m); } public int getRelativeAngle(IObject obj) { return getRelativeAngle(obj.getX(), obj.getY()); } public double getApproximateDistTo(IObject obj) { return getDistanceTo(obj) + Math.abs(getRelativeAngle(obj)); } public int getDesiredSteeringTo(int angle) { int value = Math.abs(angle); int res; if (value >= 40) res = MAX_STEER_RIGHT; else if (value >= 15) res = MAX_STEER_RIGHT*2/3; else if (value >= 8) res = MAX_STEER_RIGHT/2; else res = MAX_STEER_RIGHT/3; if (angle < 0) res = -res; return res; } public int getDesiredSteeringTo(IObject obj) { return getDesiredSteeringTo(getRelativeAngle(obj)); } public int getDesiredThrottle(double dist, int angle) { int res; //new formula double sp = getSpeed(); if (dist < 25) res = 0; else { res = (int)Math.round((dist/4 - sp)*20*3/4); } if (res > MAX_THROTTLE) res = MAX_THROTTLE; if (res < MIN_THROTTLE) res = MIN_THROTTLE; return res; } public int getDesiredThrottle(IObject obj) { return getDesiredThrottle(getDistanceTo(obj), getRelativeAngle(obj)); } public void calcPoint(ICar p1, IObject p2, IObject p3, int index, boolean skip) { double l; FieldPoint v1 = new FieldPoint(p1.getX() - p2.getX(), p1.getY() - p2.getY()); FieldPoint v2 = new FieldPoint(p3.getX() - p2.getX(), p3.getY() - p2.getY()); FieldPoint v = new FieldPoint(v1.x + v2.x, v1.y + v2.y); int angle = Math.abs(correctAngle(p2.getHeadingTo(p1) - p2.getHeadingTo(p3))); int mul = 0; if (angle < 160) { mul = (160 - angle)*20/(160-130); if (mul > 20) mul = 20; } l = vecLength(v); if (Math.abs(l) < 0.001) vecMul(v, 0); else if (skip) vecMul(v, 80/l); else { vecMul(v, mul/l); FieldPoint head = new FieldPoint( Math.sin(p1.getHeading()) * 20, -Math.cos(p1.getHeading()) * 20 ); v.x -= head.x; v.y -= head.y; if ((l = vecLength(v)) > 20) vecMul(v, 20/l); } points[first_used_defined_point + index].x = p2.getX() + v.x; points[first_used_defined_point + index].y = p2.getY() + v.y; } public boolean mayHit(double x, double y) { double dist = 3200D; return x*x + y*y < dist; } public boolean checkForCarHit(double x, double y, double h) { java.awt.geom.Rectangle2D rect = new java.awt.geom.Rectangle2D.Double(-20D - 7.5D, -30D - 10D, 40D + 15D, 60D + 20D); java.awt.geom.Rectangle2D rect2 = new java.awt.geom.Rectangle2D.Double(-20D - 7.5D, -30D - 10D, 40D + 15D, 60D + 20D); double hh = h / (360 / 2 / Math.PI); AffineTransform transform = AffineTransform.getTranslateInstance(x, y); transform.concatenate(AffineTransform.getRotateInstance(hh)); Shape shape2 = transform.createTransformedShape(rect2); return shape2.intersects(rect); } FieldPoint getTargetFromNum(int num) { num = num & 0xff; if (num == 0) return null; return points[num - 1]; } /** * @see com.ibm.rally.Car#initialize() */ public void initialize() { infinite_fuel = false; strategy_state = 0; desired_point = -1; checkpointsNum = getCheckpoints().length; IObject objs[] = getCheckpoints(); for (int i=0; i= 0) desired_checkpoint = (desired_checkpoint + 1)%checkpointsNum; for (int i=1; i getApproximateDistTo(getCheckpoints()[i])*points2) targetnum = i; } curCheckpoint = targetnum; strategy_state = 1; stop = true; break; case 1: //go throught checkpoints speedn++; double speed = getSpeed(); speedsum += speed; //System.out.println("state 1 "+ getSpeed() + " " + speedsum/speedn); if (event == 1) { desired_point = -1; strategy_state = 2; //low fuel } else { //checkpoint passed if ((event == 3) || (event == 4)) { IObject ch[] = getCheckpoints(); boolean skip_checkpoint = isDangerousCheckpoint((curCheckpoint + 1)%checkpointsNum); setHeadlightsOn(skip_checkpoint); curCheckpoint = (curCheckpoint + 1)%checkpointsNum; calcPoint( this, ch[curCheckpoint], ch[(curCheckpoint + 1)%checkpointsNum], 0, skip_checkpoint ); desired_point = first_used_defined_point; } if (desired_point != -1) targetnum = desired_point; else targetnum = curCheckpoint; stop = true; } break; case 2: //looking for gas station //System.out.println("state 2"); targetnum = 0; if (event == 7) { if (targetnum == curGasDepot) targetnum++; for (int i=1; i < 3; i++) if (i != curGasDepot) if (getApproximateDistTo(getFuelDepots()[targetnum]) > getApproximateDistTo(getFuelDepots()[i])) targetnum = i; event = 0; } else { for (int i=1; i<3; i++) if (getApproximateDistTo(getFuelDepots()[targetnum]) > getApproximateDistTo(getFuelDepots()[i])) targetnum = i; } curGasDepot = targetnum; targetnum += checkpointsNum; strategy_state = 3; flags |= 0x0100; stop = true; break; case 3: //go to gas station //System.out.println("state 3"); if (event == 7) { strategy_state = 2; } else if (event == 3) strategy_state = 4; else if (event == 6) strategy_state = 0; else { flags |= 0x0100; stop = true; } targetnum = curGasDepot + checkpointsNum; break; case 4: //refill fuel //System.out.println("state 4 distance = " + getDistanceTo(target)); if ((event == 4) || (event == 5)) strategy_state = 2; else if ((event == 2) || (event == 6)) strategy_state = 0; else { flags |= 0x0200; flags |= 0x0100; stop = true; } targetnum = curGasDepot + checkpointsNum; break; default: break; } return (targetnum + 1)|flags; } /** * @see com.ibm.rally.Car#move(int, boolean, ICar, ICar) * Put the car in reverse for a few moves if you collide with another car. * Go toward the first gas depot. */ public void move(int lastMoveTime, boolean hitWall, ICar collidedWithCar, ICar hitBySpareTire) { if (getFuel() == 0) { enterProtectMode(); } ICar op[] = getOpponents(); if (isReadyToThrowSpareTire()) { for (int i=0; i= MAX_CLOCK_TICKS - getClockTicks()) infinite_fuel = true; if (!infinite_fuel) { if (getFuel()<30) sendEvent(1); if (getFuel()>=95) sendEvent(2); } else { sendEvent(6); enterProtectMode(); } double d = getDistanceTo(target); if (d <= 25) { sendEvent(3); } else if (d <= 40) { sendEvent(4); } else sendEvent(5); if (Math.abs(d - 35)<10 && Math.abs(Math.abs(getRelativeAngle(target)) - 40)<15) { bad_target_cnt++; } else { bad_target_cnt = 0; } if (bad_target_cnt > 10 && strategy_state == 3) { sendEvent(7); bad_target_cnt = 0; } if ((flags & 0x0200) > 0) { setThrottle(0); setSteeringSetting(0); } else if ((flags & 0x0100) > 0) { setThrottle(getDesiredThrottle(target)); setSteeringSetting(getDesiredSteeringTo(target)); } else { setThrottle(MAX_THROTTLE); setSteeringSetting(getDesiredSteeringTo(target)); } } }