/** Approximate action delay between two locations. */ public static int heuristic(MapLocation loc1, MapLocation loc2) { int dx = Math.abs(loc1.x - loc2.x); int dy = Math.abs(loc1.y - loc2.y); int min, diff; if (dx > dy) { min = dy; diff = dx - dy; } else { min = dx; diff = dy - dx; } return (min * NORMAL_DIAGONAL + diff * NORMAL_ORTHOGONAL); }
public int evalDirection( MapLocation currentLocation, Direction dir, MapLocation goal, Direction dirToGoal, int currentMovesToGoal) { boolean hasDefusion = rc.hasUpgrade(Upgrade.DEFUSION); MapLocation square = currentLocation.add(dir); int directionPenalty; int dirDiff = Math.abs(dir.ordinal() - dirToGoal.ordinal()); if (dirDiff <= 2) { directionPenalty = this.movesAway(square, goal) - currentMovesToGoal; } else { directionPenalty = hasDefusion ? 5 : 12; } int minePenalty; if (hasDefusion) { minePenalty = this.mineHazard(square) ? 5 : 0; } else { minePenalty = this.mineHazard(square) ? 12 : 0; } int visitPenalty = 2 * this.mapIntDistribution[square.x][square.y] * (hasDefusion ? 5 : 12); return directionPenalty + minePenalty + visitPenalty; }
private Direction chooseRetreatDirection() throws GameActionException { int[] numEnemiesAttackingDir = countNumEnemiesAttackingMoveDirs(); int repelX = 0; int repelY = 0; for (int i = visibleEnemies.length; i-- > 0; ) { Direction repelDir = visibleEnemies[i].location.directionTo(here); repelX += repelDir.dx; repelY += repelDir.dy; } int absRepelX = Math.abs(repelX); int absRepelY = Math.abs(repelY); Direction retreatDir; if (absRepelX >= 1.5 * absRepelY) { retreatDir = repelX > 0 ? Direction.EAST : Direction.WEST; } else if (absRepelY >= 1.5 * absRepelX) { retreatDir = repelY > 0 ? Direction.SOUTH : Direction.NORTH; } else if (repelX > 0) { retreatDir = repelY > 0 ? Direction.SOUTH_EAST : Direction.NORTH_EAST; } else { retreatDir = repelY > 0 ? Direction.SOUTH_WEST : Direction.NORTH_WEST; } // Test to see if retreatDir, or either of the adjacent directions, actually work // To work, three conditions have to be satisfied: // (a) we have to be able to move in that direction // (b) moving in that direction has to take us out of range of enemy attacks // (c) moving in that direction can't take us within range of the enemy HQ int[] tryDirs = new int[] {0, 1, -1, 2, -2, 3, -3, 4}; for (int i = 0; i < tryDirs.length; i++) { Direction tryDir = Direction.values()[(retreatDir.ordinal() + tryDirs[i] + 8) % 8]; if (!rc.canMove(tryDir)) continue; MapLocation tryLoc = here.add(tryDir); if (numEnemiesAttackingDir[tryDir.ordinal()] > 0) continue; if (Util.inHQAttackRange(tryLoc, theirHQ)) continue; return tryDir; } return null; }
public NoiseTowerBehavior() { for (int i = 7; i >= 0; i--) { int lastdir = (i + 4) % 8; int at = 1; paths[i][0] = currentLocation; int lastcow = 0; for (int j = 1; j < 30; j++) { if (i < 7 && RC.isActive()) { try { makeSomeNoise(); } catch (GameActionException e1) { e1.printStackTrace(); } } int k = lastdir + 2; k %= 8; int bestscore = -1; MapLocation bestplace = currentLocation; while (k != (lastdir + 6) % 8) { int score = Math.abs(i - k); if (score < 4) score = 8 - score; score *= score * score; MapLocation here = paths[i][j - 1].add(directions[k]); double cows; try { cows = Utils.COW_GROWTH[here.x][here.y]; if (cows > 0) lastcow = j; score = (here.add(directions[k])).distanceSquaredTo(currentLocation) > 300 || RC.senseTerrainTile(here) == TerrainTile.VOID ? -10 : cows == 0.0 ? 30 : score + (int) (cows) * 0 + 30; } catch (Exception e) { score = -2; } if (score > bestscore) { bestscore = score; bestplace = here; } k++; if (k == 8) k = 0; } if (!bestplace.equals(currentLocation)) { paths[i][j] = bestplace; } else { break; } } pathat[i] = lastcow; while (paths[i][pathat[i]] == null && pathat[i] > 0) pathat[i]--; if (lastcow < 29) lastcow++; } skip[0] = false; double[] d = new double[8]; int[] dist = new int[8]; MapLocation[] toconsider = new MapLocation[8]; for (int i = 7; i >= 0; i--) { if (pathat[i] == 0) { d[i] = 0; dist[i] = 0; } else { toconsider[i] = paths[i][pathat[i] - 1]; d[i] = Math.atan2(toconsider[i].y - curY, toconsider[i].x - curX); dist[i] = currentLocation.distanceSquaredTo(toconsider[i]); } } for (int i = 7; i >= 0; i--) { if (dist[i] == 0) skip[i] = true; else { for (int j = i - 1; j >= 0; j--) { if (i == j || dist[j] == 0) continue; if (Math.abs(d[i] - d[j]) < 0.4 && pathbetween(toconsider[i], toconsider[j])) { if (dist[i] < dist[j]) skip[i] = true; else skip[j] = true; } } } } }
public int movesAway(MapLocation start, MapLocation target) { return Math.max(Math.abs(target.x - start.x), Math.abs(target.y - start.y)); }