Beispiel #1
0
  /**
   * Attempts to build a robot of the given type in a random direction (attempts all directions).
   * Only attempts building if rc has no core delay and has more parts than the threshold.
   *
   * @param rc RobotController from which to build
   * @param buildType type of robot to build
   * @return true if buildType is built else false
   * @throws GameActionException
   */
  private static boolean tryToBuild(RobotController rc, RobotType buildType)
      throws GameActionException {
    if (rc.isCoreReady()) {
      Direction buildDir = getRandomDirection();
      for (int i = 0; i < 8; i++) {
        if (rc.canBuild(buildDir, buildType)) {
          rc.build(buildDir, buildType);
          rc.broadcastMessageSignal(SENDING_MODE, currentMode, ONE_SQUARE_RADIUS);

          if (!turtleCorner.equals(LOCATION_NONE)) {
            rc.broadcastMessageSignal(SENDING_TURTLE_X, turtleCorner.x, ONE_SQUARE_RADIUS);
            rc.broadcastMessageSignal(SENDING_TURTLE_Y, turtleCorner.y, ONE_SQUARE_RADIUS);
          }

          if (buildType.equals(RobotType.SCOUT)) {
            for (MapLocation scoutKitingLoc : SCOUT_KITING_LOCATIONS) {
              rc.broadcastMessageSignal(
                  SENDING_SCOUT_KITING_LOCATION_X, scoutKitingLoc.x, ONE_SQUARE_RADIUS);
              rc.broadcastMessageSignal(
                  SENDING_SCOUT_KITING_LOCATION_Y, scoutKitingLoc.y, ONE_SQUARE_RADIUS);
            }
          }
          return true;
        }
        buildDir = buildDir.rotateRight(); // try all directions clockwise
      }
    }
    return false;
  }
Beispiel #2
0
 private static void archonIntroMode(RobotController rc) throws GameActionException {
   processIntroMessageSignals(rc);
   // TODO: what if, after an appropriate number of turns, the scouts haven't reported anything?
   // should we have all of the archons move together in some direction and hope it is towards a
   // corner?
   if (SCOUTED_CORNERS.size() >= 2 && turtleCorner.equals(LOCATION_NONE)) {
     List<Direction> crossDirections =
         Arrays.asList(
             Direction.NORTH_WEST,
             Direction.NORTH_EAST,
             Direction.SOUTH_WEST,
             Direction.SOUTH_EAST);
     if (!(crossDirections.contains(SCOUTED_CORNERS.get(0).directionTo(SCOUTED_CORNERS.get(1)))
         || SCOUTED_CORNERS.size() > 2)) {
       // TODO if they are not opposite, make a scout and send to one of the remaining corners
     } else {
       MapLocation[] newCorners = {
         new MapLocation(SCOUTED_CORNERS.get(0).x, SCOUTED_CORNERS.get(1).y),
         new MapLocation(SCOUTED_CORNERS.get(1).x, SCOUTED_CORNERS.get(0).y)
       };
       for (MapLocation corner : newCorners) {
         if (!SCOUTED_CORNERS.contains(corner)) {
           SCOUTED_CORNERS.add(corner);
         }
       }
       currentMode = TRANSITION_MODE;
       turtleCorner = findBestTurtleCorner(rc);
       for (MapLocation corner : SCOUTED_CORNERS) {
         if (crossDirections.contains(turtleCorner.directionTo(corner))) {
           fullMapRadius = turtleCorner.distanceSquaredTo(corner);
           break;
         }
       }
       // TODO (also broadcast this locally to scouts when you make them? So they can message
       // back more efficiently, if they have to)
       rc.broadcastMessageSignal(
           SENDING_MODE, TRANSITION_MODE, rc.getType().sensorRadiusSquared * 2);
       rc.broadcastMessageSignal(
           SENDING_TURTLE_X, turtleCorner.x, rc.getType().sensorRadiusSquared * 2);
       rc.broadcastMessageSignal(
           SENDING_TURTLE_Y, turtleCorner.y, rc.getType().sensorRadiusSquared * 2);
     }
   }
   if (!turtleCorner.equals(LOCATION_NONE)) {
     currentMode = TRANSITION_MODE;
   }
   // TODO gathering parts (need locations from scouts first...)
   if (rc.getRobotCount() - numArchons < NUM_INTRO_SCOUTS) {
     tryToBuild(rc, RobotType.SCOUT);
     Direction directionToTargetCorner = calculateDirectionToClosestCorner(rc);
     rc.broadcastMessageSignal(
         SENDING_TARGET_DIRECTION, DIRECTION_TO_SIGNAL.get(directionToTargetCorner), 4);
   }
 }
