private void updateStrategicInfo() throws GameActionException { theirPastrs = rc.sensePastrLocations(them); numEnemyPastrs = theirPastrs.length; ourPastrs = rc.sensePastrLocations(us); numAlliedPastrs = ourPastrs.length; int numKillsLastTurn = MessageBoard.ROUND_KILL_COUNT.readInt(); MessageBoard.ROUND_KILL_COUNT.writeInt(0); maxEnemySpawns -= numKillsLastTurn; virtualSpawnCountdown--; if (virtualSpawnCountdown <= 0) { maxEnemySpawns++; int maxEnemyPopCount = maxEnemySpawns + numEnemyPastrs; virtualSpawnCountdown = (int) Math.round( GameConstants.HQ_SPAWN_DELAY_CONSTANT_1 + Math.pow(maxEnemyPopCount - 1, GameConstants.HQ_SPAWN_DELAY_CONSTANT_2)); } maxEnemySoldiers = maxEnemySpawns - numEnemyPastrs; numAlliedSoldiers = 0; Robot[] allAlliedRobots = rc.senseNearbyGameObjects(Robot.class, 999999, us); allAllies = new RobotInfo[allAlliedRobots.length]; for (int i = allAlliedRobots.length; i-- > 0; ) { RobotInfo info = rc.senseRobotInfo(allAlliedRobots[i]); allAllies[i] = info; if (info.type == RobotType.SOLDIER) numAlliedSoldiers++; } ourMilk = rc.senseTeamMilkQuantity(us); theirMilk = rc.senseTeamMilkQuantity(them); }
public void herdInward() throws GameActionException { radius = 20 - Math.min(13, (Clock.getRoundNum() % 120) * 16.0 / 120.0); MapLocation target = new MapLocation( (int) (here.x + radius * Math.cos(angle)), (int) (here.y + radius * Math.sin(angle))); angle += rate; rc.setIndicatorString(0, "angle = " + angle); if (rc.canAttackSquare(target)) { rc.attackSquare(target); } }
private double estimateNearbyCowGrowth(MapLocation loc) { double ret = 0; int minX = Math.max(0, loc.x - 10); int minY = Math.max(0, loc.y - 10); int maxX = Math.min(rc.getMapWidth() - 1, loc.x + 10); int maxY = Math.min(rc.getMapHeight() - 1, loc.y + 10); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { if (rc.senseTerrainTile(new MapLocation(x, y)) != TerrainTile.VOID) ret += cowGrowth[x][y]; } } return ret; }
/** Approximate action delay between two locations. */ public static int heuristic(MapLocation loc1, MapLocation loc2) { int dx = Math.abs(loc1.x - loc2.x); int dy = Math.abs(loc1.y - loc2.y); int min, diff; if (dx > dy) { min = dy; diff = dx - dy; } else { min = dx; diff = dy - dx; } return (min * NORMAL_DIAGONAL + diff * NORMAL_ORTHOGONAL); }
private void updateDrawLoc() { if (RenderConfiguration.showDiscrete() || !isDoing(ActionType.MOVING)) { drawX = drawY = 0; } else { // still waiting perfection of delay system // float dist = .5f; float dist = (float) Math.max(Math.min(moving * (movementDelay / info.type.movementDelay), 1), 0); // System.out.println("moving: " + moving + "actionDelay: " + actionDelay + "total " + // totalActionRounds); drawX = -dist * dir.dx; drawY = -dist * dir.dy; } }
private void computeOutPath() throws GameActionException { Pair<Direction, Integer> pathingInfo = messagingSystem.readPathingInfo(dest); if (pathingInfo.first == null) { outPath = null; return; } RC.setIndicatorString(1, "Computing outPath"); outPath = new LocSet(); distances = new int[MAP_SIZE]; MapLocation loc = dest; int d = pathingInfo.second; while (!loc.equals(DIJKSTRA_CENTER)) { pathingInfo = messagingSystem.readPathingInfo(loc); distances[outPath.size] = d - pathingInfo.second; outPath.insert(loc); loc = loc.subtract(pathingInfo.first); } int[] diffs = new int[outPath.size - 1]; for (int i = diffs.length; --i > 0; ) { diffs[i] = distances[i + 1] - distances[i]; } // heuristic to prefer further away points on the path (which may be closer to us) for (int i = 1; i < outPath.size; i++) { distances[i] = distances[i - 1] + Math.max(1, diffs[i - 1] * 100 / (100 + 10 * i)); } }
public int evalDirection( MapLocation currentLocation, Direction dir, MapLocation goal, Direction dirToGoal, int currentMovesToGoal) { boolean hasDefusion = rc.hasUpgrade(Upgrade.DEFUSION); MapLocation square = currentLocation.add(dir); int directionPenalty; int dirDiff = Math.abs(dir.ordinal() - dirToGoal.ordinal()); if (dirDiff <= 2) { directionPenalty = this.movesAway(square, goal) - currentMovesToGoal; } else { directionPenalty = hasDefusion ? 5 : 12; } int minePenalty; if (hasDefusion) { minePenalty = this.mineHazard(square) ? 5 : 0; } else { minePenalty = this.mineHazard(square) ? 12 : 0; } int visitPenalty = 2 * this.mapIntDistribution[square.x][square.y] * (hasDefusion ? 5 : 12); return directionPenalty + minePenalty + visitPenalty; }
/** * @param rc * @param dirToCorner * @return the location of the corner in the given direction or LOCATION_NONE if it is not a * corner * @throws GameActionException */ private static MapLocation checkForCorner(RobotController rc, Direction dirToCorner) throws GameActionException { int senseRadiusMinusOneSquared = (int) Math.pow(Math.sqrt(rc.getType().sensorRadiusSquared) - 1, 2); // so that when you add one below to check for a corner, you can still sense the +1 location MapLocation[] nearby = MapLocation.getAllMapLocationsWithinRadiusSq(rc.getLocation(), senseRadiusMinusOneSquared); boolean isCorner = true; MapLocation corner = getFurthestInDirection(rc, nearby, dirToCorner); Direction[] nearDirections = {dirToCorner, dirToCorner.rotateLeft(), dirToCorner.rotateRight()}; for (Direction dir : nearDirections) { if (rc.onTheMap(corner.add(dir))) { isCorner = false; } } return isCorner ? corner : LOCATION_NONE; }
public Bfs(RobotController theRC) { rc = theRC; map = null; MAP_HEIGHT = GameConstants.MAP_MAX_HEIGHT; MAP_WIDTH = GameConstants.MAP_MAX_WIDTH; PAGE_SIZE = MAP_WIDTH * MAP_HEIGHT; NUM_PAGES = Math.min(45000 / PAGE_SIZE, MAX_PAGES); }
public void probeAndUpdateMapInfoModule( final MapInfoModule mapInfoModule, final MapLocation location, final RobotController robotController) throws GameActionException { final int probeDistance = (int) Math.floor(Math.sqrt(robotController.getType().sensorRadiusSquared)); if (mapInfoModule.eastBoundaryValue == MapInfoModule.UnknownValue) { final MapLocation foundProbeLocation = this.probeDirection(Direction.EAST, probeDistance, location, robotController); if (foundProbeLocation != null) { mapInfoModule.eastBoundaryValue = foundProbeLocation.x; } } if (mapInfoModule.westBoundaryValue == MapInfoModule.UnknownValue) { final MapLocation foundProbeLocation = this.probeDirection(Direction.WEST, probeDistance, location, robotController); if (foundProbeLocation != null) { mapInfoModule.westBoundaryValue = foundProbeLocation.x; } } if (mapInfoModule.northBoundaryValue == MapInfoModule.UnknownValue) { final MapLocation foundProbeLocation = this.probeDirection(Direction.NORTH, probeDistance, location, robotController); if (foundProbeLocation != null) { mapInfoModule.northBoundaryValue = foundProbeLocation.y; } } if (mapInfoModule.southBoundaryValue == MapInfoModule.UnknownValue) { final MapLocation foundProbeLocation = this.probeDirection(Direction.SOUTH, probeDistance, location, robotController); if (foundProbeLocation != null) { mapInfoModule.southBoundaryValue = foundProbeLocation.y; } } }
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(); } }
public static void printCoarseMap() { System.out.println("Coarse map:"); for (int x = 0; x < coarseMap[0].length; x++) { for (int y = 0; y < coarseMap.length; y++) { int numberOfObstacles = coarseMap[x][y]; System.out.print(Math.min(numberOfObstacles, 999) + " "); } System.out.println(); } }
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; }
// TODO: this takes a little too long on big maps private void computePastrScores() { int mapWidth = rc.getMapWidth(); int mapHeight = rc.getMapHeight(); double mapSize = Math.hypot(mapWidth, mapHeight); MapLocation mapCenter = new MapLocation(mapWidth / 2, mapHeight / 2); double[][] pastrScores = new double[mapWidth][mapHeight]; for (int y = 2; y < mapHeight - 2; y += 5) { for (int x = 2; x < mapWidth - 2; x += 5) { if (rc.senseTerrainTile(new MapLocation(x, y)) != TerrainTile.VOID) { MapLocation loc = new MapLocation(x, y); double distOurHQ = Math.sqrt(loc.distanceSquaredTo(ourHQ)); double distTheirHQ = Math.sqrt(loc.distanceSquaredTo(theirHQ)); if (distOurHQ < distTheirHQ) { int numCows = 0; for (int cowX = x - 2; cowX <= x + 2; cowX++) { for (int cowY = y - 2; cowY <= y + 2; cowY++) { if (rc.senseTerrainTile(new MapLocation(cowX, cowY)) != TerrainTile.VOID) { numCows += cowGrowth[cowX][cowY]; } } } if (numCows >= 5) { double distCenter = Math.sqrt(loc.distanceSquaredTo(mapCenter)); pastrScores[x][y] = numCows * (1 + (1.0 * distCenter - 0.5 * distOurHQ + 0.5 * distTheirHQ) / mapSize); } else { pastrScores[x][y] = -999999; // must be at least some cows } } else { pastrScores[x][y] = -999999; // only make pastrs on squares closer to our HQ than theirs } } else { pastrScores[x][y] = -999999; // don't make pastrs on void squares } } } computedPastrScores = pastrScores; }
private Direction chooseRetreatDirection() throws GameActionException { int[] numEnemiesAttackingDir = countNumEnemiesAttackingMoveDirs(); int repelX = 0; int repelY = 0; for (int i = visibleEnemies.length; i-- > 0; ) { Direction repelDir = visibleEnemies[i].location.directionTo(here); repelX += repelDir.dx; repelY += repelDir.dy; } int absRepelX = Math.abs(repelX); int absRepelY = Math.abs(repelY); Direction retreatDir; if (absRepelX >= 1.5 * absRepelY) { retreatDir = repelX > 0 ? Direction.EAST : Direction.WEST; } else if (absRepelY >= 1.5 * absRepelX) { retreatDir = repelY > 0 ? Direction.SOUTH : Direction.NORTH; } else if (repelX > 0) { retreatDir = repelY > 0 ? Direction.SOUTH_EAST : Direction.NORTH_EAST; } else { retreatDir = repelY > 0 ? Direction.SOUTH_WEST : Direction.NORTH_WEST; } // Test to see if retreatDir, or either of the adjacent directions, actually work // To work, three conditions have to be satisfied: // (a) we have to be able to move in that direction // (b) moving in that direction has to take us out of range of enemy attacks // (c) moving in that direction can't take us within range of the enemy HQ int[] tryDirs = new int[] {0, 1, -1, 2, -2, 3, -3, 4}; for (int i = 0; i < tryDirs.length; i++) { Direction tryDir = Direction.values()[(retreatDir.ordinal() + tryDirs[i] + 8) % 8]; if (!rc.canMove(tryDir)) continue; MapLocation tryLoc = here.add(tryDir); if (numEnemiesAttackingDir[tryDir.ordinal()] > 0) continue; if (Util.inHQAttackRange(tryLoc, theirHQ)) continue; return tryDir; } return null; }
protected void transferEnergon() throws GameActionException { for (Robot robot : myRC.senseNearbyGroundRobots()) { try { RobotInfo robotInfo = myRC.senseRobotInfo(robot); if (robotInfo.team == myRC.getTeam()) { MapLocation robotLocation = robotInfo.location; if (myRC.getLocation().isAdjacentTo(robotLocation)) myRC.transferEnergon( Math.max( 0, Math.min( robotInfo.maxEnergon - robotInfo.eventualEnergon, myRC.getEnergonLevel() / 2)), robotLocation, RobotLevel.ON_GROUND); } } catch (GameActionException e) { } } }
private static void moveFromCorner(RobotController rc) throws GameActionException { int minRadius = 9; // units should try to maintain a minimum of 5 squared units // away from corner // @Hope - refine max radius int maxRadius = 26 + (int) Math.pow(rc.getRobotCount() / 6, 2); // based of number // of troops the max radius increases int distanceToCorner = rc.getLocation().distanceSquaredTo(turtleCorner); if (distanceToCorner <= minRadius && rc.isCoreReady()) { Direction dir = (rc.getLocation().directionTo(turtleCorner)).opposite(); moveTowards(rc, dir); } if (distanceToCorner >= maxRadius && rc.isCoreReady()) { moveTowards(rc, rc.getLocation().directionTo(turtleCorner)); } }
// move in a given direction public static void moveInDirection(Direction d) throws GameActionException { MapLocation m = rc.getLocation().add(d); if (rc.senseRubble(m) < tooMuchRubble || Math.random() < probClearRubbleAnyways) // if it's less than 20, just move there { if (rc.isCoreReady() && rc.canMove(d)) { rc.move(d); } } else // clear it { if (rc.isCoreReady()) { rc.clearRubble(d); } } }
public static void printBigCoarseMap(RobotController rc) { System.out.println("Fine map:"); for (int x = 0; x < coarseMap[0].length * bigBoxSize; x++) { for (int y = 0; y < coarseMap.length * bigBoxSize; y++) { if (countObstacles(x, y, rc) == NORMAL_COST || countObstacles(x, y, rc) == ROAD_COST) { // there's no obstacle, so print the box's obstacle count int numberOfObstacles = coarseMap[x / bigBoxSize][y / bigBoxSize]; System.out.print(Math.min(numberOfObstacles, 999)); } else { // there's an obstacle, so print an X System.out.print("X"); } System.out.print(" "); } System.out.println(); } }
private int guessTravelRounds(MapLocation start, MapLocation dest) { int ret = (int) (GameConstants.SOLDIER_MOVE_ACTION_DELAY * Math.sqrt(start.distanceSquaredTo(dest))); MapLocation probe = start; boolean inObstacle = false; int numObstacles = 0; do { probe = probe.add(probe.directionTo(theirHQ)); if (rc.senseTerrainTile(probe) == TerrainTile.VOID) { if (!inObstacle) numObstacles++; // too big? inObstacle = true; } else { inObstacle = false; } } while (!probe.equals(theirHQ)); ret += 25 * numObstacles; return ret; }
private static boolean archonIsTooClose(RobotController rc) { boolean tooClose = false; int archonReserveDistance = (int) (Math.sqrt(rc.getRobotCount()) * 1.4); // @Hope make this more finessed List<RobotInfo> robots = Arrays.asList(rc.senseNearbyRobots(archonReserveDistance + 1, myTeam)); List<RobotInfo> archons = new ArrayList<>(); for (RobotInfo robot : robots) { if (robot.type == RobotType.ARCHON) { archons.add(robot); } } MapLocation myLocation = rc.getLocation(); for (RobotInfo archon : archons) { if (!tooClose && myLocation.distanceSquaredTo(archon.location) < archonReserveDistance) { tooClose = true; break; } } return tooClose; }
/** * 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); } } }
// Decide whether to behave aggressively or defensively. Only be aggressive if we are in attack // mode // and there is a decent number of allies around, or if we are in any mode and we have a big // numbers advantage private MicroStance chooseMicroStance(MapLocation attackTarget) throws GameActionException { if (Strategy.active == Strategy.HQ_PASTR) return MicroStance.HARRASS; if (visibleEnemies.length == 0) { return MicroStance.AGGRESSIVE; // stance doesn't matter if there are no enemies } else { int numAllies = 1; // us numAllies += Math.max( numOtherAlliedSoldiersInRange(here, RobotType.SOLDIER.sensorRadiusSquared), numOtherAlliedSoldiersInRange(Util.closest(visibleEnemies, here), 16)); if (attackTarget == null) { if (numAllies >= visibleEnemies.length * 2 || numAllies > visibleEnemies.length + 3) return MicroStance.AGGRESSIVE; else return MicroStance.DEFENSIVE; } else { if (numAllies >= 2 && numAllies >= visibleEnemies.length - 1) return MicroStance.AGGRESSIVE; else return MicroStance.DEFENSIVE; } } }
// build robots public static void buildRobots() throws GameActionException { // check if you should build if (rc.getTeamParts() > RobotType.TURRET.partCost) { // if the current type to build != null, build one of that type if (typeToBuild != null && rc.hasBuildRequirements(typeToBuild)) { buildRobot(typeToBuild); typeToBuild = null; } else { double percent = Math.random(); if (percent <= Utility.PERCENTAGE_TURRETS) // build turret { typeToBuild = RobotType.TURRET; } else if (percent <= Utility.PERCENTAGE_TURRETS + Utility.PERCENTAGE_SOLDIERS) // build a soldier { typeToBuild = RobotType.SOLDIER; } else { typeToBuild = RobotType.SCOUT; } } } }
public static void generateProposals( MapLocation locus, int distToLocus, int incrementalDist, ArrayList<Proposal> proposalList, Direction[] consideredDirs) { for (Direction d : consideredDirs) { Proposal p; if (d.isDiagonal()) { p = new Proposal(locus.add(d), d, distToLocus + incrementalDist * 14); } else { p = new Proposal(locus.add(d), d, distToLocus + incrementalDist * 10); } int val = BreadthFirst.getMapData(p.loc); if (val > 0) { // not off-map or entirely void-filled p.dist += Math.pow((val - 10000), 2) * 10; // TODO evaluate fudge factor of 10 for importance of void spaces proposalList.add(p); } } }
/** * Checks if rc can move in direction dir (runs isCoreReady and canMove). If so, moves. If not, * moves rc in any of the four directions nearest dir, if possible. * * @param rc * @param dir * @return true if rc moves else false * @throws GameActionException */ private static void moveTowards(RobotController rc, Direction dir) throws GameActionException { if (rc.isCoreReady() && !dir.equals(Direction.OMNI) && !dir.equals(Direction.NONE)) { Direction[] moveRight = { dir, dir.rotateRight(), dir.rotateLeft(), dir.rotateRight().rotateRight(), dir.rotateLeft().rotateLeft() }; Direction[] moveLeft = { dir, dir.rotateLeft(), dir.rotateRight(), dir.rotateLeft().rotateLeft(), dir.rotateRight().rotateRight() }; Direction[] nearDirections = Math.random() >= .5 ? moveRight : moveLeft; // 50% chance robot tries to move to right first for (Direction nearDir : nearDirections) { if (rc.canMove(nearDir) && rc.isCoreReady()) { rc.move(nearDir); } } if (rc.getType() != RobotType.TTM && rc.getType() != RobotType.TTM) // these types can't clear rubble { if (rc.isCoreReady() && rc.onTheMap(rc.getLocation().add(dir)) && rc.senseRubble(rc.getLocation().add(dir)) > RUBBLE_LOWER_CLEAR_THRESHOLD) { clearRubble(rc); } } } }
public static void run() throws GameActionException { rc = RobotPlayer.rc; rand = new Random(rc.getID()); // build scouts right away buildRobot(RobotType.SCOUT); while (true) { /* * INPUT */ if (rc.getLocation().equals(goal)) { goal = null; // you made it to the goal past10Locations = new ArrayList<MapLocation>(); // delete the slug trail after you reach your goal } // sense locations around you nearbyMapLocations = MapLocation.getAllMapLocationsWithinRadiusSq( rc.getLocation(), rc.getType().sensorRadiusSquared); // parts locations nearbyPartsLocations = rc.sensePartLocations(RobotType.ARCHON.sensorRadiusSquared); // find the nearest mapLocation with the most parts double maxParts = 0; MapLocation nearbyLocationWithMostParts = null; for (MapLocation loc : nearbyPartsLocations) { // add to locationsWithParts arraylist if (locationsWithParts.contains(loc) == false) { locationsWithParts.add(loc); } // find the location with the most parts double partsAtLoc = rc.senseParts(loc); if (partsAtLoc > maxParts) { maxParts = partsAtLoc; nearbyLocationWithMostParts = loc; } } // read signals Signal[] signals = rc.emptySignalQueue(); for (Signal signal : signals) { // check if the signal has parts at the location int[] message = signal.getMessage(); if (message != null && message[0] == Utility.PARTS_CODE) { // add that location to the locationsWithParts arraylist locationsWithParts.add(signal.getLocation()); } } // sense robots MapLocation myLoc = rc.getLocation(); robots = rc.senseNearbyRobots(); foes = new ArrayList<RobotInfo>(); foesWithinAttackRange = new ArrayList<RobotInfo>(); for (RobotInfo robot : robots) { if (robot.team == Team.ZOMBIE || robot.team == rc.getTeam().opponent()) // if the robot is a foe { foes.add(robot); if (myLoc.distanceSquaredTo(robot.location) < robot.type.attackRadiusSquared) { foesWithinAttackRange.add(robot); } } } int nearbyFoes = foes.size(); int nearbyFoesInAttackRange = foesWithinAttackRange.size(); /*//check stats double health = rc.getHealth(); int infectedTurns = rc.getInfectedTurns(); int robotsAlive = rc.getRobotCount(); */ /* * OUPUT */ // what to do if (nearbyFoes == 0) // if there are no foes in sight { if (rc.getTeamParts() >= RobotType.TURRET.partCost) // build if you can { buildRobots(); } else { if (maxParts > 0 && goal == null) // if there are parts nearby { // make that the goal goal = nearbyLocationWithMostParts; } else if (goal == null) // if there aren't and there is no goal { // build something or find new parts // 80% build, 20% new parts if (locationsWithParts.size() > 0 && rand.nextFloat() > .8) { goal = locationsWithParts.get(0); locationsWithParts.remove(0); goalIsASafeLocation = false; } // calculate the next goal - maybe a new parts location you got via signal } else if (goal != null) // if there is a goal, move there { moveToLocation(goal); } } } else // there are foes nearby { // message for help! if (Math.random() < probSignal) { rc.broadcastSignal(archonInTroubleSignalRadiusSquared); } if (nearbyFoesInAttackRange > 0) { goal = findSaferLocation(); rc.setIndicatorString(0, "" + goal.x + " " + goal.y); goalIsASafeLocation = true; moveToLocation(goal); } } Clock.yield(); } }
// 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 forwardishIfProtection(Direction movingDirection2) throws GameActionException { boolean stationArchon = RobotPlayer.stationArchon; // boolean tempRoamingArchon = RobotPlayer.tempRoamingArchon; if (stationArchon) return; // or do other stuff int id = RobotPlayer.id; // System.out.println(Integer.toString(id)); // int waitTurns = 1; RobotController rc = RobotPlayer.rc; int waitTurns = rc.getType() == RobotType.ARCHON ? 1 : 1; // if(rc.getRoundNum()%waitTurns ==0){// leader let the soldiers catch up if (true) { for (int i : possibleDirections) { Direction candidateDirection = Direction.values()[(movingDirection2.ordinal() + i + 8) % 8]; MapLocation candidateLocation = rc.getLocation().add(candidateDirection.dx, candidateDirection.dy); if (patient > 0) { // if (rc.getType() == RobotType.ARCHON) // System.out.println("should be an archon moving now"); MapLocation oldLoc = rc.getLocation(); if (rc.canMove(candidateDirection) && !pastLocations.contains(candidateLocation) && enoughProtectionAhead(candidateLocation)) { if (!pastLocations.contains(oldLoc)) { pastLocations.add(rc.getLocation()); } if (pastLocations.size() > 5) pastLocations.remove(0); rc.move(candidateDirection); if (rc.getType() == RobotType.ARCHON && !RobotPlayer.stationArchon) { // System.out.println("Im getting this far"); // System.out.println("I should have moved in direction: "+ // candidateDirection.toString()); } // if (rc.getType() == RobotTypse.ARCHON) // System.out.println("should have moved an archon new location " + // rc.getLocation().toString()+ "old : " + oldLoc) ; patient = Math.min(patient + 1, 30); return; } } else { if (rc.canMove(candidateDirection) && enoughProtectionAhead(candidateLocation)) { rc.move(candidateDirection); patient = Math.min(patient + 1, 30); return; } else { // dig ! if (rc.senseRubble(candidateLocation) > GameConstants.RUBBLE_OBSTRUCTION_THRESH) { rc.clearRubble(candidateDirection); return; } } } } patient = patient - 5; } }
private static Direction randomDirection() { // TODO Auto-generated method stub return Direction.values()[(int) Math.random() * 8]; }