private static void moveSoldier(RobotController rc) throws GameActionException { // if we have a real current destination rc.setIndicatorString(1, "moving somewhere " + currentDestination + rc.getRoundNum()); if (currentDestination != null) { // if bugging is never initialized or we are switching destinations, reinitialize bugging if (!currentDestination.equals(storedDestination) || bugging == null) { bugging = new Bugging(rc, currentDestination); storedDestination = currentDestination; } // if we are trying to move towards a turret, stay out of range if (rc.isCoreReady()) { if (currentDestination.equals(nearestTurretLocation)) { bugging.turretAvoidMove(turretLocations); } else // if core is ready, then try to move towards destination if (nearestTurretLocation != null) { bugging.turretAvoidMove(turretLocations); } else { bugging.move(); } } } else if (nearestArchonLocation != null) { // we don't actually have a destination, so we want to try to move towards the // closest archon rc.setIndicatorString( 0, "moving to nearest archon " + nearestArchonLocation + rc.getRoundNum()); if (!nearestArchonLocation.equals(storedDestination)) { bugging = new Bugging(rc, nearestArchonLocation); storedDestination = nearestArchonLocation; } // if core is ready, try to move if (rc.isCoreReady() && bugging != null) { if (nearestTurretLocation != null) { bugging.turretAvoidMove(turretLocations); } else if (nearestArchonLocation.equals(bugging.destination) && myLoc.distanceSquaredTo(nearestArchonLocation) > 13) { // if soldier is far, move towards archon bugging.move(); } else if (nearestArchonLocation.equals(bugging.destination) && myLoc.distanceSquaredTo(nearestArchonLocation) < 13) { // if soldier is too close, move towards archon // try to move away from nearest archon if (rc.canMove(nearestArchonLocation.directionTo(myLoc))) { rc.move(nearestArchonLocation.directionTo(myLoc)); } } } } else { // if we literally have nowhere to go rc.setIndicatorString(1, "bugging around friendly " + rc.getRoundNum()); bugAroundFriendly(rc); } }
public static void yield() { if (my_type == RobotType.ARCHON) rc.setIndicatorString(0, "Beta 1.5"); if (rc.getRoundNum() % 25 == 0) Scanner.reset_health(); Clock.yield(); }
public static void setRetreatingStatus(RobotController rc, RobotInfo[] hostiles) throws GameActionException { // Retreating is when your first hit less than a third health or when you were retreating // already and is not max health yet. // But you should not be retreating if you are infected. That's not a good idea! healing = (3 * rc.getHealth() < RobotType.SOLDIER.maxHealth || (wasHealing && rc.getHealth() < RobotType.SOLDIER.maxHealth)) && (rc.getHealth() > 2 * rc.getViperInfectedTurns()); if (!healing) { if (wasHealing) bugging = null; wasHealing = false; } if (healing) { RobotInfo[] nearbyRobots = rc.senseNearbyRobots(sightRadius, myTeam); for (RobotInfo r : nearbyRobots) { if (r.type == RobotType.ARCHON) nearestArchonLocation = r.location; } rc.setIndicatorString(0, "should be retreating " + nearestArchonLocation + rc.getRoundNum()); if (!wasHealing || !bugging.destination.equals(nearestArchonLocation)) { if (nearestArchonLocation == null) { bugging = new Bugging(rc, rc.getLocation().add(Direction.EAST)); } else { bugging = new Bugging(rc, nearestArchonLocation); } } wasHealing = true; } }
/** * 1) process signals, try to find turtleCorner 2) if enemies are within sensing radius, unpack 3) * if too close to archons, move away 4) if too close to wall, move away 5) if too close to * corner, move away 6) if it did nothing, unpack * * @param rc */ private static void ttm(RobotController rc) { turtleCorner = turtleCorner.equals(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(); } // 1) if (isNearbyEnemies(rc) && rc.isCoreReady()) { rc.unpack(); } // 2) processFighterSignals(rc); // 3) moveAwayFromArchons(rc); // 4) moveAwayFromWalls(rc); // 5) if (turtleCorner != LOCATION_NONE) moveFromCorner(rc); // 6) if (rc.isCoreReady() && rc.getType() == RobotType.TTM && rc.getRoundNum() % 25 == 0) rc.unpack(); rc.setIndicatorString(0, "Turtle x: " + turtleCorner.x + "Turtle y: " + turtleCorner.y); rc.setIndicatorString(1, "I am a TTM!"); Clock.yield(); } catch (GameActionException e) { e.printStackTrace(); } }
// check whether or not you should lure zombies to the enemy private static boolean shouldLure( RobotController rc, RobotInfo[] nearbyEnemies, RobotInfo[] nearbyAllies) { int zombieCount = 0, enemyCount = 0; for (RobotInfo r : nearbyEnemies) { if (r.team.equals(Team.ZOMBIE)) zombieCount++; else if (r.team.equals(enemyTeam)) enemyCount++; } return rc.getRoundNum() > 1500 && nearbyAllies.length < 3 && zombieCount > enemyCount; }
static void init(RobotController rc) { int roundLimit = rc.getRoundLimit(); Common.rc = rc; rand = new Random(rc.getID()); id = rc.getID(); myTeam = rc.getTeam(); enemyTeam = myTeam.opponent(); history = new MapLocation[roundLimit]; robotType = rc.getType(); enrollment = rc.getRoundNum(); if (robotType != RobotType.ARCHON) birthday = enrollment - robotType.buildTurns - BUILD_LAG; hometown = rc.getLocation(); sightRadius = robotType.sensorRadiusSquared; straightSight = (int) Math.sqrt(sightRadius); canMessageSignal = robotType.canMessageSignal(); Signals.buildTarget = new MapLocation[roundLimit]; Signals.buildStrategy = new SignalStrategy[roundLimit]; try { addInfo(rc.senseRobot(id)); myArchonHometowns = rc.getInitialArchonLocations(myTeam); enemyArchonHometowns = rc.getInitialArchonLocations(enemyTeam); int coordinates[] = new int[MAP_MAX]; int x = 0; int y = 0; for (int i = enemyArchonHometowns.length - 1; i >= 0; --i) { MapLocation loc = enemyArchonHometowns[i]; twiceCenterX += loc.x; twiceCenterY += loc.y; coordinates[loc.y] *= MAP_MAX; coordinates[loc.y] += loc.x + 1; } for (int i = 0; i < myArchonHometowns.length; ++i) { MapLocation loc = myArchonHometowns[i]; twiceCenterX += loc.x; twiceCenterY += loc.y; x += loc.x; y += loc.y; } twiceCenterX /= myArchonHometowns.length; twiceCenterY /= myArchonHometowns.length; x /= myArchonHometowns.length; y /= myArchonHometowns.length; for (int i = 0; i < myArchonHometowns.length; ++i) { MapLocation loc = myArchonHometowns[i]; int xCoord = coordinates[loc.y] - 1; coordinates[loc.y] /= MAP_MAX; if (loc.x != twiceCenterX - xCoord) rotation = true; } Archon.center = new MapLocation(x, y); myBase = new MapLocation(twiceCenterX / 2, twiceCenterY / 2).directionTo(Archon.center); enemyBase = myBase.opposite(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } }
@SuppressWarnings("fallthrough") static void addInfo(int id, Team team, RobotType robotType, MapLocation loc) throws GameActionException { boolean newLoc = false; // use knownTypes because team, time, and location can come from intercepting signals boolean newRobot = knownTypes[id] == null; knownTeams[id] = team; knownTypes[id] = robotType; if (loc != null && loc.x != MAP_NONE) { // loc.y assumed if (knownLocations[id] == null) newLoc = true; knownTimes[id] = rc.getRoundNum(); knownLocations[id] = loc; } if (rc.getType().canMessageSignal() && (newRobot || newLoc) && rc.getRoundNum() - enrollment > 10) { if (team == Team.NEUTRAL) { SignalUnit s = new SignalUnit(id, team, robotType, loc); s.add(); typeSignals[typeSignalsSize++] = s.toInt(); neutralIds[neutralIdsSize++] = id; neutralTypes[neutralTypesSize++] = robotType; neutralLocations[neutralLocationsSize++] = loc; } else { switch (robotType) { case VIPER: if (team != myTeam) break; case TURRET: case TTM: if (robotType == RobotType.VIPER || team != enemyTeam) break; case ARCHON: case ZOMBIEDEN: case BIGZOMBIE: new SignalUnit(id, team, robotType, loc).add(); if (newRobot) typeSignals[typeSignalsSize++] = new SignalUnit(id, team, robotType).toInt(); break; default: break; } } } }
@Override public boolean runInner(RobotController rc) throws GameActionException { if (rc.getRoundNum() == Common.enrollment) { target = new Target(Common.enemyBase); target.weights.put(Target.TargetType.ZOMBIE_ATTACK, Target.TargetType.Level.INACTIVE); Common.models.addFirst(target); } move(rc); attack(rc, rc.senseNearbyRobots(Common.sightRadius, Common.enemyTeam)); return false; }
/** * Expensive method. Should call upon initialization only. * * @param rc * @throws GameActionException */ static void senseRubble(RobotController rc) throws GameActionException { int roundNum = rc.getRoundNum(); for (int x = -straightSight; x <= straightSight; ++x) { for (int y = -straightSight; y <= straightSight; ++y) { MapLocation loc = rc.getLocation().add(x, y); if (rc.canSense(loc)) { rubbleTimes[loc.x % MAP_MOD][loc.y % MAP_MOD] = roundNum; mapRubble[loc.x % MAP_MOD][loc.y % MAP_MOD] = rc.senseRubble(loc); } } } }
public void run() { while (true) { try { currentLocation = rc.getLocation(); roundNumber = rc.getRoundNum(); doTurn(); Clock.yield(); } catch (GameActionException e) { System.out.println(e.getMessage()); e.printStackTrace(); } } }
static void build( RobotController rc, Direction dir, RobotType robotType, LowStrategy lowStrategy, Target.TargetType targetType, MapLocation targetLocation) throws GameActionException { buildCommon(rc, dir, robotType); int round = rc.getRoundNum() + robotType.buildTurns - 1; Signals.buildStrategy[round] = new SignalStrategy(Common.highStrategy, lowStrategy, targetType, Common.archonIds); Signals.buildTarget[round] = targetLocation; }
/** * 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); } } }
static void activate( RobotController rc, MapLocation loc, RobotType robotType, LowStrategy lowStrategy, Target.TargetType targetType, MapLocation targetLocation) throws GameActionException { activateCommon(rc, loc); // abusing build pipeline int round = rc.getRoundNum() + 1; Signals.buildStrategy[round] = new SignalStrategy(Common.highStrategy, lowStrategy, targetType, Common.archonIds); Signals.buildTarget[round] = targetLocation; }
static void senseParts(RobotController rc) throws GameActionException { int roundNum = rc.getRoundNum(); for (MapLocation loc : rc.sensePartLocations(sightRadius)) { if (mapParts[loc.x % MAP_MOD][loc.y % MAP_MOD] == 0) { double parts = rc.senseParts(loc); if (parts >= PART_KEEP_THRESH) partLocations[partLocationsSize++] = loc; mapParts[loc.x % MAP_MOD][loc.y % MAP_MOD] = parts; } partsTimes[loc.x % MAP_MOD][loc.y % MAP_MOD] = roundNum; } // if(robotType == RobotType.ARCHON && rand.nextInt(1) == 0) { // // cull list // ListIterator<MapLocation> it = partLocations.listIterator(); // while(it.hasNext()) { // MapLocation loc = it.next(); // if(rc.canSense(loc) && rc.senseParts(loc) == 0) it.remove(); // } // } }
/** * Code to run every turn. * * @param rc */ static void runBefore(RobotController rc) throws GameActionException { // -2 for build signals Signals.maxMessages = GameConstants.MESSAGE_SIGNALS_PER_TURN - 2; read = Signals.readSignals(rc); sent = 0; int turn = rc.getRoundNum(); switch (turn - enrollment) { case 0: if (targetType != null && Signals.targetsSize > 0) { models.addFirst(new Target(targetType, Signals.targets[0])); } break; case 1: for (int i = 0; i < sqrt.length; ++i) sqrt[i] = Math.sqrt(i); break; case 2: // Sense rubble a little after construction // TODO: change to 3(?) to avoid overlapping with action senseRubble(rc); break; default: break; } if (canMessageSignal) { sendRadius = 2 * sightRadius; sendBoundariesLow = false; sendBoundariesHigh = false; senseParts(rc); } updateMap(rc); if (turn > 5) { robotInfos = rc.senseNearbyRobots(); for (RobotInfo info : robotInfos) { addInfo(info); } } }
private static void rushMicro(RobotController rc, RobotInfo[] hostiles) throws GameActionException { // Prioritizes attacking turrets. RobotInfo bestEnemy = null; boolean canAttackBestEnemy = false; int bestEnemyDist = 10000; // only care if can't hit for (RobotInfo hostile : hostiles) { // Can attack this enemy. int dist = myLoc.distanceSquaredTo(hostile.location); // Summary: // Prioritizes enemies over zombies. // Prioritizes turret enemies over other enemies. // Prioritizes lowest health enemy last if (dist <= attackRadius) { if (bestEnemy != null) { if (bestEnemy.team == enemyTeam) { // best is already enemy if (hostile.team == enemyTeam) { // found an enemy if (countsAsTurret(bestEnemy.type)) { if (countsAsTurret(hostile.type)) { // Take lowest health if (bestEnemy.health > hostile.health) bestEnemy = hostile; } } else { if (countsAsTurret(hostile.type)) { bestEnemy = hostile; } else { // Take lowest health if (bestEnemy.health > hostile.health) bestEnemy = hostile; } } } } else { // best is not an enemy! if (hostile.team == enemyTeam) { // found an enemy bestEnemy = hostile; } else { // Take lowest health if (bestEnemy.health > hostile.health) bestEnemy = hostile; } } } else { bestEnemy = hostile; } canAttackBestEnemy = true; } else { // Only update best enemy if you can't attack best enemy if (!canAttackBestEnemy) { if (bestEnemy != null) { // Pick the closest one if (bestEnemyDist > dist) { bestEnemyDist = dist; bestEnemy = hostile; } } else { bestEnemyDist = dist; bestEnemy = hostile; } } } } rc.setIndicatorString(0, "Round: " + rc.getRoundNum() + ", Best enemy: " + bestEnemy); if (rc.isCoreReady()) { // If there is a best enemy, attack him. if (bestEnemy != null) { // Move closer only if blocking someone. if (rc.canAttackLocation(bestEnemy.location)) { if (isBlockingSomeone(rc, bestEnemy.location)) { Direction desired = myLoc.directionTo(bestEnemy.location); Direction dir = Movement.getBestMoveableDirection(desired, rc, 2); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, desired)) { rc.clearRubble(desired); } else if (shouldMine(rc, desired.rotateLeft())) { rc.clearRubble(desired.rotateLeft()); } else if (shouldMine(rc, desired.rotateRight())) { rc.clearRubble(desired.rotateRight()); } } } // If can't attack it, move closer! else { Direction desired = myLoc.directionTo(bestEnemy.location); Direction dir = Movement.getBestMoveableDirection(desired, rc, 2); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, desired)) { rc.clearRubble(desired); } else if (shouldMine(rc, desired.rotateLeft())) { rc.clearRubble(dir.rotateLeft()); } else if (shouldMine(rc, desired.rotateRight())) { rc.clearRubble(desired.rotateRight()); } } } // Otherwise move closer to destination else { if (currentDestination != null) { RobotInfo info = null; if (rc.canSenseLocation(currentDestination)) { info = rc.senseRobotAtLocation(currentDestination); } if (info != null) { // If can attack it, just only move closer if blocking someone behind. if (rc.canAttackLocation(info.location)) { if (isBlockingSomeone(rc, currentDestination)) { Direction desired = myLoc.directionTo(currentDestination); Direction dir = Movement.getBestMoveableDirection(desired, rc, 2); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, desired)) { rc.clearRubble(desired); } else if (shouldMine(rc, desired.rotateLeft())) { rc.clearRubble(desired.rotateLeft()); } else if (shouldMine(rc, desired.rotateRight())) { rc.clearRubble(desired.rotateRight()); } } } // If can't attack it, move closer! else { Direction desired = myLoc.directionTo(currentDestination); Direction dir = Movement.getBestMoveableDirection(desired, rc, 2); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, desired)) { rc.clearRubble(desired); } else if (shouldMine(rc, desired.rotateLeft())) { rc.clearRubble(desired.rotateLeft()); } else if (shouldMine(rc, desired.rotateRight())) { rc.clearRubble(desired.rotateRight()); } } } // If not there, just move closer. else { Direction desired = myLoc.directionTo(currentDestination); Direction dir = Movement.getBestMoveableDirection(desired, rc, 2); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, desired)) { rc.clearRubble(desired); } else if (shouldMine(rc, desired.rotateLeft())) { rc.clearRubble(desired.rotateLeft()); } else if (shouldMine(rc, desired.rotateRight())) { rc.clearRubble(desired.rotateRight()); } } } } } // Attack whenever you can. if (bestEnemy != null) { if (rc.isWeaponReady()) { if (rc.canAttackLocation(bestEnemy.location)) { broadcastingAttack(rc, bestEnemy); } } } }
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(); } } }
// special micro if a unit is infected by a viper private static void viperInfectedMicro(RobotController rc) throws GameActionException { // If there are enemies, consider moving closer to them then to us. RobotInfo closestEnemy = null; int enemyDist = 10000; RobotInfo[] enemies = rc.senseNearbyRobots(sightRadius, enemyTeam); for (RobotInfo enemy : enemies) { int dist = myLoc.distanceSquaredTo(enemy.location); if (dist < enemyDist) { closestEnemy = enemy; enemyDist = dist; } } RobotInfo closestAlly = null; int allyDist = 10000; for (RobotInfo ally : nearbyAllies) { int dist = myLoc.distanceSquaredTo(ally.location); if (dist < allyDist) { closestAlly = ally; allyDist = dist; } } if (rc.getRoundNum() > 2100) { // Move toward s enemy if (closestEnemy != null) { if (rc.isCoreReady()) { Direction dir = Movement.getBestMoveableDirection(myLoc.directionTo(closestEnemy.location), rc, 2); if (dir != Direction.NONE) { rc.move(dir); } } } // Move away from allies. if (closestAlly != null) { if (rc.isCoreReady()) { Direction dir = Movement.getBestMoveableDirection(closestAlly.location.directionTo(myLoc), rc, 2); if (dir != Direction.NONE) { rc.move(dir); } } } } else if (rc.getHealth() < 2 * rc.getViperInfectedTurns()) { if (closestEnemy != null && closestAlly != null) { if (rc.isCoreReady()) { // When enemy is further than (or same dist) as ally, move closer to enemy. if (enemyDist >= allyDist) { Direction dir = Movement.getBestMoveableDirection(myLoc.directionTo(closestEnemy.location), rc, 1); // Move closer to enemy obviously if (dir != Direction.NONE) { rc.move(dir); } // If you could not move, see if you can attack the enemy and attack him. else { if (rc.isWeaponReady()) { if (rc.canAttackLocation(closestEnemy.location)) { broadcastingAttack(rc, closestEnemy); } } } } // If closer to the enemy, then just attack them if possible. Otherwise move closer. else { if (rc.isCoreReady()) { if (!rc.canAttackLocation(closestEnemy.location)) { Direction dir = Movement.getBestMoveableDirection( myLoc.directionTo(closestEnemy.location), rc, 2); if (dir != Direction.NONE) { rc.move(dir); } } } if (rc.isWeaponReady()) { if (rc.canAttackLocation(closestEnemy.location)) { broadcastingAttack(rc, closestEnemy); } } } } } else if (closestEnemy != null) { // Move closer if can't hit closest. Otherwise attack closest. if (rc.isCoreReady()) { if (!rc.canAttackLocation(closestEnemy.location)) { Direction dir = Movement.getBestMoveableDirection(myLoc.directionTo(closestEnemy.location), rc, 2); if (dir != Direction.NONE) { rc.move(dir); } } } if (rc.isWeaponReady()) { if (rc.canAttackLocation(closestEnemy.location)) { broadcastingAttack(rc, closestEnemy); } } } // Get the hell away from ally! else if (closestAlly != null) { if (rc.isCoreReady()) { Direction dir = Movement.getBestMoveableDirection(closestAlly.location.directionTo(myLoc), rc, 2); if (dir != Direction.NONE) { rc.move(dir); } } } } }
/** * Move and update history * * @param rc * @param dir */ static void move(RobotController rc, Direction dir) throws GameActionException { rc.move(dir); MapLocation loc = rc.getLocation(); history[historySize++] = loc; int roundNum = rc.getRoundNum(); switch (dir) { case NORTH_EAST: case EAST: case SOUTH_EAST: for (int y = -straightSight; y <= straightSight; ++y) { MapLocation senseLocation = loc.add(straightSight, y); if (rc.canSense(senseLocation)) { rubbleTimes[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = roundNum; mapRubble[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = rc.senseRubble(senseLocation); } } break; case SOUTH_WEST: case WEST: case NORTH_WEST: for (int y = -straightSight; y <= straightSight; ++y) { MapLocation senseLocation = loc.add(-straightSight, y); if (rc.canSense(senseLocation)) { rubbleTimes[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = roundNum; mapRubble[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = rc.senseRubble(senseLocation); } } break; default: break; } switch (dir) { case NORTH_WEST: case NORTH: case NORTH_EAST: for (int x = -straightSight; x <= straightSight; ++x) { MapLocation senseLocation = loc.add(x, straightSight); if (rc.canSense(senseLocation)) { rubbleTimes[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = roundNum; mapRubble[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = rc.senseRubble(senseLocation); } } break; case SOUTH_EAST: case SOUTH: case SOUTH_WEST: for (int x = -straightSight; x <= straightSight; ++x) { MapLocation senseLocation = loc.add(x, -straightSight); if (rc.canSense(senseLocation)) { rubbleTimes[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = roundNum; mapRubble[senseLocation.x % MAP_MOD][senseLocation.y % MAP_MOD] = rc.senseRubble(senseLocation); } } break; default: break; } if (robotType == RobotType.ARCHON) mapParts[loc.x % MAP_MOD][loc.y % MAP_MOD] = 0; }
static void addInfo(RobotInfo info) throws GameActionException { seenRobots[info.ID] = info; seenTimes[info.ID] = rc.getRoundNum(); addInfo(info.ID, info.team, info.type, info.location); }
static void addInfo(int id, Team team, MapLocation loc) { // not regular update since RobotType unknown knownTeams[id] = team; knownTimes[id] = rc.getRoundNum(); knownLocations[id] = loc; }
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(); } } }
protected void setIndicatorString(int i, String s) { if (Config.DEBUG) { int roundNum = rc.getRoundNum(); rc.setIndicatorString(i, String.format("%d: %s", roundNum, s)); } }