package org.mafagafogigante.dungeon.game; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.NavigableSet; import java.util.TreeSet; /** * A sorted set of integers that can be expanded from both ends. */ class ExpandableIntegerSet implements Serializable { private final int minimumDifference; private final int maximumDifference; private final NavigableSet<Integer> set = new TreeSet<>(); /** * Make a new ExpandableIntegerSet. * * @param minimumDifference the minimum difference between integers, positive * @param maximumDifference the maximum difference between integers, bigger than {@code minimumDifference} */ public ExpandableIntegerSet(int minimumDifference, int maximumDifference) { if (minimumDifference < 1) { throw new IllegalArgumentException("minimumDifference must be positive"); } else if (minimumDifference >= maximumDifference) { throw new IllegalArgumentException("maximumDifference must be bigger than minimumDifference"); } else { this.minimumDifference = minimumDifference; this.maximumDifference = maximumDifference; } initialize(); } /** * Generate the first integer of the set. This method should not be invoked twice. */ private void initialize() { if (!set.isEmpty()) { throw new IllegalStateException("set already has an element."); } else { set.add(Random.nextInteger(minimumDifference)); } } /** * Expand the set of integers towards an integer a until there is an integer bigger than or equal to value. * * @return a list with all new integers. */ List<Integer> expand(int value) { if (set.isEmpty()) { throw new IllegalStateException("the set is empty."); } ArrayList<Integer> integerList = new ArrayList<>(); int integer = set.last(); while (value >= integer) { integer += Random.nextInteger(minimumDifference, maximumDifference); integerList.add(integer); set.add(integer); } integer = set.first(); while (value <= integer) { integer -= Random.nextInteger(minimumDifference, maximumDifference); integerList.add(integer); set.add(integer); } return integerList; } /** * @return true if {@code value} is in the set. */ boolean contains(int value) { return set.contains(value); } @Override public String toString() { return "ExpandableIntegerSet currently of " + set; } }