private int computeCost(int cost, Direction faceDir, Direction nextDir) { if (nextDir.isDiagonal()) { return cost + moveDiagonally + ((faceDir == nextDir) ? 0 : 1); } else { return cost + moveOrthogonally + ((faceDir == nextDir) ? 0 : 1); } }
private static void herdTowardPastrDumb() throws GameActionException { MapLocation target = null; do { int dx = radius * attackDir.dx; int dy = radius * attackDir.dy; target = new MapLocation(pastr.x + dx, pastr.y + dy); radius--; if (radius <= (attackDir.isDiagonal() ? 3 : 5)) { attackDir = Direction.values()[nextDumbHerdDir[attackDir.ordinal()]]; radius = attackDir.isDiagonal() ? maxDiagonalRadius : maxOrthogonalRadius; } } while (tooFarOffMap(target) || !rc.canAttackSquare(target)); rc.attackSquare(target); }
/* * Head towards the nearest tile that we haven't sensed before * If there is a tie, pick the one nearest to the hq */ private static void doPatrol() { if (!droneCentred) { // start point for the spiral is 2/5 of the way from our HQ to their HQ MapLocation centre = new MapLocation( (3 * myHQ.x + 2 * threats.enemyHQ.x) / 5, (3 * myHQ.y + 2 * threats.enemyHQ.y) / 5); if (threats.isThreatened(centre) || myLoc.distanceSquaredTo(centre) <= 2) droneCentred = true; else { moveDir = myLoc.directionTo(centre); } } if (droneCentred && --droneMoveCurrent <= 0) { if (patrolClockwise) moveDir = moveDir.rotateRight(); else moveDir = moveDir.rotateLeft(); if (!moveDir.isDiagonal()) droneMoveMax++; droneMoveCurrent = droneMoveMax; } while (true) { try { if (rc.canMove(moveDir) && !threats.isThreatened(myLoc.add(moveDir))) { rc.move(moveDir); break; } else if (rc.canMove(moveDir.rotateLeft()) && !threats.isThreatened(myLoc.add(moveDir.rotateLeft()))) { rc.move(moveDir.rotateLeft()); break; } else if (rc.canMove(moveDir.rotateRight()) && !threats.isThreatened(myLoc.add(moveDir.rotateRight()))) { rc.move(moveDir.rotateRight()); break; } else if (droneCentred) { moveDir = moveDir.opposite(); patrolClockwise = !patrolClockwise; if (!moveDir.isDiagonal()) droneMoveMax++; droneMoveCurrent = droneMoveMax; } else { break; } } catch (GameActionException e) { System.out.println("Drone patrol exception"); // e.printStackTrace(); } } }
private static void herdTowardPastrSmart() throws GameActionException { if (smartLoc == null || smartLoc.distanceSquaredTo(pastr) <= GameConstants.PASTR_RANGE) { smartLoc = pastr.add( nextStartDir, nextStartDir.isDiagonal() ? maxDiagonalRadius - 3 : maxOrthogonalRadius - 3); nextStartDir = nextStartDir.rotateRight(); edgeTrimIndex = edgesX.length - 1; // Debug.indicate("herd", 0, "starting new spoke"); } while (edgeTrimIndex >= 0) { MapLocation edge = new MapLocation(pastr.x + edgesX[edgeTrimIndex], pastr.y + edgesY[edgeTrimIndex]); edgeTrimIndex--; if (isOnMap(edge) && rc.canSenseSquare(edge) && rc.senseCowsAtLocation(edge) > 1000) { MapLocation targetSquare = edge.add(pastr.directionTo(edge)); if (rc.canAttackSquare(targetSquare)) { rc.attackSquareLight(targetSquare); return; } } } while (!rc.canAttackSquare(smartLoc) || !isOnMap(smartLoc)) { Direction moveDir = smartLoc.directionTo(pastr); Direction computedMoveDir = HerdPattern.readHerdDir(smartLoc, rc); if (computedMoveDir != null) moveDir = computedMoveDir; smartLoc = smartLoc.add(moveDir); if (here.distanceSquaredTo(smartLoc) > RobotType.NOISETOWER.attackRadiusMaxSquared) { smartLoc = null; return; } if (smartLoc.equals(pastr)) return; // otherwise in some situations we could get an infinite loop } Direction herdDir = smartLoc.directionTo(pastr); Direction computedHerdDir = HerdPattern.readHerdDir(smartLoc, rc); if (computedHerdDir != null) herdDir = computedHerdDir; MapLocation targetSquare = smartLoc.add(Util.opposite(herdDir), 3); // Debug.indicate("herd", 2, "want to attack " + targetSquare.toString()); if (rc.canAttackSquare(targetSquare)) rc.attackSquare(targetSquare); smartLoc = smartLoc.add(herdDir); }
private boolean spawnSoldier() throws GameActionException { if (rc.senseRobotCount() >= GameConstants.MAX_ROBOTS) return false; // if (rc.senseRobotCount() >= 2) return false; int spawnCount = MessageBoard.SPAWN_COUNT.readInt(); Direction startDir = here.directionTo(theirHQ); if (startDir.isDiagonal()) startDir = startDir.rotateRight(); int[] offsets = new int[] {0, 2, 4, 6, 1, 3, 5, 7}; for (int i = 0; i < offsets.length; i++) { Direction dir = Direction.values()[(startDir.ordinal() + offsets[i]) % 8]; if (rc.canMove(dir)) { rc.spawn(dir); MessageBoard.SPAWN_COUNT.writeInt(spawnCount + 1); return true; } } return false; }
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); } } }
/** * 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 class BotNoiseTower extends Bot { public static void loop(RobotController theRC) throws Exception { init(theRC); while (true) { try { turn(); } catch (Exception e) { e.printStackTrace(); } rc.yield(); } } protected static void init(RobotController theRC) throws GameActionException { Bot.init(theRC); // Debug.init(theRC, "herd"); here = rc.getLocation(); // claim the assignment to build this tower so others know not to build it int numPastrLocations = MessageBoard.NUM_PASTR_LOCATIONS.readInt(); amSuppressor = true; for (int i = 0; i < numPastrLocations; i++) { MapLocation pastrLoc = MessageBoard.BEST_PASTR_LOCATIONS.readFromMapLocationList(i); if (rc.getLocation().isAdjacentTo(pastrLoc)) { amSuppressor = false; MessageBoard.TOWER_BUILDER_ROBOT_IDS.claimAssignment(i); break; } } if (amSuppressor) { int bestDistSq = 999999; int numSuppressors = MessageBoard.NUM_SUPPRESSORS.readInt(); int suppressorIndex = -1; for (int i = 0; i < numSuppressors; i++) { MapLocation target = MessageBoard.SUPPRESSOR_TARGET_LOCATIONS.readFromMapLocationList(i); int distSq = here.distanceSquaredTo(target); if (distSq < bestDistSq) { bestDistSq = distSq; suppressionTarget = target; suppressorIndex = i; } } if (suppressorIndex != -1) { MessageBoard.SUPPRESSOR_BUILDER_ROBOT_IDS.claimAssignment(suppressorIndex); } } else { // Figure out the best direction to start herding in double[] freeCows = new double[8]; double[][] cowGrowth = rc.senseCowGrowth(); Direction[] dirs = Direction.values(); for (int i = 0; i < 8; i++) { Direction dir = dirs[i]; MapLocation probe = here.add(dir); while (Util.passable(rc.senseTerrainTile(probe)) && here.distanceSquaredTo(probe) <= RobotType.NOISETOWER.attackRadiusMaxSquared) { freeCows[i] += cowGrowth[probe.x][probe.y]; probe = probe.add(dir); } } double bestScore = -1; int bestDir = -1; for (int i = 0; i < 8; i++) { double score = freeCows[i] + freeCows[(i + 1) % 8] + freeCows[(i + 2) % 8]; if (score > bestScore) { bestScore = score; bestDir = i; } } attackDir = dirs[bestDir]; } } static MapLocation here; static MapLocation pastr = null; static boolean amSuppressor; static MapLocation suppressionTarget; private static void turn() throws GameActionException { if (!rc.isActive()) return; if (amSuppressor) { MapLocation[] theirPastrs = rc.sensePastrLocations(them); MapLocation closestEnemyPastr = Util.closest(theirPastrs, here); if (closestEnemyPastr != null) { if (rc.canAttackSquare(closestEnemyPastr)) { rc.attackSquare(closestEnemyPastr); return; } else { MapLocation closer = closestEnemyPastr.add(closestEnemyPastr.directionTo(here)); if (rc.canAttackSquare(closer)) { rc.attackSquare(closer); return; } } } else { if (suppressionTarget != null && rc.canAttackSquare(suppressionTarget)) { rc.attackSquare(suppressionTarget); return; } } } pastr = findNearestAlliedPastr(); if (pastr == null || here.distanceSquaredTo(pastr) > 2 * RobotType.NOISETOWER.attackRadiusMaxSquared) { pastr = here; } herdTowardPastrDumb(); // herdTowardPastrSmart(); } private static MapLocation findNearestAlliedPastr() { MapLocation[] pastrs = rc.sensePastrLocations(us); return Util.closest(pastrs, here); } static final int maxOrthogonalRadius = (int) Math.sqrt(RobotType.NOISETOWER.attackRadiusMaxSquared); static final int maxDiagonalRadius = (int) Math.sqrt(RobotType.NOISETOWER.attackRadiusMaxSquared / 2); static Direction attackDir = Direction.NORTH; static int radius = attackDir.isDiagonal() ? maxDiagonalRadius : maxOrthogonalRadius; // static final int[] nextDumbHerdDir = new int[] { 2, 3, 4, 5, 6, 7, 1, 0 }; static final int[] nextDumbHerdDir = new int[] {1, 2, 3, 4, 5, 6, 7, 0}; private static void herdTowardPastrDumb() throws GameActionException { MapLocation target = null; do { int dx = radius * attackDir.dx; int dy = radius * attackDir.dy; target = new MapLocation(pastr.x + dx, pastr.y + dy); radius--; if (radius <= (attackDir.isDiagonal() ? 3 : 5)) { attackDir = Direction.values()[nextDumbHerdDir[attackDir.ordinal()]]; radius = attackDir.isDiagonal() ? maxDiagonalRadius : maxOrthogonalRadius; } } while (tooFarOffMap(target) || !rc.canAttackSquare(target)); rc.attackSquare(target); } private static boolean tooFarOffMap(MapLocation loc) { int W = 2; return loc.x < -W || loc.y < -W || loc.x >= rc.getMapWidth() + W || loc.y >= rc.getMapWidth() + W; } static MapLocation smartLoc = null; static Direction nextStartDir = Direction.NORTH; static int[] edgesX = new int[] {-2, -1, 0, 1, 2, -3, -2, 2, 3, -3, 3, -3, 3, -3, 3, -3, -2, 2, 3, -2, -1, 0, 1, 2}; static int[] edgesY = new int[] {3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 0, 0, -1, -1, -2, -2, -2, -2, -3, -3, -3, -3, -3}; static int edgeTrimIndex = 0; private static void herdTowardPastrSmart() throws GameActionException { if (smartLoc == null || smartLoc.distanceSquaredTo(pastr) <= GameConstants.PASTR_RANGE) { smartLoc = pastr.add( nextStartDir, nextStartDir.isDiagonal() ? maxDiagonalRadius - 3 : maxOrthogonalRadius - 3); nextStartDir = nextStartDir.rotateRight(); edgeTrimIndex = edgesX.length - 1; // Debug.indicate("herd", 0, "starting new spoke"); } while (edgeTrimIndex >= 0) { MapLocation edge = new MapLocation(pastr.x + edgesX[edgeTrimIndex], pastr.y + edgesY[edgeTrimIndex]); edgeTrimIndex--; if (isOnMap(edge) && rc.canSenseSquare(edge) && rc.senseCowsAtLocation(edge) > 1000) { MapLocation targetSquare = edge.add(pastr.directionTo(edge)); if (rc.canAttackSquare(targetSquare)) { rc.attackSquareLight(targetSquare); return; } } } while (!rc.canAttackSquare(smartLoc) || !isOnMap(smartLoc)) { Direction moveDir = smartLoc.directionTo(pastr); Direction computedMoveDir = HerdPattern.readHerdDir(smartLoc, rc); if (computedMoveDir != null) moveDir = computedMoveDir; smartLoc = smartLoc.add(moveDir); if (here.distanceSquaredTo(smartLoc) > RobotType.NOISETOWER.attackRadiusMaxSquared) { smartLoc = null; return; } if (smartLoc.equals(pastr)) return; // otherwise in some situations we could get an infinite loop } Direction herdDir = smartLoc.directionTo(pastr); Direction computedHerdDir = HerdPattern.readHerdDir(smartLoc, rc); if (computedHerdDir != null) herdDir = computedHerdDir; MapLocation targetSquare = smartLoc.add(Util.opposite(herdDir), 3); // Debug.indicate("herd", 2, "want to attack " + targetSquare.toString()); if (rc.canAttackSquare(targetSquare)) rc.attackSquare(targetSquare); smartLoc = smartLoc.add(herdDir); } }
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); }