Skip to content

Commit

Permalink
Created reducer that determines closest location ProjectSWGCore#150
Browse files Browse the repository at this point in the history
  • Loading branch information
madsboddum committed Mar 15, 2020
1 parent 4a83fcc commit 9752f2d
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
@@ -0,0 +1,50 @@
package com.projectswg.holocore.resources.support.data.location;

import com.projectswg.common.data.location.Location;
import com.projectswg.common.data.location.Terrain;

import java.util.function.BinaryOperator;

/**
* Reducer that determines the Location that is closest to a given base Location.
*/
public class ClosestLocationReducer implements BinaryOperator<Location> {

private final Location baseLocation;

public ClosestLocationReducer(Location baseLocation) {
this.baseLocation = baseLocation;
}

@Override
public Location apply(Location location1, Location location2) {
Terrain terrainBase = baseLocation.getTerrain();
Terrain terrain1 = location1.getTerrain();
Terrain terrain2 = location2.getTerrain();
boolean terrain1Match = terrainBase == terrain1;
boolean terrain2Match = terrainBase == terrain2;

if (!terrain1Match && !terrain2Match) {
// Given locations are both located on different planets
return null;
}

if (terrain1Match && !terrain2Match) {
// Location 1 is a best fit since it has the same terrain as the base location while location 2 doesn't
return location1;
} else if (!terrain1Match) {
// Location 2 is a best fit since it has the same terrain as the base location while location 1 doesn't
return location2;
}

// location1 and location2 are on same terrain as baseLocation. Let's perform a distance check.
double location1Distance = baseLocation.flatDistanceTo(location1);
double location2Distance = baseLocation.flatDistanceTo(location2);

if (location1Distance > location2Distance) {
return location2; // Location 2 is closest to the player - return location2
} else {
return location1; // Location 1 is closest to the player or both locations are equally close - return location1
}
}
}
@@ -0,0 +1,98 @@
package com.projectswg.holocore.resources.support.data.location;

import com.projectswg.common.data.location.Location;
import com.projectswg.common.data.location.Terrain;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

public class TestClosestLocationReducer {

private ClosestLocationReducer reducer;

@Before
public void setup() {
Location base = Location.builder()
.setTerrain(Terrain.TATOOINE)
.setX(100)
.setZ(-100)
.build();
reducer = new ClosestLocationReducer(base);
}

/**
* Verifies that the terrain check can return neither of the given locations if both are on different planets
*/
@Test
public void testBothLocationsDifferentPlanet() {
Location loc1 = Location.builder()
.setTerrain(Terrain.DANTOOINE)
.setX(100)
.setZ(-100)
.build();

Location loc2 = Location.builder()
.setTerrain(Terrain.DANTOOINE)
.setX(900)
.setZ(-900)
.build();

Location reduced = reducer.apply(loc1, loc2);

assertNull("Null should be the result when reducing locations not located on the same planet as the base location", reduced);
}

/**
* Verifies that the distance check works when all locations are on the same planet
*/
@Test
public void testBothLocationsSamePlanet() {
Location closest = Location.builder()
.setTerrain(Terrain.TATOOINE)
.setX(110)
.setZ(-110)
.build();

Location farthest = Location.builder()
.setTerrain(Terrain.TATOOINE)
.setX(900)
.setZ(-900)
.build();

Location reduced = reducer.apply(closest, farthest);

assertEquals("The location closest to the base location should be the reduced location", closest, reduced);
}

/**
* Verifies that the distance check only matters if on the same terrain
*/
@Test
public void testOneLocationOnDifferentPlanet() {
Location base = Location.builder()
.setTerrain(Terrain.TATOOINE)
.setX(100)
.setZ(-100)
.build();
ClosestLocationReducer reducer = new ClosestLocationReducer(base);

Location closestDifferentPlanet = Location.builder()
.setTerrain(Terrain.DANTOOINE)
.setX(110)
.setZ(-110)
.build();

Location farthestSamePlanet = Location.builder()
.setTerrain(Terrain.TATOOINE)
.setX(900)
.setZ(-900)
.build();

Location reduced = reducer.apply(closestDifferentPlanet, farthestSamePlanet);

assertEquals("The location on the same planet should be picked even if it's furthest away from the X Y Z coordinates", farthestSamePlanet, reduced);
}

}

0 comments on commit 9752f2d

Please sign in to comment.