protected void updatePos() {
    super.updatePos();
    float speed = getSpeed();
    float speed_lim = getRoad().getSpeedLimit();
    int dist_ints = next_ints_dist();
    int dist_obst = dist_ints;
    int dist_new_car = dist_ints;
    if (front_car != null) {
      dist_new_car = getDist(front_car);
      if (dist_new_car < dist_obst) dist_obst = dist_new_car;
    }
    if ((float) dist_obst > 4F * speed) {
      float a = 0.0F;
      if ((double) speed < 0.8D * (double) speed_lim) a = 50F;
      else if (speed < speed_lim) a = 10F;
      else if (speed > speed_lim) a = 10F * (speed_lim - speed);
      if ((double) (speed + a) < 10D) a = 10F - speed;
      accelerate(a);
    } else if (dist_ints < 6) {
      boolean stop_inter = false;

      if (!stop_inter) {
        int dir = random.nextInt(3);
        Road roads[] = nextInter.getRoads();
        int d[] = new int[3];
        int direction = getDir();
        d[0] = RoadGrid.getLeftDir(direction);
        d[1] = direction;
        for (d[2] = RoadGrid.getRightDir(direction); roads[d[dir]] == null; dir = random.nextInt(3))
          ;
        accelerate(-50F);
        make_Turn(d[dir]);
      }
      if (watch_red || front_car != null) {
        accelerate(-50F);
        stop_inter = true;
      }
    } else if (speed > 12F) accelerate(-(speed * speed) / (float) (4 * dist_ints));
    else accelerate(10F - speed);

    if (front_car != null) {
      double diff;
      if (getRoad().getDir() == getDir()
          && (getDist((Car) this, front_car, getDir()) < 2 * getSpeed())) {
        if (getSpeed() > front_car.getSpeed()) diff = getSpeed() - front_car.getSpeed();
        else diff = -1 * (getSpeed() - front_car.getSpeed());
        accelerate(-1 * (float) (diff / 2.0f), 2);

        if ((int) Math.sqrt(Coords.distSqrd(front_car.getPos(), getPos())) < 20)
          accelerate((float) (-1 * getSpeed() * getSpeed() / (0.01)), 20);
      }
    }
  }
 private Intersection findNextInter() {
   Road r = getRoad();
   if (getDir() == r.getDir()) nextInter = r.getEndIntersection();
   else nextInter = r.getStartIntersection();
   TrafficControl tc = nextInter.getTrafficControl();
   if (tc != null && tc.getType() == 0) {
     int oppDir = RoadGrid.getOppDir(getDir());
     synchronized (tc) {
       ((TrafficSignal) tc).addListener(this, oppDir);
     }
     watch_red = ((TrafficSignal) tc).getSignalState(oppDir) == 0;
   }
   return nextInter;
 }
 private void make_Turn(int dir) {
   TrafficControl traf_cont = nextInter.getTrafficControl();
   int oppDir = RoadGrid.getOppDir(getDir());
   boolean listen = false;
   if (traf_cont != null && traf_cont.getType() == 0) listen = true;
   if (!watch_red && !nextInter.isOccupied()) {
     if (listen)
       synchronized (traf_cont) {
         ((TrafficSignal) traf_cont).removeListener(this, oppDir);
       }
     synchronized (nextInter) {
       crossIntersection(nextInter, dir);
       this.accelerate((getRoad().getSpeedLimit() - getSpeed()) * 10, 0);
     }
     findNextInter();
   }
 }