public static void continueComputation() { // System.out.println("b" + Clock.getBytecodesLeft()); if (!started) return; while (!que.isEmpty()) { if (Clock.getBytecodesLeft() < 2000) return; MapLocation loc = que.poll().b; if (visited[loc.x][loc.y]) continue; visited[loc.x][loc.y] = true; int thisDist = distances[loc.x][loc.y] + costs[loc.x][loc.y]; int nextX, nextY, dy; for (int dx = -1; dx <= 1; ++dx) for (dy = -1; dy <= 1; ++dy) { nextX = loc.x + dx; nextY = loc.y + dy; if (nextX < 0 || nextX >= gridWidth || nextY < 0 || nextY >= gridHeight) continue; if (distances[nextX][nextY] > thisDist) { distances[nextX][nextY] = thisDist; que.add(Pair.of(thisDist, new MapLocation(nextX, nextY))); parents[nextX][nextY] = loc; } } // System.out.println("c" + Clock.getBytecodesLeft()); } done = true; }
// returns the number of enemy/allied robots if a robot were to go in each direction. // number of allied is in 10s place, number of enemies is in 1s, a 100 means the direction is // blocked public static int[] getNeighborStats(int badLocs) throws GameActionException { // TODO: Remove this int a = Clock.getBytecodesLeft(); Robot[] NearbyRobots = mRC.senseNearbyGameObjects( Robot.class, 2 * 2 + 2 * 2, ARobot.mEnemy); // 2 in either direction MapLocation roboLoc = mRC.getLocation(); // This array is NUM_DIR + 1 0s, the +1 is for the not moving location int[] eachDirectionStats = {0, 0, 0, 0, 0, 0, 0, 0, 0}; ArrayList<LocationAndIndex> directionLocs = new ArrayList<LocationAndIndex>(); Direction tempDir; // Initialize all the locations for (int i = 0; i < NUM_DIR; i++) { tempDir = Direction.values()[i]; if (mRC.canMove(tempDir) && ((badLocs >> i) & 1) != 1) { directionLocs.add(new LocationAndIndex(roboLoc.add(tempDir), i)); } else { eachDirectionStats[i] = 100; // This signifies the spot is not movable } } // Go through all the robots and see if they're near any of the squares next to us MapLocation tempLocation = null; for (Robot r : NearbyRobots) { tempLocation = mRC.senseRobotInfo(r).location; for (LocationAndIndex mp : directionLocs) { if (tempLocation.distanceSquaredTo(mp.mp) < 2) { // 2 means directly next to us eachDirectionStats[mp.i] += 1; } } if (tempLocation.distanceSquaredTo(roboLoc) < 2) { eachDirectionStats[NUM_DIR] += 1; } } mRC.setIndicatorString(1, "bytecode used for neighbor: " + (a - Clock.getBytecodesLeft())); return eachDirectionStats; }
// Computers private static void runOther() { int numTowers = -1; while (true) { threats.update(); myLoc = rc.getLocation(); // Move if we can and want to if (rc.isCoreReady() && myType.canMove()) { if (shouldRetreat()) doRetreatMove(); // Pull back if in range of the enemy guns else doAdvanceMove(); // Move towards our HQ } doTransfer(); // Perform a background breadth first search to the enemy HQ if (myType == RobotType.COMPUTER && Clock.getBytecodesLeft() > 1000) { bfs.work(threats.enemyHQ, Bfs.PRIORITY_HIGH, 1000, numTowers != threats.enemyTowers.length); } numTowers = threats.enemyTowers.length; rc.yield(); } }
// Supply our units // Getting supply to the buildings producing units is cool private static void doTransfer() { double supply = rc.getSupplyLevel(); double supplyToKeep = myType.supplyUpkeep * 10; // 10 turns worth of supply if (myType == RobotType.COMMANDER) supplyToKeep *= 10; if (supply < supplyToKeep) return; RobotInfo[] robots = rc.senseNearbyRobots(GameConstants.SUPPLY_TRANSFER_RADIUS_SQUARED, myTeam); // Pass to first neighbour with half the supply we have RobotInfo target = null; // Pick the nearest ally with the least supply for (RobotInfo r : robots) { // Never pass supply to buildings that can't spawn or to the HQ if (r.type == RobotType.HQ || r.type == RobotType.TOWER || r.type == RobotType.SUPPLYDEPOT || r.type == RobotType.HANDWASHSTATION) continue; // Drone will only pass to units with 0 supply if (myType == RobotType.DRONE && r.supplyLevel > 0) continue; if (target == null || r.supplyLevel < target.supplyLevel) target = r; if (Clock.getBytecodesLeft() < 600) break; } double toTransfer = supply - supplyToKeep; if (target == null || supply < target.supplyLevel * 2.0) return; // Keep half of what we have available unless we are the HQ if (target.type != RobotType.HQ) toTransfer /= 2.0; try { rc.transferSupplies((int) toTransfer, target.location); } catch (GameActionException e) { System.out.println("Supply exception"); // e.printStackTrace(); } }
private boolean doWork(MapLocation dest, int priority, int stopWhen, int page) throws GameActionException { if (!dest.equals(previousDest)) { initQueue(dest); System.out.print( "Cleanser BFS to " + dest + ", page " + page + ", start round " + Clock.getRoundNum() + "\n"); } previousDest = dest; previousPage = page; previousRoundWorked = Clock.getRoundNum(); int emptyCount = 0; while (emptyCount < NUM_QUEUES && qHeads[currentQ] == qTails[currentQ]) { // Skip over empty queues emptyCount++; currentQ = (currentQ + 1) % NUM_QUEUES; } if (emptyCount == NUM_QUEUES) return true; // Finished while (Clock.getBytecodesLeft() > stopWhen) { // pop a location from the queue int data = locQueues[qHeads[currentQ]]; int locX = data >> 24; int locY = (data >> 16) & 0xff; double delay = (data & 0xffff) / 10; if (++qHeads[currentQ] % MAX_QUEUE_SIZE == 0) qHeads[currentQ] -= MAX_QUEUE_SIZE; for (int i = 8; i-- > 0; ) { int x = cropX(locX + dirsX[i]); int y = cropY(locY + dirsY[i]); boolean isDiagonal = (i <= 3); if (!processed[x][y]) { processed[x][y] = true; TerrainTile t = map.tile(x, y); if (t.isTraversable()) { MapLocation newLoc = new MapLocation(x, y); // push newLoc onto queue - pick queue according to how long the move takes double newDelay; if (isDiagonal) newDelay = diagonalDelay; else newDelay = moveDelay; int newQ = (currentQ + (int) (newDelay + (delay % 1))) % NUM_QUEUES; newDelay += delay; locQueues[qTails[newQ]] = (x << 24) | (y << 16) | (int) (newDelay * 10); if (++qTails[newQ] % MAX_QUEUE_SIZE == 0) qTails[newQ] -= MAX_QUEUE_SIZE; // System.out.print("Adding " + x + ", " + y + " to queue " + newQ + " element " + // qTails[newQ] + "\n"); publishResult(page, newLoc, dest, dirs[i], (int) newDelay); } else if (t == TerrainTile.UNKNOWN) containsUnknowns = true; } } emptyCount = 0; while (emptyCount < NUM_QUEUES && qHeads[currentQ] == qTails[currentQ]) { // Skip over empty queues emptyCount++; currentQ = (currentQ + 1) % NUM_QUEUES; } if (emptyCount == NUM_QUEUES) { // map.dump(); break; } } writePageMetadata(page, previousRoundWorked, dest, priority, (emptyCount == NUM_QUEUES)); return (emptyCount == NUM_QUEUES && containsUnknowns == false); }