/ benchmark / hlt / Ripple.java
Ripple.java
 1  package hlt;
 2  
 3  import java.util.ArrayList;
 4  import java.util.HashSet;
 5  import java.util.Iterator;
 6  import java.util.Set;
 7  
 8  public class Ripple implements Iterator<Position> {
 9  
10      final private GameMap gameMap;
11      final private Position origin;
12      final private int maxDistance;
13      private ArrayList<Position> positions = new ArrayList<>();
14      private int currentDistance = 0;
15  
16      /**
17       * @return The number of cells within a ripple of size 'distance'. Includes origin position
18       */
19      public static int positionsWithinDist(int distance){
20          int num = 1;
21          for (int i = 1; i <= distance; i++){
22              num += 4 * i;
23          }
24          return num;
25      }
26  
27      /**
28       * Creates a ripple-like iterator of positions in increasing distance away from origin
29       * The ripple ends at distance maxDistance
30       */
31      public Ripple(GameMap gameMap, Position origin, int maxDistance){
32          this.gameMap = gameMap;
33          this.origin = origin;
34          this.maxDistance = maxDistance;
35          positions.add(origin);
36      }
37  
38      @Override
39      public boolean hasNext() {
40          return !positions.isEmpty();
41      }
42  
43      @Override
44      public Position next() {
45          Position next = gameMap.normalize(positions.remove(0));
46          if (positions.isEmpty() && currentDistance < maxDistance){
47              currentDistance++;
48              Set<Position> positionsSet = new HashSet<>();
49              for (int i = 0; i <= currentDistance; i++){
50                  int dx = i;
51                  int dy = currentDistance - dx;
52                  positionsSet.add(origin.offset(dx,   dy));
53                  positionsSet.add(origin.offset(-dx,  dy));
54                  positionsSet.add(origin.offset(dx,  -dy));
55                  positionsSet.add(origin.offset(-dx, -dy));
56              }
57              positions = new ArrayList<>(positionsSet);
58          }
59          return next;
60      }
61  }