public static void enemyMicro(RobotController rc, RobotInfo bestEnemy) throws GameActionException { // Prioritize movement Direction d = myLoc.directionTo(bestEnemy.location); if (rc.isCoreReady()) { if (rc.getHealth() > (numEnemySoldiers + 1) * RobotType.SOLDIER.attackPower) { // If the enemy can be killed but we're not in range, move forward if (!rc.canAttackLocation(bestEnemy.location) && bestEnemy.health <= RobotType.SOLDIER.attackPower) { if (rc.canMove(d)) { rc.move(d); } else if (rc.canMove(d.rotateLeft())) { rc.move(d.rotateLeft()); } else if (rc.canMove(d.rotateRight())) { rc.move(d.rotateRight()); } // If not in range, see if we should move in by comparing soldier health } else { double totalOurSoldierHealth = 0; RobotInfo[] allies = rc.senseNearbyRobots(bestEnemy.location, 18, rc.getTeam()); for (RobotInfo ally : allies) { if (ally.type == RobotType.SOLDIER) { if (ally.health > numEnemySoldiers * RobotType.SOLDIER.attackPower) { totalOurSoldierHealth += ally.health; } } } // If we feel that we are strong enough, rush in. if (totalOurSoldierHealth > totalEnemySoldierHealth) { if (!rc.canAttackLocation(bestEnemy.location)) { if (rc.canMove(d)) { rc.move(d); } else if (rc.canMove(d.rotateLeft())) { rc.move(d.rotateLeft()); } else if (rc.canMove(d.rotateRight())) { rc.move(d.rotateRight()); } } } else if (4 * totalOurSoldierHealth < 3 * totalEnemySoldierHealth) { if (rc.canMove(d.opposite())) { rc.move(d.opposite()); } else if (rc.canMove(d.opposite().rotateLeft())) { rc.move(d.opposite().rotateLeft()); } else if (rc.canMove(d.opposite().rotateRight())) { rc.move(d.opposite().rotateRight()); } } } } } // Attack whenever you can if (rc.isWeaponReady()) { if (rc.canAttackLocation(bestEnemy.location)) { broadcastingAttack(rc, bestEnemy); } } }
private static void archonMicro(RobotController rc, RobotInfo enemyArchon) throws GameActionException { if (rc.isCoreReady()) { int dist = myLoc.distanceSquaredTo(enemyArchon.location); // When not adjacent to the archon, walk/mine through to him. if (dist > 2) { Direction desired = myLoc.directionTo(enemyArchon.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()); } } // When adjacent to archon, rotate to the left/right when possible. else { Direction dir = myLoc.directionTo(enemyArchon.location); if (rc.canMove(dir.rotateLeft())) { rc.move(dir.rotateLeft()); } else if (rc.canMove(dir.rotateRight())) { rc.move(dir.rotateRight()); } } } if (rc.isWeaponReady()) { if (rc.canAttackLocation(enemyArchon.location)) { rc.attackLocation(enemyArchon.location); } } }
protected RobotInfo findAttackableRobot(RobotInfo[] robots) { for (RobotInfo r : robots) { if (rc.canAttackLocation(r.location)) { return r; } } return null; }
/** * Attack a robot from infos. Assumed to have delay. * * @param rc * @param infos * @return true if attacked */ static boolean attack(RobotController rc, RobotInfo[] infos) throws GameActionException { if (Common.robotType == RobotType.VIPER) return Viper.attack(rc, infos); // TODO: better selection for (RobotInfo info : infos) { if (rc.canAttackLocation(info.location)) { rc.attackLocation(info.location); return true; } } return false; }
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); } } } }
static boolean attack(RobotController rc, RobotInfo[] infos) throws GameActionException { RobotInfo best = null; double points = -Common.MAX_ID; for (RobotInfo info : infos) { double newPoints = 300 - info.health; newPoints /= Math.max(3, Math.max(info.viperInfectedTurns, info.zombieInfectedTurns)); if (newPoints > points) { best = info; points = newPoints; } } if (best != null) { if (rc.canAttackLocation(best.location)) { rc.attackLocation(best.location); return true; } } return false; }
/** * Message-processing for non-archons Currently handles messages: Change of mode Setting * turtle-corner location * * @param rc * @throws GameActionException */ private static void processFighterSignals(RobotController rc) throws GameActionException { int cornerX = Integer.MIN_VALUE; int cornerY = Integer.MIN_VALUE; RobotType type = rc.getType(); Signal[] signals = rc.emptySignalQueue(); for (Signal s : signals) { if (s.getTeam().equals(myTeam) && s.getMessage() != null) { final int[] message = s.getMessage(); if (message[0] == SENDING_MODE) { currentMode = message[1]; } else if (message[0] == SENDING_TURTLE_X) { cornerX = message[1]; } else if (message[0] == SENDING_TURTLE_Y) { cornerY = message[1]; } } // when a soldier finds a zombie den, it signals. Other soldiers that receive // the message then should move toward the den to help kill it. Ideally, // this should make it easier to remove zombie dens near the turtle corner if (type == RobotType.SOLDIER && s.getTeam().equals(myTeam) && s.getMessage() == null) { if (rc.getLocation().distanceSquaredTo(s.getLocation()) < rc.getType().sensorRadiusSquared * 2.5 && rc.isCoreReady()) { moveTowards(rc, rc.getLocation().directionTo(s.getLocation())); } } // for turrets to attack broadcasting enemies outside of sight range if (type == RobotType.TURRET && !s.getTeam().equals(myTeam) && rc.isWeaponReady() && rc.canAttackLocation(s.getLocation())) { rc.attackLocation(s.getLocation()); } } if (cornerX > Integer.MIN_VALUE && cornerY > Integer.MIN_VALUE) { turtleCorner = new MapLocation(cornerX, cornerY); } }
public static void run(RobotController rc) { int myAttackRange = 0; Random rand = new Random(rc.getID()); Team myTeam = rc.getTeam(); Team enemyTeam = myTeam.opponent(); try { // Any code here gets executed exactly once at the beginning of the game. myAttackRange = rc.getType().attackRadiusSquared; } 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 { MapLocation myLoc = rc.getLocation(); // If this robot type can attack, check for enemies within range and attack one // guards only attack ZOMBIES RobotInfo[] enemiesWithinRange = rc.senseNearbyRobots(rc.getType().sensorRadiusSquared, Team.ZOMBIE); RobotInfo[] friendliesWithinRange = rc.senseNearbyRobots(rc.getType().sensorRadiusSquared, myTeam); int closestArchonDist = 60; MapLocation closestArchonLoc = null; for (RobotInfo f : friendliesWithinRange) { if (f.type == RobotType.ARCHON) { MapLocation curArchonLoc = f.location; if (myLoc.distanceSquaredTo(curArchonLoc) < closestArchonDist) { closestArchonDist = myLoc.distanceSquaredTo(curArchonLoc); closestArchonLoc = curArchonLoc; } } } if (closestArchonLoc != null) { if (enemiesWithinRange.length > 0) { RobotInfo nearestEnemyToArchon = enemiesWithinRange[0]; int nearestEnemyToArchonDist = nearestEnemyToArchon.location.distanceSquaredTo(closestArchonLoc); for (RobotInfo e : enemiesWithinRange) { if (e.location.distanceSquaredTo(closestArchonLoc) < nearestEnemyToArchonDist) { nearestEnemyToArchonDist = e.location.distanceSquaredTo(closestArchonLoc); nearestEnemyToArchon = e; } } // only attack/move towards if it's within 24 range of the archon if (nearestEnemyToArchonDist <= 24) { // Check if weapon is ready if (rc.isWeaponReady() && rc.canAttackLocation(nearestEnemyToArchon.location)) { rc.attackLocation(nearestEnemyToArchon.location); } else { // otherwise try to move towards the enemy if (rc.isCoreReady()) { // try to move towards enemy Direction dirToMove = myLoc.directionTo(nearestEnemyToArchon.location); if (rc.canMove(dirToMove)) { rc.move(dirToMove); } else if (rc.canMove(dirToMove.rotateLeft())) { rc.move(dirToMove.rotateLeft()); } else if (rc.canMove(dirToMove.rotateRight())) { rc.move(dirToMove.rotateRight()); } } } } } else { // if no enemies, it should try to circle nearest archon if (rc.isCoreReady()) { Direction dirToMove = myLoc.directionTo(closestArchonLoc); if (rc.canMove(dirToMove)) { rc.move(dirToMove); } else if (rc.canMove(dirToMove.rotateLeft())) { rc.move(dirToMove.rotateLeft()); } else if (rc.canMove(dirToMove.rotateRight())) { rc.move(dirToMove.rotateRight()); } } } } else { rc.setIndicatorString(1, "no archon"); // if no archons nearby, move randomly and attack if (enemiesWithinRange.length > 0) { RobotInfo nearestEnemy = enemiesWithinRange[0]; int nearestEnemyDist = nearestEnemy.location.distanceSquaredTo(myLoc); for (RobotInfo e : enemiesWithinRange) { if (e.location.distanceSquaredTo(myLoc) < nearestEnemyDist) { nearestEnemyDist = e.location.distanceSquaredTo(myLoc); nearestEnemy = e; } } if (rc.isWeaponReady() && rc.canAttackLocation(nearestEnemy.location)) { rc.attackLocation(nearestEnemy.location); } else { // otherwise try to move towards the enemy if (rc.isCoreReady()) { // try to move towards enemy Direction dirToMove = myLoc.directionTo(nearestEnemy.location); if (rc.canMove(dirToMove)) { rc.move(dirToMove); } else if (rc.canMove(dirToMove.rotateLeft())) { rc.move(dirToMove.rotateLeft()); } else if (rc.canMove(dirToMove.rotateRight())) { rc.move(dirToMove.rotateRight()); } } } } else if (rc.isCoreReady()) { Direction dirToMove = RobotPlayer.directions[(rand.nextInt(8))]; for (int i = 0; i < 8; i++) { if (rc.canMove(dirToMove)) { rc.move(dirToMove); break; } else { dirToMove = dirToMove.rotateLeft(); } } } } Clock.yield(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } }
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 zombieMicro(RobotController rc) throws GameActionException { boolean thereIsNonKitableZombie = false; RobotInfo closestEnemy = null; int closestDist = 10000; for (RobotInfo hostile : nearbyEnemies) { if (hostile.type == RobotType.FASTZOMBIE || hostile.type == RobotType.RANGEDZOMBIE) { thereIsNonKitableZombie = true; } int dist = myLoc.distanceSquaredTo(hostile.location); if (dist < closestDist) { closestDist = dist; closestEnemy = hostile; } } Direction d = myLoc.directionTo(closestEnemy.location); // if we're too close, move further away if (myLoc.distanceSquaredTo(closestEnemy.location) < 5 && rc.isCoreReady()) { Direction desired = d.opposite(); Direction dir = Movement.getBestMoveableDirection(desired, rc, 1); 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 (!thereIsNonKitableZombie) { // Only move in closer if there is no non-kitable zombie if (myLoc.distanceSquaredTo(closestEnemy.location) > attackRadius && rc.isCoreReady()) { // if we are too far, we want to move closer // Desired direction is d. Direction dir = Movement.getBestMoveableDirection(d, rc, 1); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, d)) { rc.clearRubble(d); } else if (shouldMine(rc, d.rotateLeft())) { rc.clearRubble(d.rotateLeft()); } else if (shouldMine(rc, d.rotateRight())) { rc.clearRubble(d.rotateRight()); } else { // probably meaning you are blocked by allies if (closestEnemy.type == RobotType.ZOMBIEDEN) { // It is likely that we wanted to go to that den, but possibly coincidence // If not a coincidence, bug there. if (bugging != null) { if (bugging.destination.equals(closestEnemy.location)) { bugging.turretAvoidMove(turretLocations); // If coincidence, set new bugging. } else { bugging = new Bugging(rc, closestEnemy.location); bugging.turretAvoidMove(turretLocations); } } else { bugging = new Bugging(rc, closestEnemy.location); bugging.turretAvoidMove(turretLocations); } } } } } if (rc.isWeaponReady() && rc.canAttackLocation(closestEnemy.location)) { broadcastingAttack(rc, closestEnemy); } }
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); } } } } }
private static void luringMicro(RobotController rc) throws GameActionException { boolean thereIsNonKitableZombie = false; RobotInfo closestEnemy = null; MapLocation closestOpponent = null; int closestDist = 10000; for (RobotInfo hostile : nearbyEnemies) { if (hostile.type == RobotType.FASTZOMBIE || hostile.type == RobotType.RANGEDZOMBIE) { thereIsNonKitableZombie = true; } int dist = myLoc.distanceSquaredTo(hostile.location); if (dist < closestDist) { closestDist = dist; closestEnemy = hostile; } } // try to get the closest place to lure zombie for (MapLocation loc : turretLocations) { if (closestOpponent == null) closestOpponent = loc; else if (myLoc.distanceSquaredTo(loc) < myLoc.distanceSquaredTo(closestOpponent)) closestOpponent = null; } if (closestOpponent == null) closestOpponent = nearestEnemyLocation; Direction d = null; if (closestOpponent != null) d = myLoc.directionTo(closestOpponent); else d = myLoc.directionTo(rc.getInitialArchonLocations(enemyTeam)[0]); // if we are moving directly into the zombie, try to move to the side Direction temp = myLoc.directionTo(closestEnemy.location); if (d.equals(temp)) d = d.rotateLeft().rotateLeft(); else if (d.equals(temp.rotateLeft())) d = d.rotateLeft(); else if (d.equals(temp.rotateRight())) d = d.rotateRight(); // if we're too close, move further away towards the closest turret location or the closest // enemy if (myLoc.distanceSquaredTo(closestEnemy.location) < 10 && rc.isCoreReady()) { Direction desired = d; Direction dir = Movement.getBestMoveableDirection(desired, rc, 1); 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 (!thereIsNonKitableZombie) { // Only move in closer if there is no non-kitable zombie if (myLoc.distanceSquaredTo(closestEnemy.location) > attackRadius && rc.isCoreReady()) { // if we are too far, we want to move closer // Desired direction is d. Direction dir = Movement.getBestMoveableDirection(d, rc, 1); if (dir != Direction.NONE) { rc.move(dir); } else if (shouldMine(rc, d)) { rc.clearRubble(d); } else if (shouldMine(rc, d.rotateLeft())) { rc.clearRubble(d.rotateLeft()); } else if (shouldMine(rc, d.rotateRight())) { rc.clearRubble(d.rotateRight()); } else { // probably meaning you are blocked by allies if (closestEnemy.type == RobotType.ZOMBIEDEN) { // It is likely that we wanted to go to that den, but possibly coincidence // If not a coincidence, bug there. if (bugging != null) { if (bugging.destination.equals(closestEnemy.location)) { bugging.turretAvoidMove(turretLocations); // If coincidence, set new bugging. } else { bugging = new Bugging(rc, closestOpponent); bugging.turretAvoidMove(turretLocations); } } else { bugging = new Bugging(rc, closestOpponent); bugging.turretAvoidMove(turretLocations); } } } } } if (rc.isWeaponReady() && rc.canAttackLocation(closestEnemy.location)) { broadcastingAttack(rc, closestEnemy); } }
/** * run() is the method that is called when a robot is instantiated in the Battlecode world. If * this method returns, the robot dies! */ @SuppressWarnings("unused") public static void run(RobotController rc) { // You can instantiate variables here. Direction[] directions = { Direction.NORTH, Direction.NORTH_EAST, Direction.EAST, Direction.SOUTH_EAST, Direction.SOUTH, Direction.SOUTH_WEST, Direction.WEST, Direction.NORTH_WEST }; RobotType[] robotTypes = { RobotType.SCOUT, RobotType.SOLDIER, RobotType.SOLDIER, RobotType.SOLDIER, RobotType.GUARD, RobotType.GUARD, RobotType.VIPER, RobotType.TURRET }; Random rand = new Random(rc.getID()); int myAttackRange = 0; Team myTeam = rc.getTeam(); Team enemyTeam = myTeam.opponent(); if (rc.getType() == RobotType.ARCHON) { try { // Any code here gets executed exactly once at the beginning of the game. } 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 { int fate = rand.nextInt(1000); // Check if this ARCHON's core is ready if (fate % 10 == 2) { // Send a message signal containing the data (6370, 6147) rc.broadcastMessageSignal(6370, 6147, 80); } Signal[] signals = rc.emptySignalQueue(); if (signals.length > 0) { // Set an indicator string that can be viewed in the client rc.setIndicatorString(0, "I received a signal this turn!"); } else { rc.setIndicatorString(0, "I don't any signal buddies"); } if (rc.isCoreReady()) { if (fate < 800) { // Choose a random direction to try to move in Direction dirToMove = directions[fate % 8]; // Check the rubble in that direction if (rc.senseRubble(rc.getLocation().add(dirToMove)) >= GameConstants.RUBBLE_OBSTRUCTION_THRESH) { // Too much rubble, so I should clear it rc.clearRubble(dirToMove); // Check if I can move in this direction } else if (rc.canMove(dirToMove)) { // Move rc.move(dirToMove); } } else { // Choose a random unit to build RobotType typeToBuild = robotTypes[fate % 8]; // Check for sufficient parts if (rc.hasBuildRequirements(typeToBuild)) { // Choose a random direction to try to build in Direction dirToBuild = directions[rand.nextInt(8)]; for (int i = 0; i < 8; i++) { // If possible, build in this direction if (rc.canBuild(dirToBuild, typeToBuild)) { rc.build(dirToBuild, typeToBuild); break; } else { // Rotate the direction to try dirToBuild = dirToBuild.rotateLeft(); } } } } } Clock.yield(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } */ } } else if (rc.getType() != RobotType.TURRET) { try { // Any code here gets executed exactly once at the beginning of the game. myAttackRange = rc.getType().attackRadiusSquared; } 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 { int fate = rand.nextInt(1000); if (fate % 5 == 3) { // Send a normal signal rc.broadcastSignal(80); } boolean shouldAttack = false; // If this robot type can attack, check for enemies within range and attack one if (myAttackRange > 0) { RobotInfo[] enemiesWithinRange = rc.senseNearbyRobots(myAttackRange, enemyTeam); RobotInfo[] zombiesWithinRange = rc.senseNearbyRobots(myAttackRange, Team.ZOMBIE); if (enemiesWithinRange.length > 0) { shouldAttack = true; // Check if weapon is ready if (rc.isWeaponReady()) { rc.attackLocation( enemiesWithinRange[rand.nextInt(enemiesWithinRange.length)].location); } } else if (zombiesWithinRange.length > 0) { shouldAttack = true; // Check if weapon is ready if (rc.isWeaponReady()) { rc.attackLocation( zombiesWithinRange[rand.nextInt(zombiesWithinRange.length)].location); } } } if (!shouldAttack) { if (rc.isCoreReady()) { if (fate < 600) { // Choose a random direction to try to move in Direction dirToMove = directions[fate % 8]; // Check the rubble in that direction if (rc.senseRubble(rc.getLocation().add(dirToMove)) >= GameConstants.RUBBLE_OBSTRUCTION_THRESH) { // Too much rubble, so I should clear it rc.clearRubble(dirToMove); // Check if I can move in this direction } else if (rc.canMove(dirToMove)) { // Move rc.move(dirToMove); } } } } Clock.yield(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } } else if (rc.getType() == RobotType.TURRET) { try { myAttackRange = rc.getType().attackRadiusSquared; } catch (Exception e) { 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 this robot type can attack, check for enemies within range and attack one if (rc.isWeaponReady()) { RobotInfo[] enemiesWithinRange = rc.senseNearbyRobots(myAttackRange, enemyTeam); RobotInfo[] zombiesWithinRange = rc.senseNearbyRobots(myAttackRange, Team.ZOMBIE); if (enemiesWithinRange.length > 0) { for (RobotInfo enemy : enemiesWithinRange) { // Check whether the enemy is in a valid attack range (turrets have a minimum range) if (rc.canAttackLocation(enemy.location)) { rc.attackLocation(enemy.location); break; } } } else if (zombiesWithinRange.length > 0) { for (RobotInfo zombie : zombiesWithinRange) { if (rc.canAttackLocation(zombie.location)) { rc.attackLocation(zombie.location); break; } } } } Clock.yield(); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } } }