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 }