// This method will attempt to spawn in the given direction (or as close to it as possible) static boolean trySpawn(Direction d, RobotType type) { if (!rc.hasSpawnRequirements(type)) return false; int offsetIndex = 0; int[] offsets = {0, 1, -1, 2, -2, 3, -3, 4}; int dirint = directionToInt(d); while (offsetIndex < 8) { int i = (dirint + offsets[offsetIndex] + 8) % 8; Direction spawn = directions[i]; if (rc.canSpawn(spawn, type) && rc.hasSpawnRequirements(type)) { try { rc.spawn(spawn, type); strategy.addUnit(type); } catch (GameActionException e) { System.out.println("Spawn exception"); // e.printStackTrace(); } return true; } offsetIndex++; } return false; }
// Factories and supply depots private static void runBuilding() { // Most builds spawn units if (myType.canSpawn()) strategy = new BuildStrategy(rc); while (true) { if (rc.isCoreReady() && myType.canSpawn()) { threats.update(); RobotType build = strategy.getBuildOrder(); if (build != null) trySpawn(rc.getLocation().directionTo(threats.enemyHQ), build); } doTransfer(); rc.yield(); } }
// Beavers private static void runBeaver() { strategy = new BuildStrategy(rc); rand = new Random(rc.getID()); while (true) { threats.update(); myLoc = rc.getLocation(); if (rc.isCoreReady()) { RobotType build = strategy.getBuildOrder(); if (build != null) tryBuild(rc.getLocation().directionTo(threats.enemyHQ), build); } // Attack if there is an enemy in sight if (rc.isWeaponReady()) attackWeakest(); double ore = rc.senseOre(rc.getLocation()); // Move if we can and want to if (rc.isCoreReady()) { boolean ignoreThreat = overwhelms(); if (!ignoreThreat && shouldRetreat()) { doRetreatMove(); // Pull back if in range of the enemy guns } else { doMinerMove(); if (ore == 0 && rc.isCoreReady()) { // We didn't find ore nearby doSearchMove(); } } } // Mine if possible if (rc.isCoreReady() && ore > 0) { try { rc.mine(); } catch (GameActionException e) { System.out.println("Mining Exception"); // e.printStackTrace(); } } doTransfer(); rc.yield(); } }
// This method will attempt to build in the given direction (or as close to it as possible) static boolean tryBuild(Direction d, RobotType type) { int offsetIndex = 0; int[] offsets = {0, 1, -1, 2, -2, 3, -3, 4}; int dirint = directionToInt(d); while (offsetIndex < 8) { int i = (dirint + offsets[offsetIndex] + 8) % 8; Direction build = directions[i]; MapLocation m = myLoc.add(build); if (rc.canBuild(build, type) && !wouldBlock(build) && !threats.isThreatened(m)) { try { rc.build(directions[i], type); strategy.addUnit(type); } catch (GameActionException e) { System.out.println("Build exception"); // e.printStackTrace(); } return true; } offsetIndex++; } return false; }
// HQ is responsible for collating unit counts and broadcasting them each turn // It also needs to pass on its supply each turn and fire if there are enemies in range private static void runHQ() { // double lastOre = 500; strategy = new BuildStrategy(rc); while (true) { threats.update(); strategy.broadcast(); // double oreIncome = rc.getTeamOre() - lastOre + strategy.oreSpent(); // System.out.println("Ore income " + oreIncome + " per miner = " + (oreIncome-5) / // (strategy.units(RobotType.MINER) + strategy.units(RobotType.BEAVER))); // See if we need to spawn a beaver if (rc.isCoreReady()) { RobotType build = strategy.getBuildOrder(); if (build != null) { trySpawn(rc.getLocation().directionTo(threats.enemyHQ), build); } } // Attack if there is an enemy in sight if (rc.isWeaponReady()) { int senseRange = RobotType.HQ.attackRadiusSquared; MapLocation[] myTowers = rc.senseTowerLocations(); if (myTowers.length >= 5) { senseRange = 52; // This is slightly larger than the real range but does include all possible // enemies that can be hit with splash attackRange = GameConstants.HQ_BUFFED_ATTACK_RADIUS_SQUARED; } else if (myTowers.length >= 2) { attackRange = GameConstants.HQ_BUFFED_ATTACK_RADIUS_SQUARED; } else { attackRange = senseRange; } RobotInfo[] enemies = rc.senseNearbyRobots(senseRange, enemyTeam); // Pick the first valid target MapLocation best = null; for (RobotInfo e : enemies) { int range = e.location.distanceSquaredTo(myLoc); if (range <= attackRange) { best = e.location; break; } if (myTowers.length >= 5) { // Check for tiles adjacent to the enemy as they might be in splash range Direction d = e.location.directionTo(myLoc); if (e.location.add(d).distanceSquaredTo(myLoc) <= attackRange) { best = e.location.add(d); break; } if (e.location.add(d.rotateLeft()).distanceSquaredTo(myLoc) <= attackRange) { best = e.location.add(d.rotateLeft()); break; } if (e.location.add(d.rotateRight()).distanceSquaredTo(myLoc) <= attackRange) { best = e.location.add(d.rotateRight()); break; } } } if (best != null) { try { rc.attackLocation(best); } catch (GameActionException e) { System.out.println("HQ attack exception"); // e.printStackTrace(); } } } doTransfer(); // lastOre = rc.getTeamOre(); rc.yield(); } }