public void die() {
   goToNest = false;
   movementsMade = 0;
   discoveredFood.clear();
   Set<WorldGridSquare> nests = antColony.getNests();
   if (!nests.isEmpty()) {
     int nestIndex = (int) (nests.size() * Math.random());
     WorldGridSquare nest = (WorldGridSquare) nests.toArray()[nestIndex];
     this.x = nest.column;
     this.y = nest.row;
   }
 }
  public void step() {
    double chancetoTakeBest =
        Math.random(); // I don't like this, it s/b based upon pg. 222, but temp for random movement
    movementsMade++;

    discoveredFood.retainAll(antColony.getFood());

    if (this.goToNest) // has found ALL food and is working way back home.
    {
      if (this.antNetwork[this.x][this.y].hasNest()) die(); // ant "dies" upon return to the nest
      else {
        double currentMaxNestPheromone = 0;
        Map<WorldGridSquare, Double> maxFoodMap = new HashMap<WorldGridSquare, Double>();
        List<WorldGridSquare> maxNestGridSquaresList = new ArrayList<WorldGridSquare>();
        List<WorldGridSquare> allNeighborGridSquaresList = new ArrayList<WorldGridSquare>();
        double totalNeighborPheromones = 0;

        for (int c = -1; c <= 1; c++) {
          if (this.x + c < 0 || this.x + c >= antNetwork.length) continue;

          for (int r = -1; r <= 1; r++) {
            // ignore self, edges
            if (c == 0 && r == 0) continue;
            if (y + r < 0 || y + r >= antNetwork[0].length) continue;

            if (!antNetwork[this.x + c][this.y + r].isBlocked()) {
              allNeighborGridSquaresList.add(antNetwork[this.x + c][this.y + r]);
              totalNeighborPheromones += antNetwork[this.x + c][this.y + r].nestPheromoneLevel;

              if (antNetwork[this.x + c][this.y + r].getNestPheromoneLevel()
                  > currentMaxNestPheromone) {
                currentMaxNestPheromone =
                    antNetwork[this.x + c][this.y + r].getNestPheromoneLevel();
                maxNestGridSquaresList.clear();
                maxNestGridSquaresList.add(antNetwork[this.x + c][this.y + r]);
              } else if (antNetwork[this.x + c][this.y + r].getNestPheromoneLevel()
                  == currentMaxNestPheromone)
                maxNestGridSquaresList.add(antNetwork[this.x + c][this.y + r]);

              for (WorldGridSquare food : discoveredFood) {
                if (!maxFoodMap.containsKey(food)
                    || antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food)
                        > maxFoodMap.get(food))
                  maxFoodMap.put(
                      food, antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food));
              }
            }
          }
        }

        if (antNetwork[x][y].isFood())
          maxFoodMap.put(antNetwork[this.x][this.y], WorldGridSquare.maxFoodPheromoneLevel);

        for (WorldGridSquare food : discoveredFood) {
          antNetwork[this.x][this.y].setFoodPheromone(food, maxFoodMap.get(food) * Ant.dropOffRate);
        }

        // There's a % chance, essentially, that the Ant will choose the best route
        if (Ant.bestNextSquare > chancetoTakeBest) {
          if (!maxNestGridSquaresList.isEmpty()) {
            int randBestGSIndex = (int) (maxNestGridSquaresList.size() * Math.random());
            WorldGridSquare bestGridSquare = maxNestGridSquaresList.get(randBestGSIndex);

            this.x = bestGridSquare.column;
            this.y = bestGridSquare.row;
          }
        } else // if random didn't result in the best route, choose a (partially) random alternate
        {
          double currentPheromones = 0;
          double randPheromoneLevel = totalNeighborPheromones * Math.random();
          for (WorldGridSquare neighbor : allNeighborGridSquaresList) {
            currentPheromones += neighbor.getNestPheromoneLevel();
            if (currentPheromones > randPheromoneLevel) {
              this.x = neighbor.column;
              this.y = neighbor.row;
              break;
            }
          }
        }
      }
    } else // go hunting for food in the wild
    {
      if (antNetwork[this.x][this.y].isFood()) {
        discoveredFood.add(antNetwork[this.x][this.y]);
        if (discoveredFood.size() >= antColony.getFood().size()) {
          movementsMade = 0; // reset the track
          goToNest = true; // start heading home
          return;
        }
      } else if (antNetwork[this.x][this.y].hasNest()) {
        if (movementsMade > 1) {
          die();
          return;
        }
      }

      double currentMaxFoodPheromone = 0;
      double currentMaxNestPheromone = 0;

      Map<WorldGridSquare, Double> maxFoodMap = new HashMap<WorldGridSquare, Double>();
      List<WorldGridSquare> maxFoodGridSquaresList = new ArrayList<WorldGridSquare>();
      List<WorldGridSquare> allNeighborGridSquaresList = new ArrayList<WorldGridSquare>();
      double totalNeighborPheromones = 0;

      for (int c = -1; c <= 1; c++) {
        if (this.x + c < 0 || this.x + c >= antNetwork.length) continue;

        for (int r = -1; r <= 1; r++) {
          // ignore self, edges
          if (c == 0 && r == 0) continue;
          if (this.y + r < 0 || this.y + r >= antNetwork[0].length) continue;

          if (!antNetwork[this.x + c][this.y + r].isBlocked()) {
            allNeighborGridSquaresList.add(antNetwork[this.x + c][this.y + r]);

            if (currentMaxFoodPheromone == 0)
              maxFoodGridSquaresList.add(antNetwork[this.x + c][this.y + r]);

            for (WorldGridSquare food : discoveredFood) {
              if (!maxFoodMap.containsKey(food)
                  || antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food)
                      > maxFoodMap.get(food))
                maxFoodMap.put(
                    food, antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food));
            }

            if (antNetwork[this.x][this.y].isFood())
              maxFoodMap.put(antNetwork[this.x][this.y], WorldGridSquare.maxFoodPheromoneLevel);

            for (WorldGridSquare food : discoveredFood) {
              antNetwork[this.x][this.y].setFoodPheromone(
                  food, maxFoodMap.get(food) * Ant.dropOffRate);
            }

            if (antNetwork[this.x + c][this.y + r].getNestPheromoneLevel()
                > currentMaxNestPheromone) {
              currentMaxNestPheromone = antNetwork[this.x + c][this.y + r].getNestPheromoneLevel();
            }

            if (antColony.getFood().isEmpty()) totalNeighborPheromones += 1;
            else {
              for (WorldGridSquare food : antColony.getFood()) {
                if (discoveredFood.contains(food)) continue;

                totalNeighborPheromones +=
                    antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food);

                if (antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food)
                    > currentMaxFoodPheromone) {
                  currentMaxFoodPheromone =
                      antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food);
                  maxFoodGridSquaresList.clear();
                  maxFoodGridSquaresList.add(antNetwork[this.x + c][this.y + r]);
                } else if (antNetwork[this.x + c][this.y + r].getFoodPheromoneLevel(food)
                    == currentMaxFoodPheromone) {
                  maxFoodGridSquaresList.add(antNetwork[this.x + c][this.y + r]);
                }
              }
            }
          }
        }
      }

      if (antNetwork[this.x][this.y].hasNest())
        currentMaxNestPheromone = WorldGridSquare.maxNestPheromoneLevel;

      antNetwork[this.x][this.y].setNestPheromone(currentMaxNestPheromone * Ant.dropOffRate);

      if (Ant.bestNextSquare > chancetoTakeBest) {
        if (!maxFoodGridSquaresList.isEmpty()) {
          int randBestGSIndex = (int) (maxFoodGridSquaresList.size() * Math.random());
          WorldGridSquare bestGridSquare = maxFoodGridSquaresList.get(randBestGSIndex);

          this.x = bestGridSquare.column;
          this.y = bestGridSquare.row;
        }
      } else // if random didn't result in the best route, choose a (partially) random alternate
      {
        double currentPheromones = 0;
        double randPheromoneLevel = totalNeighborPheromones * Math.random();

        for (WorldGridSquare neighbor : allNeighborGridSquaresList) {
          if (antColony.getFood().isEmpty()) {
            currentPheromones += 1;
            if (currentPheromones > randPheromoneLevel) {
              this.x = neighbor.column;
              this.y = neighbor.row;
              break;
            }
          } else {
            for (WorldGridSquare food : antColony.getFood()) {
              if (discoveredFood.contains(food)) continue;
              currentPheromones += neighbor.getFoodPheromoneLevel(food);
              if (currentPheromones > randPheromoneLevel) {
                this.x = neighbor.column;
                this.y = neighbor.row;
                break;
              }
            }
          }
        }
      }
    }
  }