Commit 7fd11634 authored by Stefan Schuhbaeck's avatar Stefan Schuhbaeck

fix spawn algorithm to ensure no dynamic element overlap completely.

This is necessary because ode algorithm will loop forever if two
dynamic elements overlap in this way.
parent 5bbe81d2
......@@ -52,7 +52,12 @@ public class GroupSourceController extends SourceController {
Iterator<Integer> iter = groupsToSpawn.iterator();
while (iter.hasNext()) {
int groupSize = iter.next();
List<VPoint> newGroup = spawnArray.getNextGroup(groupSize, random);
List<VPoint> newGroup = spawnArray.getNextGroup(groupSize, random, getDynElementsAtSource());
if (newGroup == null)
throw new RuntimeException("Cannot spawn new Group. Source " + source.getId() + " is set " +
"to useFreeSpaceOnly == false but no space is left to spawn group without exactly" +
"overlapping with neighbours which can cause numerical problems. Use useFreeSpaceOnly == true (default)" +
"to queue groups.");
addElementToScenario(newGroup);
iter.remove();
}
......@@ -77,7 +82,12 @@ public class GroupSourceController extends SourceController {
Iterator<Integer> iter = groupsToSpawn.iterator();
while (iter.hasNext()) {
int groupSize = iter.next();
List<VPoint> newGroup = spawnArray.getNextGroup(groupSize);
List<VPoint> newGroup = spawnArray.getNextGroup(groupSize, getDynElementsAtSource());
if (newGroup == null)
throw new RuntimeException("Cannot spawn new Group. Source " + source.getId() + " is set " +
"to useFreeSpaceOnly == false but no space is left to spawn group without exactly" +
"overlapping with neighbours which can cause numerical problems. Use useFreeSpaceOnly == true (default)" +
"to queue groups.");
addElementToScenario(newGroup);
iter.remove();
}
......
......@@ -9,8 +9,6 @@ import org.vadere.util.geometry.shapes.VPoint;
import java.util.LinkedList;
import java.util.Random;
import jdk.nashorn.internal.ir.annotations.Ignore;
public class SingleSourceController extends SourceController {
private int numberToSpawn;
......@@ -37,7 +35,15 @@ public class SingleSourceController extends SourceController {
assert (numberToSpawn >= 0);
} else {
for (int i = 0; i < numberToSpawn; i++) {
spawnPoints.add(spawnArray.getNextRandomSpawnPoint(random));
VPoint nextRandomSpawnPoint = spawnArray.getNextRandomSpawnPoint(getDynElementsAtSource(), random);
if (nextRandomSpawnPoint == null){
throw new RuntimeException("Cannot spawn new Pedestrian. Source " + source.getId() + " is set " +
"to useFreeSpaceOnly == false but no space is left to spawn group without exactly" +
"overlapping with neighbours which can cause numerical problems. Use useFreeSpaceOnly == true (default)" +
"to queue Pedestrians.");
}
spawnPoints.add(nextRandomSpawnPoint);
}
numberToSpawn -= spawnPoints.size();
assert (numberToSpawn >= 0);
......@@ -51,7 +57,14 @@ public class SingleSourceController extends SourceController {
assert (numberToSpawn >= 0);
} else {
for (int i = 0; i < numberToSpawn; i++) {
spawnPoints.add(spawnArray.getNextSpawnPoint());
VPoint nextSpawnPoint = spawnArray.getNextSpawnPoint(getDynElementsAtSource());
if (nextSpawnPoint == null){
throw new RuntimeException("Cannot spawn new Pedestrian. Source " + source.getId() + " is set " +
"to useFreeSpaceOnly == false but no space is left to spawn group without exactly" +
"overlapping with neighbours which can cause numerical problems. Use useFreeSpaceOnly == true (default)" +
"to queue Pedestrians.");
}
spawnPoints.add(nextSpawnPoint);
}
numberToSpawn -= spawnPoints.size();
assert (numberToSpawn >= 0);
......
......@@ -18,6 +18,7 @@ import org.vadere.state.scenario.Pedestrian;
import org.vadere.state.scenario.Source;
import org.vadere.state.scenario.Topography;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
public class TestSourceControllerUsingConstantSpawnRate {
......@@ -159,7 +160,8 @@ public class TestSourceControllerUsingConstantSpawnRate {
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setOneTimeSpawn(0)
.setSpawnNumber(100)
.setUseFreeSpaceOnly(true);
.setUseFreeSpaceOnly(true)
.setSourceDim(new VRectangle(0,0,0.1,0.1)); // small source
initialize(builder);
for (double simTimeInSec = 0; simTimeInSec < 1000; simTimeInSec += 1.0) {
......
......@@ -9,6 +9,7 @@ import org.vadere.state.attributes.scenario.AttributesSource;
import org.vadere.state.attributes.scenario.SourceTestAttributesBuilder;
import org.vadere.state.scenario.Pedestrian;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
public class TestSourceControllerUsingDistributions extends TestSourceControllerUsingConstantSpawnRate {
......@@ -99,7 +100,8 @@ public class TestSourceControllerUsingDistributions extends TestSourceController
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setStartTime(startTime).setEndTime(endTime)
.setSpawnNumber(100)
.setUseFreeSpaceOnly(true);
.setUseFreeSpaceOnly(true)
.setSourceDim(new VRectangle(0,0,0.1,0.1));
initialize(builder);
doUpdates(0, 100, startTime, endTime + 1);
......@@ -122,7 +124,8 @@ public class TestSourceControllerUsingDistributions extends TestSourceController
SourceTestAttributesBuilder builder = new SourceTestAttributesBuilder()
.setOneTimeSpawn(startTime)
.setSpawnNumber(100)
.setUseFreeSpaceOnly(true);
.setUseFreeSpaceOnly(true)
.setSourceDim(new VRectangle(0,0,0.1,0.1));
initialize(builder);
doUpdates(0, 100, 0, startTime + 1);
......
......@@ -41,8 +41,11 @@ public class AttributesSource extends AttributesEmbedShape {
* wave. When the endTime is reached and not enough pedestrians have been
* created yet, there will be less pedestrians than spawnNumber *
* (endTime-startTime)/spawnDelay in the scenario.
*
* useFreeSpaceOnly = false can cause errors if tow pedestrians arw spawned at
* exactly the same place. Maybe Deprecate this switch.
*/
private boolean useFreeSpaceOnly;
private boolean useFreeSpaceOnly = true;
private List<Integer> targetIds = new LinkedList<>();
private List<Double> groupSizeDistribution = Arrays.asList(0.0, 0.0, 1.0);
......@@ -179,4 +182,24 @@ public class AttributesSource extends AttributesEmbedShape {
checkSealed();
this.groupSizeDistribution = groupSizeDistribution;
}
public void setSpawnNumber(int spawnNumber) {
checkSealed();
this.spawnNumber = spawnNumber;
}
public void setUseFreeSpaceOnly(boolean useFreeSpaceOnly) {
checkSealed();
this.useFreeSpaceOnly = useFreeSpaceOnly;
}
public void setTargetIds(List<Integer> targetIds) {
checkSealed();
this.targetIds = targetIds;
}
public void setDynamicElementType(DynamicElementType dynamicElementType) {
checkSealed();
this.dynamicElementType = dynamicElementType;
}
}
......@@ -21,12 +21,12 @@ public class SourceTestAttributesBuilder {
private int maxSpawnNumberTotal = AttributesSource.NO_MAX_SPAWN_NUMBER_TOTAL;
private double x0 = 0.0;
private double y0 = 0.0;
private double x1 = 0.1;
private double x1 = 5.0;
private double y1 = 0.0;
private double x2 = 0.1;
private double y2 = 0.1;
private double x2 = 5.0;
private double y2 = 5.0;
private double x3 = 0.0;
private double y3 = 0.1;
private double y3 = 5.0;
public AttributesSource getResult() {
String json = generateSourceAttributesJson();
......
......@@ -6,6 +6,7 @@ import org.vadere.state.scenario.DynamicElement;
import org.vadere.util.geometry.shapes.VPoint;
import org.vadere.util.geometry.shapes.VRectangle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
......@@ -21,6 +22,7 @@ import java.util.stream.IntStream;
public class SpawnArray {
private static Logger logger = LogManager.getLogger(SpawnArray.class);
private static final double EPSILON = 0.001;
private final VPoint[] spawnPoints;
private final VRectangle spawnElementBound;
// number of spawn elements in x and y Dimension.
......@@ -92,15 +94,44 @@ public class SpawnArray {
return Arrays.copyOf(spawnPoints, spawnPoints.length);
}
public VPoint getNextSpawnPoint() {
VPoint ret = spawnPoints[nextPoint].clone();
nextPoint = (nextPoint + 1) % spawnPoints.length;
// spawn without checking for free space does not make sense.
// Check here for a complete overlap (With epsilon) and use different cell in this case
// caller must handle return null.
@Deprecated
public VPoint getNextSpawnPoint(final List<DynamicElement> neighbours) {
VPoint ret = null;
for (VPoint spawnPoint : spawnPoints) {
VPoint tmp = spawnPoints[nextPoint].clone();
nextPoint = (nextPoint + 1) % spawnPoints.length;
boolean isSpotOccupied = neighbours.stream().anyMatch(n -> n.getShape().getCentroid().equals(tmp, EPSILON));
if (!isSpotOccupied) {
ret = tmp;
break;
}
}
return ret;
}
public VPoint getNextRandomSpawnPoint(Random rnd) {
int index = rnd.nextInt(spawnPoints.length);
return spawnPoints[index];
// spawn without checking for free space does not make sense.
// Check here for a complete overlap (With epsilon) and use different cell in this case
// caller must handle return null.
@Deprecated
public VPoint getNextRandomSpawnPoint(final List<DynamicElement> neighbours, Random rnd) {
List<Integer> indexList = IntStream.range(0, spawnPoints.length)
.boxed().collect(Collectors.toList());
Collections.shuffle(indexList, rnd);
VPoint ret = null;
for (Integer i : indexList) {
VPoint tmp = spawnPoints[i].clone();
boolean isSpotOccupied = neighbours.stream().anyMatch(n -> n.getShape().getCentroid().equals(tmp, EPSILON));
if (!isSpotOccupied){
ret = tmp;
break;
}
}
return ret;
}
/**
......@@ -160,57 +191,13 @@ public class SpawnArray {
// Groups
/**
* This function only spawns non overlapping groups. This means that for instance within a
* source of the size 4x4 there are only 4 possible locations to spawn a group of the size 4
*
* **00 | 00** | 0000 | 0000 |------------------------------------------------------------------
* **00 | 00** | 0000 | 0000 |------------------------------------------------------------------
* 0000 | 0000 | **00 | 00** |------------------------------------------------------------------
* 0000 | 0000 | **00 | 00** |------------------------------------------------------------------
*
* This function does not test if the space is occupied.
*
* @param groupSize size of group which should be spawned
* @return Point List
*/
public LinkedList<VPoint> getNextGroup(int groupSize) {
return nextGroup(groupSize, null);
}
public LinkedList<VPoint> getNextGroup(int groupSize, Random rnd) {
return nextGroup(groupSize, rnd);
@Deprecated
public LinkedList<VPoint> getNextGroup(int groupSize, final List<DynamicElement> neighbours) {
return nextFreeGroupPos(groupSize, null, neighbours, true);
}
private LinkedList<VPoint> nextGroup(int groupSize, Random rnd) {
if (groupSize > spawnPoints.length)
throw new IndexOutOfBoundsException("GroupSize: " + groupSize
+ "to big for source. Max GroupSize of source is " + spawnPoints.length);
GroupPlacementHelper pHelper;
if (groupPlacementHelpers.containsKey(groupSize)) {
pHelper = groupPlacementHelpers.get(groupSize);
} else {
pHelper = new GroupPlacementHelper(xDim, yDim, groupSize);
groupPlacementHelpers.put(groupSize, pHelper);
}
int groupNumber;
if (rnd != null) {
groupNumber = rnd.nextInt(pHelper.getNoneOverlappingGroupCount());
} else {
groupNumber = nextGroupPos.getOrDefault(groupSize, 0);
}
LinkedList<VPoint> points = new LinkedList<>();
for (int i = 0; i < groupSize; i++) {
// move index in group
int index = pHelper.getNoneOverlappingIndex(groupNumber, i);
points.add(spawnPoints[index].clone());
}
nextGroupPos.put(groupSize, pHelper.nextNoneOverlappingGroupNumber(groupNumber));
return points;
public LinkedList<VPoint> getNextGroup(int groupSize, Random rnd, final List<DynamicElement> neighbours) {
return nextFreeGroupPos(groupSize, rnd, neighbours, true);
}
/**
......@@ -227,14 +214,14 @@ public class SpawnArray {
* @return Point List or null if no free location is found for given group size.
*/
public LinkedList<VPoint> getNextFreeGroup(int groupSize, final List<DynamicElement> neighbours) {
return nextFreeGroupPos(groupSize, null, neighbours);
return nextFreeGroupPos(groupSize, null, neighbours, false);
}
public LinkedList<VPoint> getNextFreeGroup(int groupSize, Random rnd, final List<DynamicElement> neighbours) {
return nextFreeGroupPos(groupSize, rnd, neighbours);
return nextFreeGroupPos(groupSize, rnd, neighbours, false);
}
private LinkedList<VPoint> nextFreeGroupPos(int groupSize, Random rnd, final List<DynamicElement> neighbours) {
private LinkedList<VPoint> nextFreeGroupPos(int groupSize, Random rnd, final List<DynamicElement> neighbours, boolean allowOverlap) {
if (groupSize > spawnPoints.length)
throw new IndexOutOfBoundsException("GroupSize: " + groupSize
+ "to big for source. Max Groupsize of source is " + spawnPoints.length);
......@@ -252,21 +239,36 @@ public class SpawnArray {
//over all overlapping groups in source
boolean isOccupied = true;
List<Integer> groupNumbers;
ArrayList<Integer> groupNumbers;
if (rnd != null) {
groupNumbers = IntStream.range(0, pHelper.getOverlappingGroupCount())
.boxed().collect(Collectors.toList());
.boxed().collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(groupNumbers, rnd);
} else {
groupNumbers = IntStream.range(0, pHelper.getOverlappingGroupCount())
.boxed().collect(Collectors.toList());
.boxed().collect(Collectors.toCollection(ArrayList::new));
}
groupNumbers.trimToSize();
// run through all possible group placements. If allowOverlap is set we must start from
// the next group pos saved in the the nextGroupPos map. The if variable g is not used
// and only is used to run through all placements options. The currently used index
// is currentGroupPos.
int currentGroupPos = allowOverlap ? nextGroupPos.getOrDefault(groupSize, 0) : 0;
for (int g=0 ; g < groupNumbers.size(); g++) {
for (Integer groupNumber : groupNumbers) {
// test if at currentGroupPos all places within the group are free or
// (in the case of allowOverlap) only the centroid of the new group members does not
// overlap with existing neighbours
for (int i = 0; i < groupSize; i++) {
int index = pHelper.getOverlappingIndex(groupNumber, i);
int index = pHelper.getOverlappingIndex(currentGroupPos, i);
VPoint p = spawnPoints[index].clone();
isOccupied = neighbours.parallelStream().anyMatch(n -> ((n.getShape().distance(p) < d) || n.getShape().contains(p)));
if (allowOverlap){
isOccupied = neighbours.parallelStream().anyMatch(n -> n.getShape().getCentroid().equals(p, EPSILON));
} else {
isOccupied = neighbours.parallelStream().anyMatch(n -> ((n.getShape().distance(p) < d) || n.getShape().contains(p)));
}
if (!isOccupied) {
points.add(p);
} else {
......@@ -274,10 +276,15 @@ public class SpawnArray {
break;
}
}
currentGroupPos = (currentGroupPos + 1) % pHelper.getOverlappingGroupCount();
// if a group was found with no overlapping point break and return group.
if (!isOccupied)
if (!isOccupied) {
break;
}
}
nextGroupPos.put(groupSize, currentGroupPos);
if (points.size() < groupSize) {
return null;
......
......@@ -23,9 +23,9 @@ import static org.junit.Assert.assertNull;
public class SpawnArrayTest {
VRectangle source;
VRectangle elementBound;
SpawnArray spawnArray;
private VRectangle source;
private VRectangle elementBound;
private SpawnArray spawnArray;
@Test
public void NumberOfElements() {
......@@ -87,7 +87,7 @@ public class SpawnArrayTest {
spawnArray = new SpawnArray(source, elementBound);
VPoint[] spawnPoints = spawnArray.getSpawnPoints();
LinkedList<VPoint> points = spawnArray.getNextGroup(6);
LinkedList<VPoint> points = spawnArray.getNextGroup(6, createMock(0.5));
assertEquals(spawnPoints[0], points.pollFirst());
assertEquals(spawnPoints[1], points.pollFirst());
assertEquals(spawnPoints[2], points.pollFirst());
......@@ -104,23 +104,51 @@ public class SpawnArrayTest {
spawnArray = new SpawnArray(source, elementBound);
// first Point
VPoint p = spawnArray.getNextSpawnPoint();
List<DynamicElement> dynamicElements = createMock(0.5);
VPoint p = spawnArray.getNextSpawnPoint(dynamicElements);
assertEquals("Point does not match", p, new VPoint(1.5, 1.5));
assertEquals("Next Element does not match", 1, spawnArray.getNextSpawnPointIndex());
// 10 more points
IntStream.range(0, 10).forEach(i -> spawnArray.getNextSpawnPoint());
IntStream.range(0, 10).forEach(i -> spawnArray.getNextSpawnPoint(dynamicElements));
assertEquals("Next Element does not match", 11, spawnArray.getNextSpawnPointIndex());
VPoint first = new VPoint(source.x + elementBound.width / 2, source.y + elementBound.height / 2);
assertEquals("Point does not match", spawnArray.getNextSpawnPoint(),
assertEquals("Point does not match", spawnArray.getNextSpawnPoint(dynamicElements),
new VPoint(first.x + 2 * 2 * elementBound.width / 2, first.y + 1 * 2 * elementBound.height / 2));
// now at point 12 because getNextSpawnPoint() increments NextPointIndex
// spawn 81 more to wrapp around to point 12.
IntStream.range(0, 81).forEach(i -> spawnArray.getNextSpawnPoint());
IntStream.range(0, 81).forEach(i -> spawnArray.getNextSpawnPoint(dynamicElements));
assertEquals("Next Element does not match", 12, spawnArray.getNextSpawnPointIndex());
assertEquals("Point does not match", spawnArray.getNextSpawnPoint(),
assertEquals("Point does not match", spawnArray.getNextSpawnPoint(dynamicElements),
new VPoint(first.x + 3 * 2 * elementBound.width / 2, first.y + 1 * 2 * elementBound.height / 2));
VPoint[] spawnPoints = spawnArray.getSpawnPoints();
List<DynamicElement> dynamicElements2 = createMock(0.5,
spawnPoints[12], // direct match (use next)
spawnPoints[13].add(new VPoint(0, 0.0003)), // match within Epsilon (use next)
spawnPoints[14].add(new VPoint(0.3, 0)) // match outside Epsilon (use this one)
);
assertEquals("Point does not match", spawnArray.getNextSpawnPoint(dynamicElements2), spawnPoints[14]);
assertEquals("Next Element does not match", 15, spawnArray.getNextSpawnPointIndex());
}
// if all points are occupied measured only with centroid point throw exception
@Test()
public void PointsWithException(){
source = new VRectangle(1.0, 1.0, 2.0, 2.0);
elementBound = new VRectangle(0.0, 0.0, 1.0, 1.0);
spawnArray = new SpawnArray(source, elementBound);
VPoint[] spawnPoints = spawnArray.getSpawnPoints();
List<DynamicElement> dynamicElements = createMock(0.5,
spawnPoints[0],
spawnPoints[1],
spawnPoints[2],
spawnPoints[3].add(new VPoint(0, 0.0003))
);
assertEquals("there should be no free spot", null, spawnArray.getNextSpawnPoint(dynamicElements));
}
@Test
......@@ -187,50 +215,52 @@ public class SpawnArrayTest {
assertEquals("Number of spawn points does not match", 64, spawnArray.getSpawnPoints().length);
VPoint[] spawnPoint = spawnArray.getSpawnPoints();
List<DynamicElement> dynamicElements = createMock(0.5);
//group 0
LinkedList<VPoint> group = spawnArray.getNextGroup(4);
assertEquals(group.pollFirst(), spawnPoint[0]);
assertEquals(group.pollFirst(), spawnPoint[1]);
assertEquals(group.pollFirst(), spawnPoint[8]);
assertEquals(group.pollFirst(), spawnPoint[9]);
LinkedList<VPoint> group = spawnArray.getNextGroup(4, dynamicElements);
assertEquals( spawnPoint[0], group.pollFirst());
assertEquals( spawnPoint[1], group.pollFirst());
assertEquals( spawnPoint[8], group.pollFirst());
assertEquals( spawnPoint[9], group.pollFirst());
//group 1
group = spawnArray.getNextGroup(4);
assertEquals(group.pollFirst(), spawnPoint[2]);
assertEquals(group.pollFirst(), spawnPoint[3]);
assertEquals(group.pollFirst(), spawnPoint[10]);
assertEquals(group.pollFirst(), spawnPoint[11]);
group = spawnArray.getNextGroup(4, dynamicElements);
assertEquals( spawnPoint[1], group.pollFirst());
assertEquals( spawnPoint[2], group.pollFirst());
assertEquals( spawnPoint[9], group.pollFirst());
assertEquals( spawnPoint[10], group.pollFirst());
//group 2-3
spawnArray.getNextGroup(4);
group = spawnArray.getNextGroup(4);
assertEquals(group.pollFirst(), spawnPoint[6]);
assertEquals(group.pollFirst(), spawnPoint[7]);
assertEquals(group.pollFirst(), spawnPoint[14]);
assertEquals(group.pollFirst(), spawnPoint[15]);
//group 4 (line wrap)
group = spawnArray.getNextGroup(4);
assertEquals(group.pollFirst(), spawnPoint[16]);
assertEquals(group.pollFirst(), spawnPoint[17]);
assertEquals(group.pollFirst(), spawnPoint[24]);
assertEquals(group.pollFirst(), spawnPoint[25]);
//group 15 (last group)
IntStream.range(0, 10).forEach(i -> spawnArray.getNextGroup(4));
group = spawnArray.getNextGroup(4);
assertEquals(group.pollFirst(), spawnPoint[54]);
assertEquals(group.pollFirst(), spawnPoint[55]);
assertEquals(group.pollFirst(), spawnPoint[62]);
assertEquals(group.pollFirst(), spawnPoint[63]);
spawnArray.getNextGroup(4 , dynamicElements);
group = spawnArray.getNextGroup(4, dynamicElements);
assertEquals( spawnPoint[3], group.pollFirst());
assertEquals( spawnPoint[4], group.pollFirst());
assertEquals( spawnPoint[11], group.pollFirst());
assertEquals( spawnPoint[12], group.pollFirst());
//group 8 (line wrap)
IntStream.range(4, 7).forEach(i -> spawnArray.getNextGroup(4,dynamicElements));
group = spawnArray.getNextGroup(4, dynamicElements);
assertEquals( spawnPoint[8], group.pollFirst());
assertEquals( spawnPoint[9], group.pollFirst());
assertEquals( spawnPoint[16], group.pollFirst());
assertEquals( spawnPoint[17], group.pollFirst());
//group 48 (last group)
IntStream.range(8, 48).forEach(i -> spawnArray.getNextGroup(4, dynamicElements));
group = spawnArray.getNextGroup(4, dynamicElements);
assertEquals( spawnPoint[54], group.pollFirst());
assertEquals( spawnPoint[55], group.pollFirst());
assertEquals( spawnPoint[62], group.pollFirst());
assertEquals( spawnPoint[63], group.pollFirst());
// group 0 (wrap around to first group)
group = spawnArray.getNextGroup(4);
assertEquals(group.pollFirst(), spawnPoint[0]);
assertEquals(group.pollFirst(), spawnPoint[1]);
assertEquals(group.pollFirst(), spawnPoint[8]);
assertEquals(group.pollFirst(), spawnPoint[9]);
group = spawnArray.getNextGroup(4, dynamicElements);
assertEquals( spawnPoint[0], group.pollFirst());
assertEquals( spawnPoint[1], group.pollFirst());
assertEquals( spawnPoint[8], group.pollFirst());
assertEquals( spawnPoint[9], group.pollFirst());
}
......@@ -242,54 +272,70 @@ public class SpawnArrayTest {
spawnArray = new SpawnArray(source, elementBound);
assertEquals("Number of spawn points does not match", 64, spawnArray.getSpawnPoints().length);
VPoint[] spawnPoint = spawnArray.getSpawnPoints();
VPoint[] spawnPoints = spawnArray.getSpawnPoints();
List<DynamicElement> dynamicElements = createMock(0.5);
//group 0
LinkedList<VPoint> group = spawnArray.getNextGroup(6);
assertEquals(group.pollFirst(), spawnPoint[0]);
assertEquals(group.pollFirst(), spawnPoint[1]);
assertEquals(group.pollFirst(), spawnPoint[2]);
assertEquals(group.pollFirst(), spawnPoint[8]);
assertEquals(group.pollFirst(), spawnPoint[9]);
assertEquals(group.pollFirst(), spawnPoint[10]);
LinkedList<VPoint> group = spawnArray.getNextGroup(6, dynamicElements);
assertEquals(spawnPoints[0], group.pollFirst());
assertEquals(spawnPoints[1], group.pollFirst());
assertEquals(spawnPoints[2], group.pollFirst());
assertEquals(spawnPoints[8], group.pollFirst());
assertEquals(spawnPoints[9], group.pollFirst());
assertEquals(spawnPoints[10], group.pollFirst());
//group 1