Beispiel #3
0
 public boolean send(int radiusSquared) throws GameActionException {
   if (rc.getMessageSignalCount() < GameConstants.MESSAGE_SIGNALS_PER_TURN) {
     rc.broadcastMessageSignal(message[0], message[1], radiusSquared);
     return true;
   }
   return false;
 }
Beispiel #4
0
 static void runAfter(RobotController rc) throws GameActionException {
   if (canMessageSignal) {
     if (mapBoundUpdate && Common.lowStrategy == LowStrategy.EXPLORE) {
       final int minRadius = 2 * sightRadius;
       int bounds = Signals.getBounds(rc).toInt();
       MapLocation target = furthestArchonStart(rc);
       int radius = MAP_UPDATE_MESSAGE_FACTOR * rc.getLocation().distanceSquaredTo(target);
       if (radius < minRadius || rc.getType() == RobotType.ARCHON) radius = minRadius;
       rc.broadcastMessageSignal(bounds, Signals.BUFFER, radius);
       ++sent;
       sendBoundariesLow = false;
       sendBoundariesHigh = false;
       mapBoundUpdate = false;
     }
     if (sendBoundariesLow) Signals.addBoundsLow(rc);
     if (sendBoundariesHigh) Signals.addBoundsHigh(rc);
   }
   sent += Signals.sendQueue(rc, sendRadius);
   // rc.setIndicatorString(0, String.format("sent %d received %d bounds %d %d %d %d", sent, read,
   // xMin, yMin, xMax, yMax));
 }
  public static void run(RobotController rc) {
    Random rand = new Random(rc.getID());
    Team myTeam = rc.getTeam();
    Team enemyTeam = myTeam.opponent();
    int numFriendly = 0;
    RobotInfo[] adjNeutralRobots = rc.senseNearbyRobots(2, Team.NEUTRAL);
    // if useTurrets = true, then use turret strategy
    boolean useTurrets = false;

    try {
      // Any code here gets executed exactly once at the beginning of the game.
      RobotInfo[] nearbyArchons =
          rc.senseNearbyRobots(RobotType.ARCHON.sensorRadiusSquared, rc.getTeam());
      if (nearbyArchons.length >= 2) {
        useTurrets = true;
      }
      // rc.setIndicatorString(1, "newString");
    } catch (Exception e) {
      // Throwing an uncaught exception makes the robot die, so we need to catch exceptions.
      // Caught exceptions will result in a bytecode penalty.
      System.out.println(e.getMessage());
      e.printStackTrace();
    }

    while (true) {
      // This is a loop to prevent the run() method from returning. Because of the Clock.yield()
      // at the end of it, the loop will iterate once per game round.
      try {
        if (useTurrets) {
          boolean escape = false;
          //					if (rc.isCoreReady()) {
          //						int numAdjTurrets = 0;
          //						for (RobotInfo f : friendlyAdjacent) {
          //							if (f.type == RobotType.TURRET) {
          //								numAdjTurrets++;
          //							}
          //						}
          //						if (numAdjTurrets < 3) {
          //							escape = Movement.moveAwayFromEnemy(rc);
          //						}
          //					}
          //					if (rc.isCoreReady()) {
          //						escape = Movement.moveAwayFromEnemy(rc);
          //					}
          if (!escape) {
            if (adjNeutralRobots.length > 0) {
              // if there is a neutral robot adjacent, activate it or wait until there's no core
              // delay
              if (rc.isCoreReady()) {
                rc.activate(adjNeutralRobots[0].location);
              }
            }
            // careful- moving to parts might get into enemy turret range
            if (Movement.getToAdjParts(rc)) {
            } else {
              boolean toheal = false;
              // repair a nearby friendly robot
              if (rc.isWeaponReady()) {
                RobotInfo[] friendlyWithinRange = rc.senseNearbyRobots(24, myTeam);
                numFriendly = friendlyWithinRange.length;
                if (friendlyWithinRange.length > 0) {
                  RobotInfo toRepair = friendlyWithinRange[0];
                  for (RobotInfo r : friendlyWithinRange) {
                    if ((r.health < toRepair.health)
                        && (r.type != RobotType.ARCHON)
                        && (r.maxHealth - r.health > 1)) {
                      toRepair = r;
                    }
                  }
                  if ((toRepair.maxHealth - toRepair.health > 1)
                      && (toRepair.type != RobotType.ARCHON)) {
                    toheal = true;
                    rc.repair(toRepair.location);
                  }
                }
              }
              if (toheal == false && rc.isCoreReady()) {
                // did not heal any robots

                // sense all the hostile robots within the archon's radius
                MapLocation myLoc = rc.getLocation();
                RobotInfo[] hostileWithinRange =
                    rc.senseHostileRobots(myLoc, RobotType.ARCHON.sensorRadiusSquared);
                RobotInfo closestRobot = null;
                int closestDistance = 0;
                // get the furthest robot from the scout
                for (RobotInfo r : hostileWithinRange) {
                  if (r.location.distanceSquaredTo(myLoc) > closestDistance) {
                    closestRobot = r;
                    closestDistance = r.location.distanceSquaredTo(myLoc);
                  }
                }
                // if there is such an enemy, signal it to range 8
                if (closestRobot != null) {
                  try {
                    // this signaling is only effective against non turret enemies
                    rc.broadcastMessageSignal(closestRobot.location.x, closestRobot.location.y, 8);
                  } catch (GameActionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                  }
                }

                int turnNum = rc.getRoundNum();
                int numVeryCloseScouts = 0;
                int numNearbyTurrets = 0;
                RobotInfo[] friendlyNearby =
                    rc.senseNearbyRobots(RobotType.ARCHON.sensorRadiusSquared, myTeam);
                for (RobotInfo f : friendlyNearby) {
                  if (f.type == RobotType.TURRET) {
                    numNearbyTurrets++;
                  }
                }
                // for sensing if there are guards within range 24
                RobotInfo[] friendlyClose = rc.senseNearbyRobots(24, myTeam);
                int numNearbyGuards = 0;
                for (RobotInfo f : friendlyClose) {
                  if (f.type == RobotType.GUARD) {
                    numNearbyGuards++;
                  }
                }
                // check for scouts; how close should they be????
                RobotInfo[] friendlyVeryClose = rc.senseNearbyRobots(15, myTeam);
                for (RobotInfo f : friendlyClose) {
                  if (f.type == RobotType.SCOUT) {
                    numVeryCloseScouts++;
                  }
                }
                if (rc.hasBuildRequirements(RobotType.GUARD)
                    && rc.isCoreReady()
                    && numNearbyGuards < 1) {
                  Direction dirToBuild = RobotPlayer.directions[rand.nextInt(8)];
                  for (int i = 0; i < 8; i++) {
                    // If possible, build in this direction
                    if (rc.canBuild(dirToBuild, RobotType.GUARD)) {
                      rc.build(dirToBuild, RobotType.GUARD);
                      break;
                    } else {
                      // Rotate the direction to try
                      dirToBuild = dirToBuild.rotateLeft();
                    }
                  }
                }
                // if there are <1 turrets next to archon, build asap
                if (rc.hasBuildRequirements(RobotType.TURRET)
                    && rc.isCoreReady()
                    && numNearbyTurrets < 1) {
                  Direction dirToBuild = RobotPlayer.directions[rand.nextInt(4) * 2];
                  for (int i = 0; i < 4; i++) {
                    // If possible, build in this direction
                    if (rc.canBuild(dirToBuild, RobotType.TURRET)) {
                      rc.build(dirToBuild, RobotType.TURRET);
                      turretCount++;
                      break;
                    } else {
                      // Rotate the direction to try
                      dirToBuild = dirToBuild.rotateLeft();
                      dirToBuild = dirToBuild.rotateLeft();
                    }
                  }
                }
                // if there are <1 scout next to archon and 1 turret, build scout asap
                if (rc.hasBuildRequirements(RobotType.SCOUT)
                    && rc.isCoreReady()
                    && numNearbyTurrets > 0
                    && numVeryCloseScouts == 0
                    && turnNum < 400) {
                  Direction dirToBuild = RobotPlayer.directions[rand.nextInt(8)];
                  for (int i = 0; i < 8; i++) {
                    // If possible, build in this direction
                    if (rc.canBuild(dirToBuild, RobotType.SCOUT)) {
                      rc.build(dirToBuild, RobotType.SCOUT);
                      scoutCount++;
                      break;
                    } else {
                      // Rotate the direction to try
                      dirToBuild = dirToBuild.rotateLeft();
                    }
                  }
                }
                // build turret every 100 turns until turn 400
                //								if (turnNum > 1 && turnNum < 400) {
                //									if (turnNum % 100 == 85 && rc.isCoreReady()) {
                //										Direction dirToBuild = RobotPlayer.directions[rand.nextInt(4)*2];
                //										for (int i = 0; i < 4; i++) {
                //											// If possible, build in this direction
                //											if (rc.canBuild(dirToBuild, RobotType.TURRET)) {
                //												rc.build(dirToBuild, RobotType.TURRET);
                //												turretCount++;
                //												break;
                //											} else {
                //												// Rotate the direction to try
                //												dirToBuild = dirToBuild.rotateLeft();
                //												dirToBuild = dirToBuild.rotateLeft();
                //											}
                //										}
                //									}
                //								}
                else {
                  // Check if this ARCHON's core is ready
                  if (rc.isCoreReady()) {
                    boolean built = false;
                    RobotType typeToBuild = RobotType.TURRET;
                    if (scoutCount < turretCount / 5) {
                      typeToBuild = RobotType.SCOUT;
                    }
                    // never build scouts after a certain turn
                    if (turnNum < 1500) {
                      typeToBuild = RobotType.TURRET;
                    }
                    // Check for sufficient parts
                    if (rc.hasBuildRequirements(typeToBuild)) {
                      // Choose a random direction to try to build in; NESW for turrets; all 8 for
                      // scouts
                      if (typeToBuild.equals(RobotType.TURRET)) {
                        Direction dirToBuild = RobotPlayer.directions[rand.nextInt(4) * 2];
                        for (int i = 0; i < 4; i++) {
                          // If possible, build in this direction
                          if (rc.canBuild(dirToBuild, RobotType.TURRET)) {
                            rc.build(dirToBuild, RobotType.TURRET);
                            turretCount++;
                            break;
                          } else {
                            // Rotate the direction to try
                            dirToBuild = dirToBuild.rotateLeft();
                            dirToBuild = dirToBuild.rotateLeft();
                          }
                        }
                      } else {
                        Direction dirToBuild = RobotPlayer.directions[rand.nextInt(8)];
                        for (int i = 0; i < 8; i++) {
                          // If possible, build in this direction
                          if (rc.canBuild(dirToBuild, RobotType.SCOUT)) {
                            rc.build(dirToBuild, RobotType.SCOUT);
                            scoutCount++;
                            break;
                          } else {
                            // Rotate the direction to try
                            dirToBuild = dirToBuild.rotateLeft();
                          }
                        }
                      }
                    }
                    // only move around if there are resources
                    if ((!built)
                        && rc.hasBuildRequirements(RobotType.TURRET)
                        && (rc.isCoreReady())) {
                      // don't move into enemy turret range if scout sends signal about it
                      Set<Direction> dangerousDirs = new HashSet<>();
                      Signal currentSignal = rc.readSignal();
                      while (currentSignal != null) {
                        int messageX = currentSignal.getMessage()[0];
                        int messageY = currentSignal.getMessage()[1];
                        // if signal message > 80000, then the message is signaling a turret
                        // location
                        if (messageX > 80000) {
                          messageX = messageX - 100000;
                          messageY = messageY - 100000;
                          MapLocation enemyTurretLoc = new MapLocation(messageX, messageY);
                          Direction dirToEnemyTurret = myLoc.directionTo(enemyTurretLoc);
                          Direction dirToEnemyTurretL =
                              myLoc.directionTo(enemyTurretLoc).rotateLeft();
                          Direction dirToEnemyTurretR =
                              myLoc.directionTo(enemyTurretLoc).rotateRight();
                          if (myLoc.add(dirToEnemyTurret).distanceSquaredTo(enemyTurretLoc) <= 48) {
                            dangerousDirs.add(dirToEnemyTurret);
                          }
                          if (myLoc.add(dirToEnemyTurretL).distanceSquaredTo(enemyTurretLoc)
                              <= 48) {
                            dangerousDirs.add(dirToEnemyTurretL);
                          }
                          if (myLoc.add(dirToEnemyTurretR).distanceSquaredTo(enemyTurretLoc)
                              <= 48) {
                            dangerousDirs.add(dirToEnemyTurretR);
                          }
                        }
                        currentSignal = rc.readSignal();
                      }

                      Direction dirToMove = RobotPlayer.directions[(rand.nextInt(4) * 2) + 1];
                      for (int i = 0; i < 4; i++) {
                        if (rc.canMove(dirToMove) && !dangerousDirs.contains(dirToMove)) {
                          rc.move(dirToMove);
                          break;
                        } else {
                          dirToMove = dirToMove.rotateLeft();
                          dirToMove = dirToMove.rotateLeft();
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        } else { // use soldiers
          boolean escape = false;
          if (rc.isCoreReady()) {
            escape = Movement.moveAwayFromEnemy(rc);
          }
          if (!escape) {
            if (adjNeutralRobots.length > 0) {
              // if there is a neutral robot adjacent, activate it or wait until there's no core
              // delay
              if (rc.isCoreReady()) {
                rc.activate(adjNeutralRobots[0].location);
              }
            }
            if (Movement.getToAdjParts(rc)) {
            } else {
              boolean toheal = false;
              // repair a nearby friendly robot
              if (rc.isWeaponReady()) {
                RobotInfo[] friendlyWithinRange = rc.senseNearbyRobots(24, myTeam);
                numFriendly = friendlyWithinRange.length;
                if (friendlyWithinRange.length > 0) {
                  RobotInfo toRepair = friendlyWithinRange[0];
                  for (RobotInfo r : friendlyWithinRange) {
                    if ((r.health < toRepair.health)
                        && (r.type != RobotType.ARCHON)
                        && (r.maxHealth - r.health > 1)) {
                      toRepair = r;
                    }
                  }
                  if ((toRepair.maxHealth - toRepair.health > 1)
                      && (toRepair.type != RobotType.ARCHON)) {
                    toheal = true;
                    rc.repair(toRepair.location);
                  }
                }
              }
              if (toheal == false) {
                // for sensing if there are guards within range 24
                RobotInfo[] friendlyClose = rc.senseNearbyRobots(24, myTeam);
                int numNearbyGuards = 0;
                for (RobotInfo f : friendlyClose) {
                  if (f.type == RobotType.GUARD) {
                    numNearbyGuards++;
                  }
                }

                boolean built = false;
                int turnNum = rc.getRoundNum();
                if (rc.hasBuildRequirements(RobotType.SCOUT)
                    && rc.isCoreReady()
                    && turnNum > 1
                    && turnNum % 150 >= 0
                    && turnNum % 150 <= 19
                    && turnNum < 900) {
                  Direction dirToBuild = RobotPlayer.directions[rand.nextInt(8)];
                  for (int i = 0; i < 8; i++) {
                    // If possible, build in this direction
                    if (rc.canBuild(dirToBuild, RobotType.SCOUT)) {
                      rc.build(dirToBuild, RobotType.SCOUT);
                      built = true;
                      break;
                    } else {
                      // Rotate the direction to try
                      dirToBuild = dirToBuild.rotateLeft();
                    }
                  }
                }
                if (rc.hasBuildRequirements(RobotType.GUARD)
                    && rc.isCoreReady()
                    && !built
                    && numNearbyGuards < 1) {
                  Direction dirToBuild = RobotPlayer.directions[rand.nextInt(8)];
                  for (int i = 0; i < 8; i++) {
                    // If possible, build in this direction
                    if (rc.canBuild(dirToBuild, RobotType.GUARD)) {
                      rc.build(dirToBuild, RobotType.GUARD);
                      built = true;
                      break;
                    } else {
                      // Rotate the direction to try
                      dirToBuild = dirToBuild.rotateLeft();
                    }
                  }
                }
                if (rc.hasBuildRequirements(RobotType.SOLDIER) && rc.isCoreReady() && !built) {
                  Direction dirToBuild = RobotPlayer.directions[rand.nextInt(8)];
                  for (int i = 0; i < 8; i++) {
                    // If possible, build in this direction
                    if (rc.canBuild(dirToBuild, RobotType.SOLDIER)) {
                      rc.build(dirToBuild, RobotType.SOLDIER);
                      built = true;
                      break;
                    } else {
                      // Rotate the direction to try
                      dirToBuild = dirToBuild.rotateLeft();
                    }
                  }
                }
                // if archon has nothing to do, tell soldiers to come to it's location
                /*if (rc.getRoundNum() > 500 && rc.isCoreReady() && rc.isWeaponReady()) {
                	rc.broadcastMessageSignal(-100, 0, 70 * 70);
                }*/
              }
            }
          }
        }
        Clock.yield();
      } catch (Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
      }
    }
  }
Beispiel #6
0
  private static void scout(RobotController rc) {
    // do one time things here
    Direction targetDirection = Direction.NONE;
    while (true) {
      try {
        // TODO - I've made it so the scouts will go in pairs now; not sure if we want this later or
        // not, but they
        // aren't avoiding enemies well enough
        if (currentMode == INTRO_MODE && rc.getRoundNum() >= 40) {
          // TODO - scouts don't pick their directions well enough - try running diffusion.
          // one often starts already in/near a corner; if we find a corner very close, we should
          // probably just move to it
          // and turtle right away (even if we don't know about the others yet)
          if (targetDirection.equals(Direction.NONE)) {
            targetDirection = getScoutTargetDirection(rc);
          }

          //					RobotInfo[] zombies = rc.senseNearbyRobots(-1, Team.ZOMBIE);
          // TODO: bring this back in, but only if there aren't bots that will attack the scout
          // (otherwise, the delay makes them too vulnerable; finding corners matters more first)
          //					for (RobotInfo zombie : zombies) {
          //						if (zombie.type == RobotType.ZOMBIEDEN) {
          //							if (!ZOMBIE_DEN_LOCATIONS.contains(zombie.location)) {
          //								ZOMBIE_DEN_LOCATIONS.add(zombie.location);
          //								rc.broadcastMessageSignal(SENDING_DEN_X, zombie.location.x, fullMapRadius);
          //								rc.broadcastMessageSignal(SENDING_DEN_Y, zombie.location.y, fullMapRadius);
          //							}
          //						}
          //					}
          //					int start = Clock.getBytecodeNum();
          MapLocation corner = checkForCorner(rc, targetDirection);
          //					System.out.println("CheckforCorner: " + (Clock.getBytecodeNum() - start));
          if (!corner.equals(LOCATION_NONE)) {
            rc.broadcastMessageSignal(SENDING_CORNER_X, corner.x, fullMapRadius);
            rc.broadcastMessageSignal(SENDING_CORNER_Y, corner.y, fullMapRadius);
            // head to opposite in case other scout didn't make it
            // TODO or scout around for other zombie dens, kite, etc.
            targetDirection = targetDirection.opposite();
          }
          //					start = Clock.getBytecodeNum();
          moveCautiously(rc, targetDirection);
          //					System.out.println("moveCautiously: " + (Clock.getBytecodeNum() - start));
        } else { // not intro mode; do kiting
          RobotInfo[] zombies = rc.senseNearbyRobots(-1, Team.ZOMBIE);
          if (zombies.length > 0) {
            turnsToCheckForZombies = NUM_TURNS_TO_CHECK_FOR_ZOMBIES;
          }
          if (turnsToCheckForZombies > 0) {
            turnsToCheckForZombies--;
            leadZombiesToEnemy(rc);
          } else {

          }
          //				rc.sensePartLocations(-1); //TODO
        }
        Clock.yield();
      } catch (GameActionException e) {
        e.printStackTrace();
      }
    }
  }
Beispiel #7
0
  /**
   * @Nathan - Should we adjust these priorities (specifically where should building troops be?)
   * TODO for archons - 1) repair nearest injured unit 2) signal turtle location 3) pick up adjacent
   * parts and activate neutral units 4) move to turtle corner 5) build troops 6) run away from
   * enemies
   *
   * @param rc
   * @throws GameActionException
   */
  private static void archon(RobotController rc) {
    numArchons = rc.getInitialArchonLocations(myTeam).length;
    turtleCorner = LOCATION_NONE;
    while (true) {
      try {
        // 1) repair nearest injured unit
        repairFirst(rc);
        // 2) signal turtle location - every 25 turns
        int broadcastRadius = rc.getType().sensorRadiusSquared * (2 + (rc.getRobotCount() / 50));
        if (rc.getRoundNum() > 100 && rc.getRoundNum() % 30 == 0 && turtleCorner != LOCATION_NONE) {
          rc.broadcastMessageSignal(turtleCorner.x, turtleCorner.y, broadcastRadius);
        }

        // @Nathan - Intro mode is all you -- I just pasted all the text into a separate method for
        // clarity
        if (turtleCorner != LOCATION_NONE && currentMode != TURTLE_MODE) {
          currentMode = TRANSITION_MODE;
        }
        if (currentMode == INTRO_MODE) {
          archonIntroMode(rc);
          // if (turtleCorner.equals(LOCATION_NONE)) tryToLocateCorner(rc);
        }
        // 4) Move to turtle corner
        if (currentMode == TRANSITION_MODE) {
          if (rc.getLocation().distanceSquaredTo(turtleCorner) > 4) {
            moveTowards(rc, rc.getLocation().directionTo(turtleCorner));
          } else {
            // TODO get in proper position
            currentMode = TURTLE_MODE;
            rc.broadcastMessageSignal(SENDING_MODE, TURTLE_MODE, rc.getType().sensorRadiusSquared);
          }
        }

        // 5) Build Troops !
        // @Nathan do we need to build more scouts in turtle mode so we can do more kiting?
        boolean hasNearbyEnemies = isNearbyEnemies(rc);
        if (!hasNearbyEnemies && rc.getRobotCount() - numArchons < NUM_INTRO_SCOUTS) {
          tryToBuild(rc, RobotType.SCOUT);
          Direction directionToTargetCorner = calculateDirectionToClosestCorner(rc);
          rc.broadcastMessageSignal(
              SENDING_TARGET_DIRECTION, DIRECTION_TO_SIGNAL.get(directionToTargetCorner), 4);
        }
        if ((rc.getRobotCount() <= 30 || hasNearbyEnemies)) {
          tryToBuild(rc, RobotType.SOLDIER);
        }
        if (rc.getRobotCount() > 30 && !hasNearbyEnemies) {
          tryToBuild(rc, RobotType.TURRET);
        }
        // 6) if senses enemy troop that is not a scout, run away from it
        if (hasNearbyEnemies) moveAwayFromEnemies(rc);
        // 3) Pick up parts on current square, check for adjacent parts and try to collect them
        collectParts(rc);
        // 3a) activate any nearby units
        activateUnits(rc);
        rc.setIndicatorString(0, "Turtle x: " + turtleCorner.x + "Turtle y: " + turtleCorner.y);
        rc.setIndicatorString(1, "Current Mode" + currentMode);
        Clock.yield(); // end turn
      } catch (GameActionException e) {
        e.printStackTrace();
      }
    }
  }