public static void workOnCache(RobotController rc, int bytecodeLimit) { if (cacheFinished) return; int mapWidth = rc.getMapWidth(); int mapHeight = rc.getMapHeight(); int x, y; if (workStarted) { x = workLocX; y = workLocY; } else { x = mapWidth - 1; y = mapHeight - 1; workStarted = true; } outerloop: while (x >= 0) { while (y >= 0) { terrain[x][y] = rc.senseTerrainTile(new MapLocation(x, y)); y--; // TODO: this is in a tight loop so it would be nice to do this check less often if (Clock.getBytecodeNum() > bytecodeLimit) break outerloop; } y = mapHeight - 1; x--; } workLocX = x; workLocY = y; if (x < 0) cacheFinished = true; }
public static void timerEnd(String message) { int endBytecodeNum = Clock.getBytecodeNum(); int endRoundNum = Clock.getRoundNum(); if (endRoundNum == startRoundNum) System.out.format( "timed %s: took %d bytecodes\n", message, endBytecodeNum - startBytecodeNum); else System.out.format( "timed %s: took %d turns + %d bytecodes\n", message, endRoundNum - startRoundNum, endBytecodeNum - startBytecodeNum); }
private static void turn() throws GameActionException { if (rc.getHealth() <= 6 * RobotType.SOLDIER.attackPower) { MessageBoard.PASTR_DISTRESS_SIGNAL.writeInt(Clock.getRoundNum()); } // do speculative pathing calculations int bytecodeLimit = 9000; MapLocation[] enemyPastrs = rc.sensePastrLocations(them); for (int i = 0; i < enemyPastrs.length; i++) { if (Clock.getBytecodeNum() > bytecodeLimit) break; Bfs.work(enemyPastrs[i], Bfs.PRIORITY_LOW, bytecodeLimit); } }
// HQ or pastr calls this function to spend spare bytecodes computing paths for soldiers public static void work(MapLocation dest, int priority, int bytecodeLimit) throws GameActionException { int page = findFreePage(dest, priority); Debug.indicate("path", 1, "BFS Pathing to " + dest.toString() + "; using page " + page); if (page == -1) return; // We can't do any work, or don't have to if (!dest.equals(previousDest)) { Debug.indicate("path", 0, "BFS initingQueue"); initQueue(dest); } else { Debug.indicate("path", 0, "BFS queue already inited"); } previousDest = dest; previousRoundWorked = Clock.getRoundNum(); previousPage = page; int mapWidth = rc.getMapWidth(); int mapHeight = rc.getMapHeight(); MapLocation enemyHQ = rc.senseEnemyHQLocation(); boolean destInSpawn = dest.distanceSquaredTo(enemyHQ) <= 25; while (locQueueHead != locQueueTail && Clock.getBytecodeNum() < bytecodeLimit) { // pop a location from the queue MapLocation loc = locQueue[locQueueHead]; locQueueHead++; int locX = loc.x; int locY = loc.y; for (int i = 8; i-- > 0; ) { int x = locX + dirsX[i]; int y = locY + dirsY[i]; if (x >= 0 && y >= 0 && x < mapWidth && y < mapHeight && !wasQueued[x][y]) { MapLocation newLoc = new MapLocation(x, y); if (rc.senseTerrainTile(newLoc) != TerrainTile.VOID && (destInSpawn || !Bot.isInTheirHQAttackRange(newLoc))) { publishResult(page, newLoc, dest, dirs[i]); // push newLoc onto queue locQueue[locQueueTail] = newLoc; locQueueTail++; wasQueued[x][y] = true; } } } } boolean finished = locQueueHead == locQueueTail; Debug.indicate("path", 2, "BFS finished = " + finished + "; locQueueHead = " + locQueueHead); writePageMetadata(page, Clock.getRoundNum(), dest, priority, finished); }
public static void dig(MapLocation initial_dig_location) throws GameActionException { if (Scanner.says_there_are_targets_in_range() && my_type.canAttack()) return; if (my_type == RobotType.TURRET) return; Direction initial_dig_direction; if (initial_dig_location == null || initial_dig_location == current_location) { initial_dig_direction = Direction.NORTH; } else { initial_dig_direction = current_location.directionTo(initial_dig_location); } for (int offset : combat_directions) { if (Clock.getBytecodeNum() > byte_code_limiter - 300) return; Direction try_to_clear = Direction.values()[(initial_dig_direction.ordinal() + offset + 8) % 8]; if (rc.senseRubble(current_location.add(try_to_clear)) >= GameConstants.RUBBLE_OBSTRUCTION_THRESH) { rc.clearRubble(try_to_clear); return; } } }
/** * Compute until either bytecodes have run out or we find a destination. * * @param end Hash-map of destination. * @param bytecodes The bytecode limit. * @param broadcast Whether to broadcast the results (used by the HQ). * @return Whether we found a destination. */ public boolean compute(boolean[][] end, int bytecodes, boolean broadcast) { // cache variables int min, w, x, y; int[] weight; MapLocation next, nbr, prev, p; Direction dir; final BucketQueue<MapLocation> queue = this.queue; final int[][] distance = this.distance; final Direction[][] from = this.from; // final MapLocation[][] parent = this.parent; final boolean[][] unsafe = getUnsafe(); // int iters = 0; // int bc = Clock.getBytecodeNum(); while (queue.size > 0) { // iters++; if (Clock.getBytecodeNum() >= bytecodes - 500) { break; } // RC.setIndicatorString(0, Integer.toString(min)); // ALERT: queue.min is valid only after a call to deleteMin()! next = queue.deleteMin(); min = queue.min; x = next.x; y = next.y; // check if we have already visited this node if (min == distance[x][y]) { if (unsafe[x][y]) min += 100; dir = from[x][y]; /* * if (dir != null) { * prev = next.subtract(dir); * p = parent[prev.x][prev.y]; * if (min <= distance[p.x][p.y] + PARENT_DIST) { * parent[x][y] = p; * } else { * parent[x][y] = prev; * } * } */ if (broadcast) { try { messagingSystem.writePathingInfo(next, dir, min, null /* parent[x][y] */); } catch (GameActionException e) { // e.printStackTrace(); } } // if (end[x][y]) { // reached = next; // break; // } weight = WEIGHT[RC.senseTerrainTile(next).ordinal()]; int i; if (dir == null) { dir = Direction.NORTH; i = 8; } else if (dir.isDiagonal()) { dir = dir.rotateLeft().rotateLeft(); i = 5; } else { dir = dir.rotateLeft(); i = 3; } for (; --i >= 0; dir = dir.rotateRight()) { nbr = next.add(dir); if (RC.senseTerrainTile(nbr).isTraversableAtHeight(RobotLevel.ON_GROUND)) { w = min + weight[dir.ordinal()]; x = nbr.x; y = nbr.y; if (from[x][y] == null) { queue.insert_fast(w, nbr); // System.out.println("inserted " + nbr + " with distance " + w + " from " + dir); distance[x][y] = w; from[x][y] = dir; } else { if (w < distance[x][y]) { queue.insert_fast(w, nbr); distance[x][y] = w; from[x][y] = dir; } } } } } } // bc = Clock.getBytecodeNum() - bc; // RC.setIndicatorString(2, "average Dijkstra bytecodes: " + bc / iters); return reached != null; }
public static void timerStart() { startRoundNum = Clock.getRoundNum(); startBytecodeNum = Clock.getBytecodeNum(); }
public static void debugBytecodes(String message) { System.out.format( "turn: %d, bytecodes: %d: %s\n", Clock.getRoundNum(), Clock.getBytecodeNum(), message); }
public BFSNoiseTower() throws GameActionException { System.out.println("start " + Clock.getBytecodeNum()); queue[0] = currentLocation; dir[17][17] = Direction.OMNI; for (int i = 7; i >= 0; i--) { Direction d = directions[i]; MapLocation loc = currentLocation.add(d); TerrainTile there = RC.senseTerrainTile(loc); if (!there.isTraversableAtHeight(RobotLevel.ON_GROUND)) continue; int x = loc.x - currentLocation.x; int y = loc.y - currentLocation.y; dir[x + 17][y + 17] = d.opposite(); queue[at] = loc; at++; } for (int s = 1; s < at; s++) { if (s % 30 == 0 && RC.isActive()) { if (target == null || target.distanceSquaredTo(ALLY_PASTR_COUNT > 0 ? ALLY_PASTR_LOCS[0] : currentLocation) <= 5) { earlyNearbyCows(); } MapLocation realTarget = target.add(currentLocation.directionTo(target), 3); if (RC.canAttackSquare(realTarget)) RC.attackSquare(realTarget); target = target.add(target.directionTo(currentLocation)); } Direction initD = dir[queue[s].x - currentLocation.x + 17][queue[s].y - currentLocation.y + 17]; Direction aD; Direction bD; if (initD.isDiagonal()) { aD = initD.rotateLeft().rotateLeft(); bD = initD.rotateRight(); } else { aD = initD.rotateLeft().rotateLeft().rotateLeft(); bD = initD.rotateRight().rotateRight(); } for (Direction d = aD; d != bD; d = d.rotateLeft()) { MapLocation loc = queue[s].add(d); TerrainTile there = RC.senseTerrainTile(loc); if (!there.isTraversableAtHeight(RobotLevel.ON_GROUND)) continue; int x = loc.x - currentLocation.x; int y = loc.y - currentLocation.y; if (x * x + y * y > 200) continue; if (dir[x + 17][y + 17] == null) { dir[x + 17][y + 17] = d.opposite(); queue[at] = loc; at++; } } } System.out.println("end " + Clock.getBytecodeNum()); System.out.println("at " + at); }
public boolean compute(int bytecodes) { // cache variables int d, w, e, x, y; int[] weight; MapLocation next, nbr; Direction dir; final BucketQueue<MapLocation> queue = this.queue; final int[][] distance = this.distance; final Direction[][] from = this.from; // int iters = 0; // int bc = Clock.getBytecodeNum(); while (queue.size > 0) { // iters++; if (Clock.getBytecodeNum() >= bytecodes - 600) { break; } // RC.setIndicatorString(0, Integer.toString(min)); // ALERT: queue.min is valid only after a call to deleteMin()! next = queue.deleteMin(); x = next.x; y = next.y; d = distance[x][y]; // check if we have already visited this node if (!visited[x][y]) { visited[x][y] = true; /* * if (broadcast) { * try { * messagingSystem.writePathingDirection(next, from[x][y]); * } catch (GameActionException ex) { * ex.printStackTrace(); * } * } */ weight = WEIGHT[RC.senseTerrainTile(next).ordinal()]; dir = from[x][y]; int i; if (dir == Direction.NONE) { dir = Direction.NORTH; i = 8; } else if (dir.isDiagonal()) { dir = dir.rotateLeft().rotateLeft(); i = 5; } else { dir = dir.rotateLeft(); i = 3; } for (; --i >= 0; dir = dir.rotateRight()) { nbr = next.add(dir); if (RC.senseTerrainTile(nbr).isTraversableAtHeight(RobotLevel.ON_GROUND)) { w = d + weight[dir.ordinal()]; e = w + heuristic(next, dest); x = nbr.x; y = nbr.y; if (from[x][y] == null) { queue.insert(e, nbr); // if (RC.getRobot().getID() == 118) // System.out.println("inserted " + nbr + ": " + w + " " + e); distance[x][y] = w; // estimate[x][y] = e; from[x][y] = dir; } else { if (w < distance[x][y]) { queue.insert(e, nbr); distance[x][y] = w; // estimate[x][y] = e; from[x][y] = dir; visited[x][y] = false; } } } } } } // bc = Clock.getBytecodeNum() - bc; // RC.setIndicatorString(2, "average DStar bytecodes: " + (iters > 0 ? bc / iters : bc)); return arrived(dest); }