/ benchmark / pep / Harvester.java
Harvester.java
  1  package pep;
  2  
  3  import hlt.*;
  4  
  5  import java.util.ArrayList;
  6  import java.util.Random;
  7  
  8  public class Harvester extends Behavior {
  9      private static Random rng = new Random(System.nanoTime());
 10      private InnerHarvester innerHarvester;
 11  
 12      Harvester(){
 13          //boolean isBH = Math.random() <= Parameters.getPercentBH();
 14          //innerHarvester = isBH ? new BestHarvester() : new ThresholdHarvester();
 15          innerHarvester = new ThresholdHarvester();
 16      }
 17  
 18      @Override
 19      public boolean meetsCriteria(Ship ship, Type currentBehavior, Game game) {
 20          if (currentBehavior == Type.SCRUBBER){
 21              return true;
 22          }
 23          return game.gameMap.at(ship).hasStructure() && game.gameMap.at(ship).structure.owner.equals(game.me.id);
 24      }
 25  
 26      @Override
 27      public Position getTarget(Ship ship, Game game) {
 28          Position target = innerHarvester.getTarget(ship, game);
 29          return (target != null) ? target : getAdjacent(ship, game);
 30      }
 31  
 32      @Override
 33      public boolean minimizesCost() {
 34          return false;
 35      }
 36  
 37      @Override
 38      public Type getType() {
 39          return Type.HARVESTER;
 40      }
 41  
 42      /**
 43       * @return A good position to explore adjacent this ship
 44       */
 45      private Position getAdjacent(Ship ship, Game game){
 46          GameMap gameMap = game.gameMap;
 47          Direction randomDirection = Direction.ALL_CARDINALS.get(rng.nextInt(4));
 48          Position target = ship.position.directionalOffset(randomDirection);
 49  
 50          for (Position pos : ship.position.adjacentPositions()) {
 51              if (gameMap.at(pos).halite > 1.3 * gameMap.at(target).halite) {
 52                  target = pos;
 53              }
 54          }
 55          return target;
 56      }
 57  
 58      /**
 59       * Subclasses of InnerHarvester allow for slightly different harvesting behavior
 60       */
 61      private abstract class InnerHarvester {
 62          int scanDistance;
 63  
 64          abstract Position getTarget(Ship ship, Game game);
 65      }
 66  
 67      /**
 68       * A ThresholdHarvester targets the closest cell with halite amount above some threshold
 69       */
 70      private class ThresholdHarvester extends InnerHarvester{
 71  
 72          private ThresholdHarvester(){
 73              scanDistance = Parameters.getScanDistanceTH();
 74          }
 75  
 76          @Override
 77          public Position getTarget(Ship ship, Game game) {
 78              int scarceHalite = Parameters.getScarceHalite(game, ship);
 79  
 80              GameMap gameMap = game.gameMap;
 81              if (gameMap.at(ship.position).halite > scarceHalite) {
 82                  return ship.position;
 83              }
 84              int threshold = Parameters.getThresholdTH(game, ship);
 85              MapCell nearestCell = gameMap.nearestCellWithHalite(ship.position, scanDistance, threshold);
 86              return (nearestCell == null) ? null : nearestCell.position;
 87          }
 88      }
 89  
 90      /**
 91       * A BestHarvester targets the cell with the most halite within a given radius
 92       */
 93      private class BestHarvester extends InnerHarvester {
 94          private BestHarvester(){
 95              scanDistance = Parameters.getScanDistanceBH();
 96          }
 97  
 98          @Override
 99          public Position getTarget(Ship ship, Game game) {
100              Log.log("Ship: " + ship.id + ". Pos: " + ship.position);
101              GameMap gameMap = game.gameMap;
102              if (gameMap.at(ship.position).halite > Parameters.getScarceHalite(game, ship)) {
103                  return ship.position;
104              }
105              Position dense = gameMap.densestCell(ship.position, scanDistance).position;
106              Log.log("Ship: " + ship.id + ". Densest: " + dense);
107              return dense;
108          }
109      }
110  }