private static void turret(RobotController rc) { // do one time things here turtleCorner = turtleCorner == null ? LOCATION_NONE : turtleCorner; try { RobotInfo[] friendlyRobots = rc.senseNearbyRobots(rc.getType().sensorRadiusSquared, rc.getTeam()); if (rc.getHealth() <= 3 && rc.isInfected() && friendlyRobots.length > 0) { rc.disintegrate(); } turretAttack(rc); processFighterSignals(rc); if ((archonIsTooClose(rc) || isAdjacentToWall(rc)) && rc.getType() == RobotType.TURRET && rc.isCoreReady()) { rc.pack(); } if (turtleCorner != LOCATION_NONE && rc.isCoreReady() && rc.getType() == RobotType.TURRET) { int minCornerRadius = (20 + (rc.getRobotCount() / 10)); if (rc.getLocation().distanceSquaredTo(turtleCorner) < minCornerRadius) { rc.pack(); } } rc.setIndicatorString(0, "Turtle x: " + turtleCorner.x + "Turtle y: " + turtleCorner.y); rc.setIndicatorString(1, "I am a turret"); // if (turtleCorner.equals(LOCATION_NONE)) tryToLocateCorner(rc); Clock.yield(); } catch (GameActionException e) { e.printStackTrace(); } }
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); } }
private static void moveFromCorner(RobotController rc) throws GameActionException { int minRadius = 9; // units should try to maintain a minimum of 5 squared units // away from corner // @Hope - refine max radius int maxRadius = 26 + (int) Math.pow(rc.getRobotCount() / 6, 2); // based of number // of troops the max radius increases int distanceToCorner = rc.getLocation().distanceSquaredTo(turtleCorner); if (distanceToCorner <= minRadius && rc.isCoreReady()) { Direction dir = (rc.getLocation().directionTo(turtleCorner)).opposite(); moveTowards(rc, dir); } if (distanceToCorner >= maxRadius && rc.isCoreReady()) { moveTowards(rc, rc.getLocation().directionTo(turtleCorner)); } }
/** * Currently we use two pairs of intro scouts, so this method identifies two opposite corners to * which those scouts should be sent. So that no extra communication is needed, one archon will * calculate one of the corners as closest for him and all of the other archons will calculate the * other corner so that the two scouts are guaranteed to move towards opposite corners. * * @param rc must be an archon in its initial location and should have built nothing except scouts * yet * @return */ private static Direction calculateDirectionToClosestCorner(RobotController rc) { // TODO determine which corner pair is better to use Direction toTarget = Direction.NONE; List<MapLocation> archonLocations = Arrays.asList(rc.getInitialArchonLocations(myTeam)); if (archonLocations.size() == 1) { // this one must send a scout to both corners if (rc.getRobotCount() == 1) { toTarget = Direction.NORTH_EAST; } else { toTarget = Direction.SOUTH_WEST; } } else { Optional<MapLocation> northernMost = archonLocations.stream().min((a, b) -> a.y - b.y); if (rc.getLocation().equals(northernMost.get())) { return Direction.NORTH_EAST; } else { return Direction.SOUTH_WEST; } } return toTarget; }
private static boolean archonIsTooClose(RobotController rc) { boolean tooClose = false; int archonReserveDistance = (int) (Math.sqrt(rc.getRobotCount()) * 1.4); // @Hope make this more finessed List<RobotInfo> robots = Arrays.asList(rc.senseNearbyRobots(archonReserveDistance + 1, myTeam)); List<RobotInfo> archons = new ArrayList<>(); for (RobotInfo robot : robots) { if (robot.type == RobotType.ARCHON) { archons.add(robot); } } MapLocation myLocation = rc.getLocation(); for (RobotInfo archon : archons) { if (!tooClose && myLocation.distanceSquaredTo(archon.location) < archonReserveDistance) { tooClose = true; break; } } return tooClose; }
/** * @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(); } } }