/**
   * Changes the state. Checks if there is active power pills nearby, if true go eat. Checks if
   * there still is a ghost close, if true stay in state Defaults to eat pill state
   *
   * @return returns change state. Returns null if it remains in this state
   */
  public State changeState(Game game, long timeDue) {
    int pacmanPos = game.getPacmanCurrentNodeIndex();
    // Check for power pill
    int closestPowerPill = 0;
    int closestDistPowerPill = -1;
    if (game.getNumberOfActivePowerPills() > 0) {
      for (int i : game.getActivePowerPillsIndices()) {
        int temp = game.getShortestPathDistance(pacmanPos, i);
        if (closestDistPowerPill > temp || closestDistPowerPill == -1) {
          closestPowerPill = i;
          closestDistPowerPill = temp;
        }
      }
    }
    if (game.getNumberOfActivePowerPills() > 0
        && game.getShortestPathDistance(pacmanPos, closestPowerPill) < mach.DistToPowerPill) {
      // System.out.println("(RunFromGhost)Try power pill");
      return (State) mach.dataStruc.get("moveNearestPowerPill");
    }
    // Check for ghost distance

    for (GHOST ghost : GHOST.values()) {
      if (game.getGhostLairTime(ghost) > 0 || game.isGhostEdible(ghost)) {
        continue;
      }
      if (game.getShortestPathDistance(pacmanPos, game.getGhostCurrentNodeIndex(ghost))
          < mach.DistFromNonEdible) {
        mach.dataStruc.put("ghost", ghost);
        return null;
      }
    }
    // System.out.println("(RunFromGhost) Try nearest pill");
    return (State) mach.dataStruc.get("moveNearestPill");
  }
  @Override
  public MOVE getMove(Game game, long timeDue) {
    int current = game.getPacmanCurrentNodeIndex();

    // Strategy 1: if any non-edible ghost is too close (less than MIN_DISTANCE), run away
    for (GHOST ghost : GHOST.values())
      if (game.getGhostEdibleTime(ghost) == 0 && game.getGhostLairTime(ghost) == 0)
        if (game.getShortestPathDistance(current, game.getGhostCurrentNodeIndex(ghost))
            < MIN_DISTANCE)
          return game.getNextMoveAwayFromTarget(
              game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(ghost), DM.PATH);

    // Strategy 2: find the nearest edible ghost and go after them
    int minDistance = Integer.MAX_VALUE;
    GHOST minGhost = null;

    for (GHOST ghost : GHOST.values())
      if (game.getGhostEdibleTime(ghost) > 0) {
        int distance = game.getShortestPathDistance(current, game.getGhostCurrentNodeIndex(ghost));

        if (distance < minDistance) {
          minDistance = distance;
          minGhost = ghost;
        }
      }

    if (minGhost != null) // we found an edible ghost
    return game.getNextMoveTowardsTarget(
          game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(minGhost), DM.PATH);

    // Strategy 3: go after the pills and power pills
    int[] pills = game.getPillIndices();
    int[] powerPills = game.getPowerPillIndices();

    ArrayList<Integer> targets = new ArrayList<Integer>();

    for (int i = 0; i < pills.length; i++) // check which pills are available	
    if (game.isPillStillAvailable(i)) targets.add(pills[i]);

    for (int i = 0; i < powerPills.length; i++) // check with power pills are available
    if (game.isPowerPillStillAvailable(i)) targets.add(powerPills[i]);

    int[] targetsArray = new int[targets.size()]; // convert from ArrayList to array

    for (int i = 0; i < targetsArray.length; i++) targetsArray[i] = targets.get(i);

    // return the next direction once the closest target has been identified
    return game.getNextMoveTowardsTarget(
        current, game.getClosestNodeIndexFromNodeIndex(current, targetsArray, DM.PATH), DM.PATH);
  }
  public DataTuple(Game game, MOVE move) {
    if (move == MOVE.NEUTRAL) {
      move = game.getPacmanLastMoveMade();
    }

    this.DirectionChosen = move;

    this.mazeIndex = game.getMazeIndex();
    this.currentLevel = game.getCurrentLevel();
    this.pacmanPosition = game.getPacmanCurrentNodeIndex();
    this.pacmanLivesLeft = game.getPacmanNumberOfLivesRemaining();
    this.currentScore = game.getScore();
    this.totalGameTime = game.getTotalTime();
    this.currentLevelTime = game.getCurrentLevelTime();
    this.numOfPillsLeft = game.getNumberOfActivePills();
    this.numOfPowerPillsLeft = game.getNumberOfActivePowerPills();

    if (game.getGhostLairTime(GHOST.BLINKY) == 0) {
      this.isBlinkyEdible = game.isGhostEdible(GHOST.BLINKY);
      this.blinkyDist =
          game.getShortestPathDistance(
              game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.BLINKY));
    }

    if (game.getGhostLairTime(GHOST.INKY) == 0) {
      this.isInkyEdible = game.isGhostEdible(GHOST.INKY);
      this.inkyDist =
          game.getShortestPathDistance(
              game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.INKY));
    }

    if (game.getGhostLairTime(GHOST.PINKY) == 0) {
      this.isPinkyEdible = game.isGhostEdible(GHOST.PINKY);
      this.pinkyDist =
          game.getShortestPathDistance(
              game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.PINKY));
    }

    if (game.getGhostLairTime(GHOST.SUE) == 0) {
      this.isSueEdible = game.isGhostEdible(GHOST.SUE);
      this.sueDist =
          game.getShortestPathDistance(
              game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.SUE));
    }

    this.blinkyDir =
        game.getNextMoveTowardsTarget(
            game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.BLINKY), DM.PATH);
    this.inkyDir =
        game.getNextMoveTowardsTarget(
            game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.INKY), DM.PATH);
    this.pinkyDir =
        game.getNextMoveTowardsTarget(
            game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.PINKY), DM.PATH);
    this.sueDir =
        game.getNextMoveTowardsTarget(
            game.getPacmanCurrentNodeIndex(), game.getGhostCurrentNodeIndex(GHOST.SUE), DM.PATH);

    this.numberOfNodesInLevel = game.getNumberOfNodes();
    this.numberOfTotalPillsInLevel = game.getNumberOfPills();
    this.numberOfTotalPowerPillsInLevel = game.getNumberOfPowerPills();
  }