private static void doMinerMove() { // If there is an available adjacent tile with twice as much ore we are better off moving Direction startDir = directions[rand.nextInt(directions.length)]; Direction d = startDir; Direction best = Direction.NONE; double mostOre = rc.senseOre(myLoc) * 2; // Only move if there is twice as much ore boolean done = false; while (!done) { if (rc.canMove(d)) { MapLocation adj = rc.getLocation().add(d); double ore = rc.senseOre(adj); if ((ore > mostOre || (ore == mostOre && ore > 0 && adj.distanceSquaredTo(myHQ) > myLoc.distanceSquaredTo(myHQ))) && !threats.isThreatened(adj)) { mostOre = rc.senseOre(adj); best = d; } } d = d.rotateRight(); done = (d == startDir); } if (best != Direction.NONE) { rc.setIndicatorString(2, "Mining - better ore " + d); try { rc.move(best); } catch (GameActionException e) { System.out.println("Miner move exception"); // e.printStackTrace(); } } }
private static void flashTowards(MapLocation m, boolean ignoreThreat) { // We want to pick a safe tile that is within flash range (10) and nearest to the destination // If we are allowed to ignore threat store the nearest threatened tile in case there are no // safe ones // We don't bother with moves to adjacent tiles! MapLocation[] inRange = MapLocation.getAllMapLocationsWithinRadiusSq(myLoc, GameConstants.FLASH_RANGE_SQUARED); MapLocation bestSafe = myLoc; MapLocation best = myLoc; // The closest regardless of threat try { for (MapLocation target : inRange) { if (!target.equals(myLoc) && rc.isPathable(myType, target) && !rc.isLocationOccupied(target) && target.distanceSquaredTo(myLoc) > 1) { if (target.distanceSquaredTo(m) < bestSafe.distanceSquaredTo(m) && !threats.isThreatened(target)) bestSafe = target; if (target.distanceSquaredTo(m) < best.distanceSquaredTo(m)) best = target; } } if (!bestSafe.equals(myLoc)) rc.castFlash(bestSafe); else if (ignoreThreat && !best.equals(myLoc)) rc.castFlash(best); } catch (GameActionException e) { System.out.println("Flash exception"); // e.printStackTrace(); } }
/* * 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(); } } }
/* * Beavers and miners without ore do this */ private static void doSearchMove() { // We keep moving in the direction we were going // When blocked we turn left or right depending on our unique ID rc.setIndicatorString(2, "Mining: No ore - searching"); if (lastMove == null || rand.nextInt(10) == 1) lastMove = directions[rand.nextInt(directions.length)]; Direction startDir = lastMove; while (!rc.canMove(lastMove) || threats.isThreatened(myLoc.add(lastMove))) { if (rc.getID() % 2 == 0) lastMove = lastMove.rotateLeft(); else lastMove = lastMove.rotateRight(); if (lastMove == startDir) // We are trapped return; } try { rc.move(lastMove); } catch (GameActionException e) { System.out.println("Move exception"); // e.printStackTrace(); } }
// This method will attempt to build in the given direction (or as close to it as possible) static boolean tryBuild(Direction d, RobotType type) { int offsetIndex = 0; int[] offsets = {0, 1, -1, 2, -2, 3, -3, 4}; int dirint = directionToInt(d); while (offsetIndex < 8) { int i = (dirint + offsets[offsetIndex] + 8) % 8; Direction build = directions[i]; MapLocation m = myLoc.add(build); if (rc.canBuild(build, type) && !wouldBlock(build) && !threats.isThreatened(m)) { try { rc.build(directions[i], type); strategy.addUnit(type); } catch (GameActionException e) { System.out.println("Build exception"); // e.printStackTrace(); } return true; } offsetIndex++; } return false; }
private static void tryMove(Direction preferred, boolean ignoreThreat) { Direction[] options = null; int turn = Clock.getRoundNum(); if ((turn / 50) % 3 == 0) { // 1/3 of the time we prefer to move left Direction[] allMovesLeft = { preferred, preferred.rotateLeft(), preferred.rotateRight(), preferred.rotateLeft().rotateLeft(), preferred.rotateRight().rotateRight(), Direction.NONE, preferred.opposite().rotateRight(), preferred.opposite().rotateLeft(), preferred.opposite() }; options = allMovesLeft; } else if ((turn / 50) % 3 == 1) { // 1/3 of the time we prefer to move right Direction[] allMovesRight = { preferred, preferred.rotateRight(), preferred.rotateLeft(), preferred.rotateRight().rotateRight(), preferred.rotateLeft().rotateLeft(), Direction.NONE, preferred.opposite().rotateLeft(), preferred.opposite().rotateRight(), preferred.opposite() }; options = allMovesRight; } else { // 1/3 of the time we prefer to stay still if we can't move forward Direction[] allMovesForward = { preferred, preferred.rotateLeft(), preferred.rotateRight(), Direction.NONE, preferred.rotateLeft().rotateLeft(), preferred.rotateRight().rotateRight(), preferred.opposite().rotateRight(), preferred.opposite().rotateLeft(), preferred.opposite() }; options = allMovesForward; } // Scan through possible moves // If we find a valid move but it is a threatened tile we store it and continue // If we don't find a better move we use the stored one Direction retreat = null; for (Direction d : options) { boolean valid = (d == Direction.NONE || rc.canMove(d)); MapLocation dest = myLoc.add(d); if (valid) { // This is a valid move - check to see if it is safe if (ignoreThreat || !threats.isThreatened(dest)) { // Do this move if (d != Direction.NONE) try { // System.out.println("tryMove: preferred " + preferred + " got " + d); rc.move(d); } catch (GameActionException e) { System.out.println("Movement exception"); // e.printStackTrace(); } return; } else if (retreat == null) retreat = d; } } if (retreat != null && retreat != Direction.NONE) { try { rc.move(retreat); } catch (GameActionException e) { System.out.println("Movement exception"); // e.printStackTrace(); } } }
private static boolean inCombat(int multiplier) { return rc.senseNearbyRobots(senseRange * multiplier, enemyTeam).length > 0 || threats.isThreatened(myLoc); }
// If our tile is threatened we should retreat unless the enemy is quicker than us // If the enemy can advance and fire before we can move away we might as well stand and fight private static boolean shouldRetreat() { if (myType == RobotType.LAUNCHER && rc.getMissileCount() == 0) return true; return threats.isThreatened(myLoc) || threats.inMissileRange(); }