public static MapLocation spotOfTrollTower(RobotController rc, MapLocation pastr) { MapLocation target = pastr; int width = rc.getMapWidth(); int height = rc.getMapHeight(); int dist = 350; if (pastr.x < width / 2) { while (target.distanceSquaredTo(pastr) < dist && target.x > 0) { target = target.add(Direction.WEST); } } else { while (target.distanceSquaredTo(pastr) < dist && target.x < rc.getMapWidth() - 1) { target = target.add(Direction.EAST); } } if (pastr.y < height / 2) { while (target.distanceSquaredTo(pastr) < dist && target.y < height - 1) { target = target.add(Direction.SOUTH); } } else { while (target.distanceSquaredTo(pastr) < dist && target.y > 0) { target = target.add(Direction.NORTH); } } while (rc.senseTerrainTile(target) == TerrainTile.VOID && target.x < width / 2) { target = target.add(Direction.EAST); } while (rc.senseTerrainTile(target) == TerrainTile.VOID && target.x > width / 2) { target = target.add(Direction.WEST); } return target; }
public static MapLocation spotOfPastr(RobotController rc) { MapLocation target; int[] lookPlaces = {1, 1, 0, 3, 6, 7, 4, 5, 2, 3, 0, 2, 2, 3, 1, 4, 5, 3, 2, 5, 6}; int counter = 0; Direction dir; int corner = findBestCorner(rc); rand = new Random(); switch (corner) { case 1: target = new MapLocation(2, 2); break; case 2: target = new MapLocation(rc.getMapWidth() - 3, 2); break; case 3: target = new MapLocation(2, rc.getMapHeight() - 3); break; default: target = new MapLocation(rc.getMapWidth() - 3, rc.getMapHeight() - 3); break; } while (rc.senseTerrainTile(target).equals(TerrainTile.VOID)) { dir = directions[rand.nextInt(8)]; target = target.add(dir); counter++; } return target; }
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 MapLocation spotOfSensorTower(RobotController rc) { rand = new Random(); MapLocation target = null; int corner = Utilities.findBestCorner(rc); switch (corner) { case 1: target = new MapLocation(5, 5); break; case 2: target = new MapLocation(rc.getMapWidth() - 6, 5); break; case 3: target = new MapLocation(5, rc.getMapHeight() - 6); break; default: target = new MapLocation(rc.getMapWidth() - 6, rc.getMapHeight() - 6); break; } Direction dir = directions[rand.nextInt(8)]; // make sure we don't try to build on a void space while (rc.senseTerrainTile(target).equals(TerrainTile.VOID)) { target = target.add(dir); dir = directions[rand.nextInt(8)]; } return target; }
/** * Checks if square is void, out of map, out of tower range * * @param loc * @return */ public boolean locationValid(MapLocation loc) { return !(rc.senseTerrainTile(loc) == TerrainTile.VOID || loc.x > xmax || loc.y > ymax || loc.x < 0 || loc.y < 0 || loc.distanceSquaredTo(tLoc) > attackRadius); }
// 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 int countObstacles(int x, int y, RobotController rc) { // returns a 0 or a 1 int terrainOrdinal = rc.senseTerrainTile(new MapLocation(x, y)).ordinal(); // 0 NORMAL, 1 ROAD, 2 VOID, 3 OFF_MAP switch (terrainOrdinal) { case 0: return NORMAL_COST; case 1: return ROAD_COST; case 2: return VOID_COST; case 3: return OFF_MAP_COST; default: return 0; } }
/* * Moves towards the nearest enemy * Returns true if we moved or are in the right place */ private static boolean doCloseWithEnemyMove(boolean ignoreThreat) { // Move to within attack range of the nearest enemy - ignore towers and HQ until later in the // game // We can move in closer if we are still out of range of the enemy RobotInfo nearest = null; RobotInfo preferred = null; RobotInfo[] enemies = rc.senseNearbyRobots(senseRange * 16, enemyTeam); boolean canFly = (myType == RobotType.DRONE); int now = Clock.getRoundNum(); for (RobotInfo e : enemies) { // We want to find and circle units, not towers or HQ (until later in the game) if (now < maxRounds / 2 && (e.type == RobotType.HQ || e.type == RobotType.TOWER)) continue; // Drones on VOID tiles cannot be reached by ground troops - ignore them if (!canFly && rc.senseTerrainTile(e.location) != TerrainTile.NORMAL) continue; // Commanders are good at picking off miners, beavers and non combat buildings - have a // preference for them if (myType == RobotType.COMMANDER && commanderLikes(e.type) && (preferred == null || e.location.distanceSquaredTo(myLoc) < preferred.location.distanceSquaredTo(myLoc))) preferred = e; if (nearest == null || e.location.distanceSquaredTo(myLoc) < nearest.location.distanceSquaredTo(myLoc)) nearest = e; } if (preferred != null) nearest = preferred; int attackRange = myType.attackRadiusSquared; if (myType == RobotType.LAUNCHER) attackRange = (1 + GameConstants.MISSILE_LIFESPAN) * (1 + GameConstants.MISSILE_LIFESPAN); if (nearest != null) { if (ignoreThreat || myLoc.distanceSquaredTo(nearest.location) > attackRange) { rc.setIndicatorString(2, "Closing with " + nearest.type + " at " + nearest.location); if (rc.isCoreReady()) tryMove(rc.getLocation().directionTo(nearest.location), ignoreThreat); } else { rc.setIndicatorString( 2, "Holding at range with " + nearest.type + " at " + nearest.location); } return true; } return false; }
// finds best corner to collect milk where the return is an int as follows: // 1 2 // 3 4 public static int findBestCorner(RobotController rc) { double[][] pasture = rc.senseCowGrowth(); double[] voids = new double[4]; double[] cows = new double[4]; double[] distances = new double[4]; double max = 0; int corner = 0; double total = 0; MapLocation target = null; MapLocation current = rc.senseHQLocation(); for (int k = 1; k <= 4; k++) { switch (k) { case 1: target = new MapLocation(5, 5); break; case 2: target = new MapLocation(rc.getMapWidth() - 6, 5); break; case 3: target = new MapLocation(5, rc.getMapHeight() - 6); break; default: target = new MapLocation(rc.getMapWidth() - 6, rc.getMapHeight() - 6); break; } while (target.x != current.x || target.y != current.y) { if (rc.senseTerrainTile(current) == TerrainTile.VOID) { total++; } current = current.add(current.directionTo(target)); } voids[k - 1] = total; distances[k - 1] = rc.senseHQLocation().distanceSquaredTo(target); total = 0; current = rc.senseHQLocation(); } // top left corner for (int k = 0; k < 10; k++) { for (int a = 0; a < 10; a++) { total += pasture[k][a]; } } cows[0] = total; total = 0; // top right corner for (int k = rc.getMapWidth() - 11; k < rc.getMapWidth(); k++) { for (int a = 0; a < 10; a++) { total += pasture[k][a]; } } cows[1] = total; total = 0; // bottom left corner for (int k = 0; k < 10; k++) { for (int a = rc.getMapHeight() - 11; a < rc.getMapHeight(); a++) { total += pasture[k][a]; } } cows[2] = total; total = 0; // bottom right corner for (int k = rc.getMapWidth() - 11; k < rc.getMapWidth(); k++) { for (int a = rc.getMapHeight() - 11; a < rc.getMapHeight(); a++) { total += pasture[k][a]; } } cows[3] = total; for (int k = 0; k < 4; k++) { total = cows[k] * 1 - voids[k] * 50 - distances[k] * .001; if (total > max) { max = total; corner = k + 1; } } return corner; }
// this method will advance one square towards a target and try to avoid enemies as much as // possible public static void avoidEnemiesMove(RobotController rc, MapLocation target) { try { // first we will find all enemy bots near us GameObject[] nearByBots = rc.senseNearbyGameObjects(Robot.class, 15, rc.getTeam().opponent()); Direction direction = rc.getLocation().directionTo(target); // if we don't see anything then lets head towards target if (nearByBots.length == 0) { // rc.setIndicatorString(2, "No enemies detected"); // rc.setIndicatorString(1, "x: "+target.x + " y: " + target.y); direction = rc.getLocation().directionTo(target); if (rc.canMove(direction)) // && // !rc.senseTerrainTile(rc.getLocation().add(direction).add(direction)).equals(TerrainTile.VOID)) { if (rc.isActive()) { rc.move(direction); } } else { MapLocation target2 = rc.getLocation().add(direction); if (rc.senseTerrainTile(target2).equals(TerrainTile.VOID)) { int j = 0; while (rc.senseTerrainTile(target2).equals(TerrainTile.VOID)) { rc.setIndicatorString(0, "" + j); j++; target2 = target2.add(direction); } Utilities.MoveMapLocation(rc, target2, false); } /* int distanceRight = 0; int distanceLeft = 0; direction = direction.rotateRight(); while (!rc.canMove(direction) && rc.senseTerrainTile(rc.getLocation().add(direction)).equals(TerrainTile.VOID)) { direction = direction.rotateRight(); } if (rc.isActive()) { if (rc.canMove(direction)) { rc.move(direction); } } */ } } // otherwise we need to avoid them else { rc.setIndicatorString(2, "Avoiding enemies"); rc.setIndicatorString(1, "Numb of Enemies: " + nearByBots.length); // now we will calculate the distance form all 5 spots towards are target and the distance // from that spot to all enemies we can see // we will pick the one with the greatest distance int[] distancesToLocations = new int[5]; for (int k = 0; k < distancesToLocations.length; k++) { distancesToLocations[k] = 0; } MapLocation spot; Direction newDir; // first we look 90 to our right newDir = direction.rotateRight().rotateRight(); for (int j = 0; j < 5; j++) { if (rc.canMove(newDir)) { spot = rc.getLocation().add(newDir); for (int i = 0; i < nearByBots.length; i++) { // System.out.println("entering for loop"); distancesToLocations[j] += spot.distanceSquaredTo(rc.senseLocationOf(nearByBots[i])); } } else { distancesToLocations[j] = -123; } // every time through the loop we look one further to the left newDir.rotateLeft(); } int indexOfLargest = 0; int largest = distancesToLocations[0]; for (int j = 1; j < distancesToLocations.length; j++) { if (largest < distancesToLocations[j]) { indexOfLargest = j; largest = distancesToLocations[j]; } } // now we orientate newDir to the right spot newDir = direction.rotateRight().rotateRight(); for (int i = 0; i <= indexOfLargest; i++) { newDir = newDir.rotateLeft(); } while (!rc.isActive()) { rc.yield(); } // now we can finally move if (rc.isActive()) { if (rc.canMove(newDir)) { rc.move(newDir); } } } } catch (Exception e) { e.printStackTrace(); } }
public static void MoveMapLocation(RobotController rc, MapLocation target, boolean sneak) { MapLocation[] pastLocations = new MapLocation[10]; int side = 45; Direction dir; Direction newDir; rand = new Random(); // we initialize pastLocations to hold our current location 5 times for (int i = 0; i < pastLocations.length; i++) { pastLocations[i] = rc.getLocation(); } // this method will run until we get to our target location while (!rc.getLocation().equals(target)) { // we put the try block inside of the while loop so an exception won't terminate the method try { dir = rc.getLocation().directionTo(target); newDir = Direction.NONE; // simple shoot at an enemy if we see one will need to be improved later Robot[] nearbyEnemies = rc.senseNearbyGameObjects(Robot.class, 10, rc.getTeam().opponent()); if (nearbyEnemies.length > 0 && rc.senseRobotInfo((Robot) nearbyEnemies[0]).health < 201) { fire(rc); } // if we can move towards target and we haven't been on the square recently then lets move else if (rc.canMove(dir) && !MapLocationInArray(rc, rc.getLocation().add(dir), pastLocations)) { newDir = dir; // if we found a direction to move then we go to it if (newDir != Direction.NONE) { // now we decide if we are going to sneak or run if (sneak) { // another check to make sure we don't throw any exceptions if (rc.isActive() && rc.canMove(newDir)) { // System.out.println(newDir); rc.sneak(newDir); } } else { // another check to make sure we don't throw any exceptions if (rc.isActive() && rc.canMove(newDir)) { rc.move(newDir); } } } side = 45; } else { // if their is a robot blocking our way then we just move in a random direction if (rc.senseObjectAtLocation(rc.getLocation().add(dir)) != null) { // newDir = directions[rand.nextInt(8)]; MoveDirection(rc, dir, sneak); } else { // rc.setIndicatorString(2, "Looking elswhere"); Direction dir2 = dir; MapLocation right; MapLocation left; dir2 = (dir.rotateRight()); while (!rc.canMove(dir2)) { dir2 = dir2.rotateRight(); } right = rc.getLocation().add(dir2); dir2 = dir.rotateLeft(); while (!rc.canMove(dir2)) { dir2 = dir2.rotateLeft(); } left = rc.getLocation().add(dir2); // left seems better so lets go that way if (left.distanceSquaredTo(target) < right.distanceSquaredTo(target)) { side = 1; } // right seems better so lets try that way else { side = 0; } // we will go hugging one side of obstacle until we get back on our original line while (!dir2.equals(dir) && !rc.getLocation().equals(target)) // && rc.canMove(dir2)) { try { if (rc.isActive()) { // rc.setIndicatorString(1, "Trying to Avoid"); // rc.setIndicatorString(2, ""+side); dir2 = rc.getLocation().directionTo(target); if (rc.canMove(dir2) && !MapLocationInArray(rc, rc.getLocation().add(dir2), pastLocations)) // && // !rc.senseTerrainTile(rc.getLocation().add(dir2).add(dir2)).equals(TerrainTile.VOID)) { // rc.setIndicatorString(0, "Going straight"); } else { for (int i = 0; i < 4; i++) { if (side == 1) { dir2 = dir2.rotateLeft(); } else { dir2 = dir2.rotateRight(); } if (rc.senseTerrainTile(rc.getLocation().add(dir2)) .equals(TerrainTile.OFF_MAP)) { dir2 = Direction.NONE; i = 48; } else if ((rc.canMove(dir2) || (rc.senseObjectAtLocation(rc.getLocation().add(dir2)) != null))) // && !MapLocationInArray(rc, rc.getLocation().add(dir2), // pastLocations))// && // !rc.senseTerrainTile(rc.getLocation().add(dir2).add(dir2)).equals(TerrainTile.VOID)) { i = 48; } else if (i == 3) { dir2 = Direction.NONE; // rc.setIndicatorString(1, "We failed to find a spot"); } } } // if we can move if (dir2 != Direction.NONE) { if (rc.isActive()) { if (rc.canMove(dir2)) { if (sneak) { rc.sneak(dir2); } else { rc.move(dir2); } } else { MoveDirection(rc, dir2, sneak); } } } else { if (side == 1) { side = 0; } else { side = 1; } } } // rc.setIndicatorString(0, "Dir: "+ dir +" Dir2: " + dir2); } catch (Exception e) { // tell the console we through an exception in utility object for debug purposes // System.out.println("Utility Exception"); // System.out.println(e.toString()); e.printStackTrace(); rc.yield(); } if (!rc.getLocation().equals(pastLocations[(pastLocations.length - 1)])) { for (int j = 0; j < (pastLocations.length - 1); j++) { pastLocations[j] = pastLocations[j + 1]; // System.out.println(pastLocations[j]); } // stick current local into array pastLocations[(pastLocations.length - 1)] = rc.getLocation(); } rc.yield(); } // rc.setIndicatorString(1, "Not trying to Avoid"); } } // now we shift everything up one in pastLocations if (rc.getLocation() != pastLocations[(pastLocations.length - 1)]) { for (int j = 0; j < (pastLocations.length - 1); j++) { pastLocations[j] = pastLocations[j + 1]; // System.out.println(pastLocations[j]); } // stick current local into array pastLocations[(pastLocations.length - 1)] = rc.getLocation(); } rc.yield(); } catch (Exception e) { // tell the console we through an exception in utility object for debug purposes System.out.println("Utility Exception"); e.printStackTrace(); // System.out.println(e.toString()); rc.yield(); } } }
public static void computeAndPublish(MapLocation here, MapLocation pastr, RobotController rc) throws GameActionException { // Useful data int attackRange = (int) (Math.sqrt(RobotType.NOISETOWER.attackRadiusMaxSquared) - 3); // -3 becauase we actually have to shoot past the square int attackRangeSq = attackRange * attackRange; int mapWidth = rc.getMapWidth(); int mapHeight = rc.getMapHeight(); Direction[] dirs = new Direction[] { Direction.NORTH_WEST, Direction.SOUTH_WEST, Direction.SOUTH_EAST, Direction.NORTH_EAST, Direction.NORTH, Direction.WEST, Direction.SOUTH, Direction.EAST }; int[] dirsX = new int[] {1, 1, -1, -1, 0, 1, 0, -1}; int[] dirsY = new int[] {1, -1, -1, 1, 1, 0, -1, 0}; // Set up the queue MapLocation[] locQueue = new MapLocation [(2 * RobotType.NOISETOWER.attackRadiusMaxSquared + 1) * (2 * RobotType.NOISETOWER.attackRadiusMaxSquared + 1)]; int locQueueHead = 0; int locQueueTail = 0; boolean[][] wasQueued = new boolean[GameConstants.MAP_MAX_WIDTH][GameConstants.MAP_MAX_HEIGHT]; // Push pastr onto queue locQueue[locQueueTail] = pastr; locQueueTail++; wasQueued[pastr.x][pastr.y] = true; while (locQueueHead != locQueueTail) { // 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 (here.distanceSquaredTo(newLoc) <= attackRangeSq) { if (rc.senseTerrainTile(newLoc) != TerrainTile.VOID) { writeHerdDir(newLoc, dirs[i], rc); // push newLoc onto queue locQueue[locQueueTail] = newLoc; locQueueTail++; wasQueued[x][y] = true; } } } } } }
// Checks to see if building here would block movement static boolean wouldBlock(Direction d) { MapLocation target = myLoc.add(d); if ((target.x + target.y) % 2 != (myHQ.x + myHQ.y) % 2) // A quick check to ensure we are lined up with the HQ - this will create a // chequerboard pattern return true; RobotInfo[] units = rc.senseNearbyRobots(2, myTeam); boolean hasTop = false; boolean hasBottom = false; boolean hasLeft = false; boolean hasRight = false; boolean[] blocked = new boolean[8]; // The 8 locations around us int clearTiles = 8; MapLocation test = rc.getLocation().add(d); test = test.add(Direction.NORTH_WEST); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasTop = true; hasLeft = true; } else { blocked[0] = true; clearTiles--; } test = test.add(Direction.EAST); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasTop = true; } else { blocked[1] = true; clearTiles--; } test = test.add(Direction.EAST); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasTop = true; hasRight = true; } else { blocked[2] = true; clearTiles--; } test = test.add(Direction.SOUTH); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasRight = true; } else { blocked[3] = true; clearTiles--; } test = test.add(Direction.SOUTH); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasRight = true; hasBottom = true; } else { blocked[4] = true; clearTiles--; } test = test.add(Direction.WEST); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasBottom = true; } else { blocked[5] = true; clearTiles--; } test = test.add(Direction.WEST); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasBottom = true; hasLeft = true; } else { blocked[6] = true; clearTiles--; } test = test.add(Direction.NORTH); if (rc.senseTerrainTile(test).isTraversable() && !buildingAt(test, units)) { hasLeft = true; } else { blocked[7] = true; clearTiles--; } // Check for a line down the middle if (blocked[1] && blocked[5] && hasLeft && hasRight) return true; // Check for line across if (blocked[3] && blocked[7] && hasTop && hasBottom) return true; // Check for blocked corners if (clearTiles > 2) { if (!blocked[0] && blocked[1] && blocked[7]) return true; if (!blocked[2] && blocked[1] && blocked[3]) return true; if (!blocked[4] && blocked[3] && blocked[5]) return true; if (!blocked[6] && blocked[5] && blocked[7]) return true; } // System.out.println("wouldBlock = false, blocked="+blocked+" hasLeft = "+hasLeft+" // hasRight="+hasRight+" hasTop="+hasTop+" hasBootom="+hasBottom); return false; }