// returns true if the robot moved away public static boolean moveAwayFromEnemy(RobotController rc) throws GameActionException { Team myTeam = rc.getTeam(); int mySightRange = rc.getType().sensorRadiusSquared; MapLocation myLoc = rc.getLocation(); RobotInfo[] hostiles = rc.senseHostileRobots(myLoc, mySightRange); MapLocation closestEnemy = null; int closestEnemyDist = 60; for (RobotInfo e : hostiles) { MapLocation curEnemyLoc = e.location; int curDist = myLoc.distanceSquaredTo(curEnemyLoc); if (curDist < closestEnemyDist) { closestEnemyDist = curDist; closestEnemy = e.location; } } if (closestEnemy == null) { return false; } else { Direction dir = getBestMoveableDirection(closestEnemy.directionTo(myLoc), rc, 4); if (dir != Direction.NONE) { rc.move(dir); return true; } else { return false; } } }
/** * Returns true if no nearby enemies or if the nearby enemies are only scouts. Returns false if * deadly enemies are within sensing radius. * * @return boolean * @param RobotController rc */ private static boolean isNearbyEnemies(RobotController rc) { RobotInfo[] enemies = rc.senseHostileRobots(rc.getLocation(), rc.getType().sensorRadiusSquared); for (int i = 0; i < enemies.length; i++) { if (enemies[i].type != RobotType.SCOUT) { return true; } } return enemies.length > 0; }
private static void turretAttack(RobotController rc) throws GameActionException { if (rc.isWeaponReady()) { // can't attack if enemy is too close so attackFirst throws errors RobotInfo[] enemies = rc.senseHostileRobots(rc.getLocation(), rc.getType().attackRadiusSquared); for (RobotInfo enemy : enemies) { if (rc.canAttackLocation(enemy.location) && rc.isWeaponReady()) { rc.attackLocation(enemy.location); } } } }
/** * @param rc * @return true if rc moves else false * @throws GameActionException */ private static void moveTowardsNearestEnemy(RobotController rc) throws GameActionException { List<RobotInfo> enemies = Arrays.asList(rc.senseHostileRobots(rc.getLocation(), -1)); Optional<RobotInfo> nearestEnemy = enemies .stream() .min( (enemy1, enemy2) -> rc.getLocation().distanceSquaredTo(enemy1.location) - rc.getLocation().distanceSquaredTo(enemy2.location)); if (nearestEnemy.isPresent() && rc.isCoreReady()) { moveTowards(rc, rc.getLocation().directionTo(nearestEnemy.get().location)); } }
/** * If rc finds a zombie den, it signals out to surrounding robots If rc has no weapon delay, * attacks in the following priority: 1) adjacent robots (if robot is a bigzombie or standard * zombie move away every other turn to kite it) 2) big zombies 3) nearest enemy * * @param rc RobotController which will attack * @param RobotController * @throws GameActionException * @return true if this robot attacked else false */ private static void attackFirst(RobotController rc) throws GameActionException { boolean equalHealth = true; int lowestHealthIndex = -1; int lowestDistanceIndex = -1; int attackIndex = -1; RobotInfo[] enemies = rc.senseHostileRobots(rc.getLocation(), rc.getType().attackRadiusSquared); if (rc.isWeaponReady() && enemies.length > 0) { for (int i = 0; i < enemies.length; i++) { if (enemies[i].type == RobotType.ZOMBIEDEN) { rc.broadcastSignal(rc.getType().sensorRadiusSquared * 2); } if (attackIndex < 0 && (rc.getLocation()).isAdjacentTo(enemies[i].location)) { attackIndex = i; // TODO test this part - work on kiting if ((enemies[i].type == RobotType.BIGZOMBIE || enemies[i].type == RobotType.STANDARDZOMBIE) && rc.getRoundNum() % 2 == 0 && rc.isCoreReady()) { moveAwayFromEnemy(rc, rc.getLocation().directionTo(enemies[i].location)); } if (rc.isWeaponReady()) { rc.attackLocation(enemies[i].location); } } if (rc.isWeaponReady() && enemies[i].type == RobotType.BIGZOMBIE) { attackIndex = i; rc.attackLocation(enemies[i].location); } if (attackIndex < 0) { lowestHealthIndex = lowestHealthIndex < 0 ? 0 : lowestHealthIndex; lowestDistanceIndex = lowestDistanceIndex < 0 ? 0 : lowestDistanceIndex; equalHealth = equalHealth && enemies[i].health == enemies[lowestHealthIndex].health; lowestDistanceIndex = rc.getLocation().distanceSquaredTo(enemies[i].location) < rc.getLocation().distanceSquaredTo(enemies[lowestDistanceIndex].location) ? i : lowestDistanceIndex; lowestHealthIndex = enemies[i].health < enemies[lowestHealthIndex].health ? i : lowestHealthIndex; } } if (attackIndex < 0 && enemies.length > 0) { attackIndex = equalHealth ? lowestDistanceIndex : lowestHealthIndex; } if (attackIndex >= 0 && rc.isWeaponReady()) { rc.attackLocation(enemies[attackIndex].location); } } }
/** * Moves rc in direction dir if possible, while attempting to stay out of attack range of hostile * robots. * * @param rc * @param dir * @throws GameActionException */ private static void moveCautiously(RobotController rc, Direction dir) throws GameActionException { if (!rc.isCoreReady()) return; final MapLocation myLocation = rc.getLocation(); final Map<MapLocation, Double> moveLocationsToWeights = new HashMap<>(); for (MapLocation loc : MapLocation.getAllMapLocationsWithinRadiusSq(rc.getLocation(), ONE_SQUARE_RADIUS)) { if (loc.equals(rc.getLocation())) { continue; } if (!rc.canMove(myLocation.directionTo(loc))) { continue; } moveLocationsToWeights.put(loc, 1.); } if (moveLocationsToWeights.size() == 0) { return; } RobotInfo[] enemies = rc.senseHostileRobots(rc.getLocation(), -1); for (MapLocation loc : moveLocationsToWeights.keySet()) { for (RobotInfo enemy : enemies) { if (enemy.weaponDelay < 1 && enemy.type.attackRadiusSquared >= enemy.location.distanceSquaredTo(loc)) { moveLocationsToWeights.put(loc, moveLocationsToWeights.get(loc) + enemy.attackPower); } } moveLocationsToWeights.put( loc, moveLocationsToWeights.get(loc) + distanceFromDirection(dir, myLocation.directionTo(loc))); } // TODO(remember, though, the enemies will get to move one more time before you do) MapLocation bestLocation = moveLocationsToWeights.keySet().iterator().next(); Double lowestWeight = moveLocationsToWeights.get(bestLocation); for (MapLocation loc : moveLocationsToWeights.keySet()) { if (moveLocationsToWeights.get(loc) < lowestWeight) { lowestWeight = moveLocationsToWeights.get(loc); bestLocation = loc; } } rc.move(myLocation.directionTo(bestLocation)); }
public void run(final RobotController robotController) throws GameActionException { final MapInfoModule mapInfoModule = new MapInfoModule(); final CombatModule combatModule = new CombatModule(); final CommunicationModule communicationModule = new CommunicationModule(mapInfoModule); final DirectionModule directionModule = new DirectionModule(robotController.getID()); final MovementModule movementModule = new MovementModule(); final RubbleModule rubbleModule = new RubbleModule(); final Team currentTeam = robotController.getTeam(); int turnsStuck = 0; while (true) { RobotType type = robotController.getType(); MapLocation currentLocation = robotController.getLocation(); // update communication communicationModule.processIncomingSignals(robotController); // let's verify existing information communicationModule.verifyCommunicationsInformation(robotController, null, false); if (type == RobotType.TTM) { // MOVE // let's get the best assignment CommunicationModuleSignal objectiveSignal = null; int closestObjectiveLocationDistance = Integer.MAX_VALUE; final Enumeration<CommunicationModuleSignal> zombieDenCommunicationModuleSignals = communicationModule.zombieDens.elements(); while (zombieDenCommunicationModuleSignals.hasMoreElements()) { final CommunicationModuleSignal signal = zombieDenCommunicationModuleSignals.nextElement(); final int distance = signal.location.distanceSquaredTo(currentLocation); if (distance < closestObjectiveLocationDistance) { objectiveSignal = signal; closestObjectiveLocationDistance = distance; } } final Enumeration<CommunicationModuleSignal> enemyArchonCommunicationModuleSignals = communicationModule.enemyArchons.elements(); while (enemyArchonCommunicationModuleSignals.hasMoreElements()) { final CommunicationModuleSignal signal = enemyArchonCommunicationModuleSignals.nextElement(); final int distance = signal.location.distanceSquaredTo(currentLocation) * 6; // multiplying by 6 to prioritize the dens if (distance < closestObjectiveLocationDistance) { objectiveSignal = signal; closestObjectiveLocationDistance = distance; } } final Enumeration<CommunicationModuleSignal> enemyTurretCommunicationModuleSignals = communicationModule.enemyTurrets.elements(); while (enemyTurretCommunicationModuleSignals.hasMoreElements()) { final CommunicationModuleSignal signal = enemyTurretCommunicationModuleSignals.nextElement(); final int distance = signal.location.distanceSquaredTo(currentLocation) * 20; if (distance < closestObjectiveLocationDistance) { objectiveSignal = signal; closestObjectiveLocationDistance = distance; } } boolean shouldMove = true; Direction desiredMovementDirection = null; Direction targetRubbleClearanceDirection = null; // check to make sure we are safe final RobotInfo[] enemies = robotController.senseHostileRobots( currentLocation, robotController.getType().sensorRadiusSquared); if (robotController.isCoreReady() && enemies.length > 0) { final Direction fleeDirection = directionModule.averageDirectionTowardDangerousRobotsAndOuterBounds( robotController, enemies); if (fleeDirection != null) { final Direction fleeMovementDirection = directionModule.recommendedMovementDirectionForDirection( fleeDirection.opposite(), robotController, false); if (fleeMovementDirection != null) { robotController.move(fleeMovementDirection); currentLocation = robotController.getLocation(); robotController.setIndicatorString( 1, fleeDirection.name() + " " + fleeMovementDirection.name()); } } } // check if there are nearby signals if (desiredMovementDirection == null) { int closestSignalDistance = Integer.MAX_VALUE; MapLocation closestSignalLocation = null; final ArrayList<Signal> notifications = communicationModule.notifications; for (int i = 0; i < notifications.size(); i++) { final Signal signal = notifications.get(i); final int distance = currentLocation.distanceSquaredTo(signal.getLocation()); if (distance < closestSignalDistance) { closestSignalDistance = distance; closestSignalLocation = signal.getLocation(); } } if (closestSignalLocation != null) { desiredMovementDirection = currentLocation.directionTo(closestSignalLocation); } } // now let's try move toward an assignment if (robotController.isCoreReady() && communicationModule.initialInformationReceived && shouldMove) { // check if we have an objective if (desiredMovementDirection == null) { if (objectiveSignal != null) { final MapLocation objectiveLocation = objectiveSignal.location; if (objectiveLocation.distanceSquaredTo(currentLocation) >= 8) { desiredMovementDirection = currentLocation.directionTo(objectiveLocation); } } } // try move towards archon starting positions if (desiredMovementDirection == null) { int closestArchonDistance = Integer.MAX_VALUE; MapLocation closestArchonLocation = null; final MapLocation[] archonLocations = robotController.getInitialArchonLocations(robotController.getTeam().opponent()); for (int i = 0; i < archonLocations.length; i++) { final MapLocation location = archonLocations[i]; final int distance = currentLocation.distanceSquaredTo(location); if (distance < closestArchonDistance) { closestArchonDistance = distance; closestArchonLocation = location; } } if (closestArchonLocation != null) { desiredMovementDirection = currentLocation.directionTo(closestArchonLocation); } } // process movement if (desiredMovementDirection != null) { final Direction recommendedMovementDirection = directionModule.recommendedMovementDirectionForDirection( desiredMovementDirection, robotController, false); final MapLocation recommendedMovementLocation = recommendedMovementDirection != null ? currentLocation.add(recommendedMovementDirection) : null; if (recommendedMovementDirection != null && !movementModule.isMovementLocationRepetitive( recommendedMovementLocation, robotController)) { robotController.move(recommendedMovementDirection); movementModule.addMovementLocation(recommendedMovementLocation, robotController); currentLocation = robotController.getLocation(); turnsStuck = 0; } } } // unpack if we're safe RobotInfo[] nearbyTeammates = robotController.senseNearbyRobots(8, currentTeam); RobotInfo[] nearbySoldiers = combatModule.robotsOfTypesFromRobots( nearbyTeammates, new RobotType[] {RobotType.SOLDIER}); if (nearbySoldiers.length > 2) { robotController.unpack(); } } else { // ATTACK final RobotInfo[] enemies = robotController.senseHostileRobots( currentLocation, robotController.getType().attackRadiusSquared); RobotInfo bestEnemy = this.getBestEnemyToAttackFromEnemies(robotController, enemies); // handle attacking if (bestEnemy != null) { if (robotController.isWeaponReady()) { // we can attack the enemy robotController.attackLocation(bestEnemy.location); if (bestEnemy.type != RobotType.ZOMBIEDEN) { communicationModule.broadcastSignal( robotController, CommunicationModule.maximumFreeBroadcastRangeForRobotType( robotController.getType())); } } } // pack if we aren't near soldiers RobotInfo[] nearbyTeammates = robotController.senseNearbyRobots(type.sensorRadiusSquared, currentTeam); RobotInfo[] nearbySoldiers = combatModule.robotsOfTypesFromRobots( nearbyTeammates, new RobotType[] {RobotType.SOLDIER}); if (nearbySoldiers.length < 3) { robotController.pack(); } } Clock.yield(); } }
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(); } } }
// find a safe location public static MapLocation findSaferLocation() // move to far spot in direction with fewest enemies { MapLocation currentLocation = rc.getLocation(); ArrayList<Direction> directions = Utility.arrayListOfDirections(); /* ArrayList<Integer> enemiesInEachDirection = new ArrayList<Integer>(10); //initialize the enemiesInEachDirection arraylist for(int i = 0; i < 10; i++) { enemiesInEachDirection.add(0); } for(RobotInfo foe : foes) { Direction dirToFoe = currentLocation.directionTo(foe.location); int index = directions.indexOf(dirToFoe); int numberOfFoesInDirection = enemiesInEachDirection.get(index); enemiesInEachDirection.set(index, numberOfFoesInDirection++); } int leastEnemies = 1000000; int directionWithLeastEnemies = 0; for(int i = 0; i<enemiesInEachDirection.size(); i++) { int numberOfEnemies = enemiesInEachDirection.get(i); if(numberOfEnemies < leastEnemies) { directionWithLeastEnemies = i; leastEnemies = numberOfEnemies; } } Direction direction = directions.get(directionWithLeastEnemies);//the direction with the fewest enemies */ // find if foes are within attack range RobotInfo[] foes = rc.senseHostileRobots(rc.getLocation(), RobotType.SCOUT.sensorRadiusSquared); ArrayList<RobotInfo> nearAttackRange = new ArrayList<RobotInfo>(); for (RobotInfo foe : foes) { RobotType type = foe.type; if (type != RobotType.ARCHON && type != RobotType.ZOMBIEDEN && type != RobotType.SCOUT) // only want enemies who can attack { // if you're close to the attack range if (currentLocation.distanceSquaredTo(foe.location) < foe.type.attackRadiusSquared + 4) { nearAttackRange.add(foe); } } } // get average loc of hostiles // could also just run away from the closest hostile // neither one of those would have you go up or down if you have enemies directly to // your left and right int n_hostiles = 0; int x_sum = 0; int y_sum = 0; if (nearAttackRange.size() > 0) { for (RobotInfo robot : nearAttackRange) { n_hostiles++; MapLocation robotLoc = robot.location; x_sum += robotLoc.x; y_sum += robotLoc.y; } int x = x_sum / n_hostiles; int y = y_sum / n_hostiles; MapLocation hostileLoc = new MapLocation(x, y); Direction dirToMove = hostileLoc.directionTo(rc.getLocation()); MapLocation locationToGoTo = currentLocation.add(dirToMove, (int) Math.sqrt(RobotType.ARCHON.sensorRadiusSquared)); return locationToGoTo; } /* OTHER WAY TO DO IT //get the average direction to them //ArrayList<Direction> listOfDirections = Utility.arrayListOfDirections(); int averageDirection = 0; for(RobotInfo foe : nearAttackRange) { averageDirection += directions.indexOf(currentLocation.directionTo(foe.location)); } if(nearAttackRange.size() > 0) { averageDirection /= nearAttackRange.size(); Direction directionToEnemies = directions.get(averageDirection); //move in that direction as far as you can see MapLocation locationToGoTo = currentLocation.add(directionToEnemies.opposite(), (int)Math.sqrt(RobotType.ARCHON.sensorRadiusSquared)); return locationToGoTo; } */ else { return rc.getLocation(); } }
public static void run(RobotController rc) { sightRadius = RobotType.SOLDIER.sensorRadiusSquared; attackRadius = RobotType.SOLDIER.attackRadiusSquared; myTeam = rc.getTeam(); enemyTeam = myTeam.opponent(); while (true) { try { numEnemySoldiers = 0; totalEnemySoldierHealth = 0; myLoc = rc.getLocation(); nearbyAllies = rc.senseNearbyRobots(sightRadius, myTeam); nearbyEnemies = rc.senseHostileRobots(myLoc, sightRadius); newArchonLoc = null; // clear bad locations resetLocations(rc); // read messages and get destination readMessages(rc); // heal if need (and set the archon destination to go to) setRetreatingStatus(rc, nearbyEnemies); // Remove turret locations that you can see are not there. // Does NOT remove turret locations due to broadcasts. Already done in read messages. removeTurretLocations(rc); if (newArchonLoc != null) { nearestArchonLocation = newArchonLoc; } rc.setIndicatorString(2, "Round: " + rc.getRoundNum() + ", rushing: " + rush); // Reset rushing if turns since rush is > 20 and see no more enemies. if (rush && myLoc.distanceSquaredTo(rushLocation) <= 100) turnsSinceRush++; if (turnsSinceRush > 20) { if (rc.senseNearbyRobots(sightRadius, enemyTeam).length == 0) { turnsSinceRush = 0; rush = false; } } // When rushing, be mad aggressive. if (rush) { rushMicro(rc, nearbyEnemies); } // When retreating, retreat else if (healing) { if (rc.isCoreReady()) { if (nearestArchonLocation != null) { if (myLoc.distanceSquaredTo(nearestArchonLocation) > 13) { bugging.enemyAvoidMove(nearbyEnemies); // Get away from archons that are not too close together. } else if (myLoc.distanceSquaredTo(nearestArchonLocation) <= 2) { Direction radialDir = nearestArchonLocation.directionTo(myLoc); Direction awayDir = Movement.getBestMoveableDirection(radialDir, rc, 2); if (awayDir != Direction.NONE) { rc.move(awayDir); } } } } // Make sure to attack people even when retreating. // Prioritize the closest enemy. Then the closest zombie. if (rc.isWeaponReady()) { // Attack the closest enemy. If there is not one, then attack the closest zombie int closestDist = 10000; RobotInfo target = null; for (RobotInfo hostile : nearbyEnemies) { int dist = myLoc.distanceSquaredTo(hostile.location); if (rc.canAttackLocation(hostile.location)) { // There is already is a target if (target != null) { if (target.team == enemyTeam) { // Target is already enemy, so prioritize the closest if (hostile.team == enemyTeam) { if (dist < closestDist) { target = hostile; closestDist = dist; } } // If hostile is not an enemy, not worth considering. } else { // Target is not on enemy team, so hostile is best choice! if (hostile.team == enemyTeam) { target = hostile; closestDist = dist; // Both are zombies, so just pick the closest. } else { if (dist < closestDist) { target = hostile; closestDist = dist; } } } // Set a target when there is not one. } else { target = hostile; closestDist = dist; } } } // We know that if there is a target, we can attack it. if (target != null) { rc.attackLocation(target.location); } } } // When viper infected and will die from the infection, do special micro else if (isViperInfected(rc) && (rc.getHealth() < rc.getViperInfectedTurns() * 2 || rc.getRoundNum() > 2100)) { viperInfectedMicro(rc); } // if there are enemies in range, we should focus on attack and micro else if (nearbyEnemies.length > 0) { if (shouldLure(rc, nearbyEnemies, nearbyAllies)) luringMicro(rc); else micro(rc); } else { // otherwise, we should always be moving somewhere moveSoldier(rc); } Clock.yield(); } catch (Exception e) { e.printStackTrace(); } } }
public static void run(RobotController rc) { team = rc.getTeam(); while (true) { try { myLoc = rc.getLocation(); int numOurTurrets = 0; // Move opposite of ally scout. Also keep track of our number of turrets. // Try to pair with ally turret. RobotInfo[] allies = rc.senseNearbyRobots(myLoc, sightRange, team); isPaired = false; int followedTurretDist = 10000; for (RobotInfo ally : allies) { if (ally.type == RobotType.SCOUT) { int randInt = rand.nextInt(3); if (randInt == 0) { mainDir = ally.location.directionTo(myLoc); } else if (randInt == 1) { mainDir = ally.location.directionTo(myLoc).rotateLeft(); } else { mainDir = ally.location.directionTo(myLoc).rotateRight(); } } else if (ally.type == RobotType.TURRET || ally.type == RobotType.TTM) { numOurTurrets++; int dist = myLoc.distanceSquaredTo(ally.location); if (dist < followedTurretDist) { // Try to pair with this turret. // Confirm that no other scout allies are nearby. RobotInfo[] otherAllies = rc.senseNearbyRobots(ally.location, dist, team); boolean canPairWith = true; for (RobotInfo otherAlly : otherAllies) { if (otherAlly.type == RobotType.SCOUT) { int otherDist = ally.location.distanceSquaredTo(otherAlly.location); if (otherDist < dist) { canPairWith = false; break; } } } if (canPairWith) { // This is turret we can pair with. isPaired = true; followedTurretDist = dist; pairedTurret = ally.location; } } } } rc.setIndicatorString(0, "Round: " + rc.getRoundNum() + ", Is paired: " + isPaired); int numEnemyTurrets = 0; boolean inEnemyAttackRangeAndPaired = false; Direction dodgeEnemyDir = Direction.NONE; boolean inDanger = false; RobotInfo[] hostiles = rc.senseHostileRobots(myLoc, sightRange); if (isPaired) { if (hostiles.length > 0) { closestTurretLoc = null; int closestDist = 10000; RobotInfo closestEnemy = hostiles[0]; RobotInfo bestEnemy = hostiles[0]; // Find the best enemy. // In the meantime, also find the closest enemy that can hit me and get away. MapLocation enemyTurretLoc = null; MapLocation enemyScoutLoc = null; for (RobotInfo hostile : hostiles) { int dist = myLoc.distanceSquaredTo(hostile.location); if (hostile.type == RobotType.SCOUT) { enemyScoutLoc = hostile.location; } else if (hostile.type == RobotType.TURRET) { enemyTurretLoc = hostile.location; } else if (hostile.type == RobotType.ZOMBIEDEN) { // if (rc.isCoreReady()) { if (!hostile.location.equals(previouslyBroadcastedDen)) { if (myLoc.distanceSquaredTo(pairedTurret) <= 2) { previouslyBroadcastedDen = hostile.location; Message.sendMessageGivenDelay(rc, hostile.location, Message.ZOMBIEDEN, 10); } } // } } // First handle finding the best enemy. // make sure hostile range is > 5 if (hostile.location.distanceSquaredTo(pairedTurret) <= RobotType.TURRET.attackRadiusSquared && hostile.location.distanceSquaredTo(pairedTurret) > 5) { if (bestEnemy.type == RobotType.ARCHON) { if (hostile.type == RobotType.ARCHON) { if (hostile.health < bestEnemy.health) { bestEnemy = hostile; } } } else { if (hostile.type == RobotType.ARCHON) { bestEnemy = hostile; } else { if (hostile.health < bestEnemy.health) { bestEnemy = hostile; } } } } // Then find the closest turret if (closestTurretDist > dist && hostile.type == RobotType.TURRET && hostile.location.distanceSquaredTo(pairedTurret) > 5) { closestTurretDist = dist; closestTurretLoc = hostile.location; } // Find the closest enemy if (closestDist > dist && hostile.type != RobotType.ARCHON && hostile.location.distanceSquaredTo(pairedTurret) > 5) { closestDist = dist; closestEnemy = hostile; } // If my closest enemy can hit me, get away. if (closestEnemy.location.distanceSquaredTo(myLoc) <= closestEnemy.type.attackRadiusSquared) { inEnemyAttackRangeAndPaired = true; // Find a direction closest to paired turret that is not in attack range. int closestPairedDist = 10000; for (Direction dir : RobotPlayer.directions) { if (rc.canMove(dir)) { MapLocation dirLoc = myLoc.add(dir); int pairedDist = dirLoc.distanceSquaredTo(pairedTurret); if (dirLoc.distanceSquaredTo(closestEnemy.location) > closestEnemy.type.attackRadiusSquared) { if (closestPairedDist > pairedDist) { closestPairedDist = pairedDist; dodgeEnemyDir = dir; } } } } } } // If there is a best enemy, send a message. if (bestEnemy != null && bestEnemy.location.distanceSquaredTo(pairedTurret) > 5 && rc.isCoreReady()) { Message.sendMessageGivenRange(rc, bestEnemy.location, Message.PAIREDATTACK, 15); } // If there is a closest turret, send a message. if (closestTurretLoc != null && rc.isCoreReady()) { Message.sendMessageGivenDelay(rc, closestTurretLoc, Message.TURRET, 2.25); previouslyBroadcastedClosestTurretLoc = closestTurretLoc; } if (previouslyBroadcastedClosestTurretLoc != null && closestTurretLoc == null && rc.isCoreReady()) { Message.sendMessageGivenDelay( rc, previouslyBroadcastedClosestTurretLoc, Message.TURRETKILLED, 2.25); } // if it sees enemy turret with a scout, signal that if (enemyScoutLoc != null && enemyTurretLoc != null && rc.isCoreReady()) { Message.sendMessageGivenRange(rc, enemyTurretLoc, Message.ENEMYTURRETSCOUT, 8); } } } else { // If sees an enemy, get away and record the two closest enemies. Then broadcast the // location while running away. // If Scout sees Den, then just broadcast immediately. // If Scout sees other enemies, then wait until far enough to broadcast. closestRecordedEnemy = null; // does not include the Den! secondClosestRecordedEnemy = null; // does not include the Den! int closestRecordedEnemyDist = 10000; int secondClosestRecordedEnemyDist = 20000; if (hostiles.length > 0) { MapLocation realLoc = myLoc.add(mainDir); int closestAttackingEnemyDist = 10000; for (RobotInfo hostile : hostiles) { if (hostile.type == RobotType.ZOMBIEDEN) { if (!hostile.location.equals(previouslyBroadcastedDen)) { previouslyBroadcastedDen = hostile.location; // if (rc.isCoreReady()) { Message.sendMessageGivenDelay(rc, hostile.location, Message.ZOMBIEDEN, 10); Direction dir = hostile.location.directionTo(myLoc); if (rc.canMove(dir)) { mainDir = dir; } else if (rc.canMove(dir.rotateLeft())) { mainDir = dir.rotateLeft(); } else if (rc.canMove(dir.rotateRight())) { mainDir = dir.rotateRight(); } // } } } else { if (hostile.type == RobotType.TURRET) { numEnemyTurrets++; } // In danger only if someone can attack me. if (hostile.type != RobotType.ARCHON) { int dist = realLoc.distanceSquaredTo(hostile.location); if (hostile.type == RobotType.ZOMBIEDEN) { if (dist <= 5) { inDanger = true; } } else if (hostile.type == RobotType.TURRET) { if (dist <= hostile.type.attackRadiusSquared) inDanger = true; } else { if (dist <= hostile.type.sensorRadiusSquared) inDanger = true; } } int dist = myLoc.distanceSquaredTo(hostile.location); if (closestRecordedEnemy == null) { closestRecordedEnemy = hostile; } else if (dist < closestRecordedEnemyDist) { // update the two closest stored locations. secondClosestRecordedEnemyDist = closestRecordedEnemyDist; secondClosestRecordedEnemy = closestRecordedEnemy; closestRecordedEnemyDist = dist; closestRecordedEnemy = hostile; } else if (dist < secondClosestRecordedEnemyDist) { // update the second closest stored location // only. secondClosestRecordedEnemyDist = dist; secondClosestRecordedEnemy = hostile; } } } if (rc.isCoreReady()) { if (closestRecordedEnemy != null) { if (closestRecordedEnemyDist <= closestRecordedEnemy.type.attackRadiusSquared) { // Send a message of the closest enemy broadcastRecordedEnemy(rc, closestRecordedEnemy); if (secondClosestRecordedEnemy != null) { // Send a message of the second closest enemy. broadcastRecordedEnemy(rc, secondClosestRecordedEnemy); } } } } } } // Broadcast collectibles if (rc.isCoreReady()) { if (numTurnsStationary < 10) { if (isPaired) { if (myLoc.distanceSquaredTo(pairedTurret) <= 2) { broadcastCollectibles(rc, hostiles.length > 0); } } else { broadcastCollectibles(rc, hostiles.length > 0); } } } // Every 50 turns, broadcast whether or not I am paired if (rc.getRoundNum() % 50 == 0) { int messageType = isPaired ? Message.PAIRED : Message.UNPAIRED; if (isPaired) { if (myLoc.distanceSquaredTo(pairedTurret) <= 2) { if (hostiles.length > 0) { Message.sendMessageGivenDelay(rc, myLoc, messageType, 8); } else { Message.sendMessageGivenDelay(rc, myLoc, messageType, 0.3); } } } else { if (hostiles.length > 0) { Message.sendMessageGivenDelay(rc, myLoc, messageType, 8); } else { Message.sendMessageGivenDelay(rc, myLoc, messageType, 0.3); } } } // When we have more turrets, broadcast that. if (numOurTurrets > numEnemyTurrets && isPaired && rc.isCoreReady()) { if (myLoc.distanceSquaredTo(pairedTurret) <= 2) { if (closestTurretLoc != null) { Message.sendMessageGivenRange(rc, closestTurretLoc, Message.RUSH, 2 * sightRange); } else { Message.sendMessageGivenRange( rc, new MapLocation(0, 0), Message.RUSHNOTURRET, 2 * sightRange); } } } // When paired, move along with the turret // Otherwise move in your main direction, and change it accordingly if you cannot move. if (isPaired) { if (rc.isCoreReady()) { if (inEnemyAttackRangeAndPaired) { // mainDir already computed above. if (dodgeEnemyDir != Direction.NONE) { mainDir = dodgeEnemyDir; rc.move(mainDir); numTurnsStationary = 0; } } else { // When not in enemy attack range, cling to paired turret (and make sure not to get // hit!) Direction dirToTurret = myLoc.directionTo(pairedTurret); // If right next to turret, then circle around turret if (myLoc.add(dirToTurret).equals(pairedTurret)) { Direction left = dirToTurret.rotateLeft(); if (rc.canMove(left) && !inEnemyAttackRange(myLoc.add(left), hostiles)) { mainDir = left; rc.move(mainDir); numTurnsStationary = 0; } else { Direction right = dirToTurret.rotateRight(); if (rc.canMove(right) && !inEnemyAttackRange(myLoc.add(right), hostiles)) { mainDir = right; rc.move(mainDir); numTurnsStationary = 0; } } } // Otherwise, move closer to the turret. else { Direction closerDir = Movement.getBestMoveableDirection(dirToTurret, rc, 2); if (closerDir != Direction.NONE && !inEnemyAttackRange(myLoc.add(closerDir), hostiles)) { mainDir = closerDir; rc.move(mainDir); numTurnsStationary = 0; } } } } } else { rc.setIndicatorString(1, "Round: " + rc.getRoundNum() + ", In Danger: " + inDanger); if (rc.isCoreReady()) { if (inDanger) { // Go in direction maximizing the minimum distance int maxMinDist = 0; for (Direction dir : RobotPlayer.directions) { if (rc.canMove(dir)) { MapLocation dirLoc = myLoc.add(dir); int minDist = 10000; for (RobotInfo hostile : hostiles) { int dist = dirLoc.distanceSquaredTo(hostile.location); minDist = Math.min(dist, minDist); } if (maxMinDist < minDist) { maxMinDist = minDist; mainDir = dir; } } } rc.setIndicatorString( 2, "Round: " + rc.getRoundNum() + ", Max min dist: " + maxMinDist + ", Dir: " + mainDir); if (rc.canMove(mainDir)) { rc.move(mainDir); numTurnsStationary = 0; } } else { if (!rc.canMove(mainDir)) { int[] disps = {1, -1, 3, -3}; for (int disp : disps) { Direction dir = RobotPlayer.directions[((mainDir.ordinal() + disp) % 8 + 8) % 8]; if (rc.canMove(dir)) { mainDir = dir; break; } } } if (rc.canMove(mainDir)) { rc.move(mainDir); numTurnsStationary = 0; } } } } numTurnsStationary++; Clock.yield(); } catch (Exception e) { e.printStackTrace(); Clock.yield(); } } }