private void computeOutPath() throws GameActionException { Pair<Direction, Integer> pathingInfo = messagingSystem.readPathingInfo(dest); if (pathingInfo.first == null) { outPath = null; return; } RC.setIndicatorString(1, "Computing outPath"); outPath = new LocSet(); distances = new int[MAP_SIZE]; MapLocation loc = dest; int d = pathingInfo.second; while (!loc.equals(DIJKSTRA_CENTER)) { pathingInfo = messagingSystem.readPathingInfo(loc); distances[outPath.size] = d - pathingInfo.second; outPath.insert(loc); loc = loc.subtract(pathingInfo.first); } int[] diffs = new int[outPath.size - 1]; for (int i = diffs.length; --i > 0; ) { diffs[i] = distances[i + 1] - distances[i]; } // heuristic to prefer further away points on the path (which may be closer to us) for (int i = 1; i < outPath.size; i++) { distances[i] = distances[i - 1] + Math.max(1, diffs[i - 1] * 100 / (100 + 10 * i)); } }
private boolean moveToPath() throws GameActionException { if (dstar == null) { dstar = new DStar(outPath, distances, currentLocation); } if (!dstar.arrived(currentLocation)) { dstar.compute(7000); } if (!RC.isActive()) return true; Direction dir = Direction.NORTH, best = null; int min = Integer.MAX_VALUE; for (int i = 0; i < 8; i++) { int d = RC.canMove(dir) ? dstar.getDistance(currentLocation.add(dir)) : Integer.MAX_VALUE; if (d < min) { min = d; best = dir; } dir = dir.rotateRight(); } if (best != null && move(best)) { RC.setIndicatorString(1, "Moving to outPath"); return true; } else { return false; } }
private MapLocation findRichSquare() { double maxCows = currentCowsHere + 50 * COW_GROWTH[curX][curY] + 300; // favor staying here double curCows; MapLocation best = currentLocation; for (MapLocation current : MapLocation.getAllMapLocationsWithinRadiusSq( currentLocation, RobotType.SOLDIER.sensorRadiusSquared)) { try { if (RC.senseTerrainTile(current) == TerrainTile.OFF_MAP) continue; curCows = RC.senseCowsAtLocation(current) + 50 * COW_GROWTH[current.x][current.y]; if (curCows > maxCows && RC.senseObjectAtLocation(current) == null) { best = current; maxCows = curCows; } } catch (GameActionException e) { e.printStackTrace(); } } RC.setIndicatorString(1, "max nearby cows: " + maxCows + " at " + best); if (maxCows > 1000) { return best; } return null; }
public void move(MovementType movementType) throws GameActionException { if (currentLocation.equals(dest)) return; this.movementType = movementType; // try computing the outpath if it isn't set if (outPath == null) { computeOutPath(); } if (outPath != null) { if (!moveToPath()) { simpleMove(dest); RC.setIndicatorString(1, "dstar failed, simpleMove to dest"); } } else { simpleMove(dest); RC.setIndicatorString(1, "no outPath, simpleMove to dest"); } }
@Override public void run() throws GameActionException { if (luge()) { // luge = micro // set mode to ATTACK or something return; // send message? } else if (mode != Mode.ENGAGE && mode != Mode.ACQUIRE_TARGET && mode != Mode.BIRTH_DECIDE_MODE && mode != Mode.FIND_PASTR_LOC && mode != Mode.BUILD_PASTR) { if (ENEMY_MILK - ALLY_MILK > 50000 || ENEMY_PASTR_COUNT > ALLY_PASTR_COUNT) { changeMode(Mode.ACQUIRE_TARGET); } else { // try to build pastures if late in game // probably deprecated (doesn't happen) if (currentRound > 1800 && ENEMY_PASTR_COUNT > ALLY_PASTR_COUNT && !panicPastrBuilding) { if (currentCowsHere < 150) { panicPastrBuilding = true; dest = ALLY_HQ.subtract(ALLY_HQ.directionTo(ENEMY_HQ)); mover.setTarget(dest); sneakToBuildingLoc = 1; changeMode(Mode.FIND_PASTR_LOC); } else if (currentCowsHere < 400) { panicPastrBuilding = true; mover.setTarget(ALLY_HQ); changeMode(Mode.RETURN_HOME); } } else if (!initialSweep) { // stand on rich squares MapLocation loc = findRichSquare(); if (loc != null) { mover.setTarget(loc); changeMode(Mode.STAND_RICH_LOC); } } } } switch (mode) { case BIRTH_DECIDE_MODE: int robotNum = RC.senseRobotCount(); if (ENEMY_PASTR_COUNT > ALLY_PASTR_COUNT + 1 || (robotNum + currentRound / 100 > 22 && ENEMY_PASTR_COUNT > ALLY_PASTR_COUNT)) { roleIndex = ALLY_PASTR_COUNT % 4; role = Role.PASTR; changeMode(Mode.FIND_PASTR_LOC); dest = new MapLocation( (ALLY_HQ.x + roleLocList[roleIndex].x) / 2, (ALLY_HQ.y + roleLocList[roleIndex].y) / 2); } else { roleIndex = robotNum % 4; role = roleList[roleIndex]; changeMode(Mode.SWEEP_OUT); dest = roleLocList[roleIndex]; initialSweep = true; } mover.setTarget(dest); mover.move(); break; case GOING_TO_MIDDLE: if (mover.arrived()) { decideNextMode(); } else { mover.movePushHome(); } break; case SWEEP_OUT: if (mover.arrived()) { dest = new MapLocation( (2 * ALLY_HQ.x + roleLocList[roleIndex].x) / 3, (2 * ALLY_HQ.y + roleLocList[roleIndex].y) / 3); mover.setTarget(dest); changeMode(Mode.RETURN_HOME); } else { mover.movePushHome(); } break; case RETURN_HOME: if (mover.arrived()) { dest = roleLocList[roleIndex]; mover.setTarget(dest); changeMode(Mode.SWEEP_OUT); initialSweep = false; } else { mover.movePushHome(); } break; case STAND_RICH_LOC: if (!mover.arrived()) { mover.sneak(); } else { RC.setIndicatorString(1, "cows here: " + currentCowsHere); if (currentCowsHere < 500) { mover.setTarget(roleLocList[roleIndex]); changeMode(Mode.SWEEP_OUT); } } break; case FIND_PASTR_LOC: if (mover.arrived()) { changeMode(Mode.BUILD_PASTR); } else { mover.execute(sneakToBuildingLoc); } break; case BUILD_PASTR: if (!RC.isConstructing() && RC.isActive()) { RC.construct(RobotType.PASTR); } if (RC.getConstructingRounds() == 0) { buildingFinished = true; } break; case ACQUIRE_TARGET: int mindistance = 10000000; MapLocation pastrTarget = null; for (MapLocation pastrLoc : ENEMY_PASTR_LOCS) { int d = currentLocation.distanceSquaredTo(pastrLoc); if (d < mindistance) { mindistance = d; pastrTarget = pastrLoc; } } if (pastrTarget == null) { mover.setTarget(ALLY_HQ); changeMode(Mode.RETURN_HOME); } else { mover.setTarget(pastrTarget); changeMode(Mode.ENGAGE); mover.move(); } break; case ENGAGE: if (mover.arrived()) { changeMode(Mode.RETURN_HOME); } else { mover.move(); } break; default: break; } }
private void changeMode(Mode m) { RC.setIndicatorString(0, currentRound + ": " + m.toString() + " " + role.toString()); mode = m; }