/** * 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; }
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); } }
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; }
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(); } } }
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(); } } }
/** * @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(); } } }