boolean roadTest(int tx, int ty) {
    if (!city.testBounds(tx, ty)) {
      return false;
    }

    char c = city.getTile(tx, ty);

    if (c < ROADBASE) return false;
    else if (c > LASTRAIL) return false;
    else if (c >= POWERBASE && c < LASTPOWER) return false;
    else return true;
  }
  void setTrafficMem() {
    while (!positions.isEmpty()) {
      CityLocation pos = positions.pop();
      mapX = pos.x;
      mapY = pos.y;
      assert city.testBounds(mapX, mapY);

      // check for road/rail
      int tile = city.getTile(mapX, mapY);
      if (tile >= ROADBASE && tile < POWERBASE) {
        city.addTraffic(mapX, mapY, 50);
      }
    }
  }
  boolean driveDone() {
    int low, high;
    switch (sourceZone) {
      case RESIDENTIAL:
        low = COMBASE;
        high = NUCLEAR;
        break;
      case COMMERCIAL:
        low = LHTHR;
        high = PORT;
        break;
      case INDUSTRIAL:
        low = LHTHR;
        high = COMBASE;
        break;
      default:
        throw new Error("unreachable");
    }

    if (mapY > 0) {
      int tile = city.getTile(mapX, mapY - 1);
      if (tile >= low && tile <= high) return true;
    }
    if (mapX + 1 < city.getWidth()) {
      int tile = city.getTile(mapX + 1, mapY);
      if (tile >= low && tile <= high) return true;
    }
    if (mapY + 1 < city.getHeight()) {
      int tile = city.getTile(mapX, mapY + 1);
      if (tile >= low && tile <= high) return true;
    }
    if (mapX > 0) {
      int tile = city.getTile(mapX - 1, mapY);
      if (tile >= low && tile <= high) return true;
    }
    return false;
  }