Refactored Walls and added test class

This commit is contained in:
tastybento 2020-10-11 09:03:13 -07:00
parent 50e3bf2988
commit 5f8e8fae99
3 changed files with 336 additions and 84 deletions

View File

@ -29,98 +29,35 @@ public class Walls extends MinMaxXZ {
private static final List<BlockFace> ORDINALS = Arrays.asList(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
public Walls(Roof roof) {
class WallFinder {
int radiusMinX;
int radiusMaxX;
int radiusMinZ;
int radiusMaxZ;
boolean stopMinX;
boolean stopMaxX;
boolean stopMinZ;
boolean stopMaxZ;
boolean isSearching() {
return !stopMinX || !stopMaxX || !stopMinZ || !stopMaxZ;
}
}
public Walls findWalls(Roof roof) {
// The player is under the roof
// Assume the player is inside the greenhouse they are trying to create
Location loc = roof.getLocation();
World world = roof.getLocation().getWorld();
World world = loc.getWorld();
floor = getFloorY(world, roof.getHeight(), roof.getMinX(), roof.getMaxX(), roof.getMinZ(), roof.getMaxZ());
// Now start with the player's x and z location
int radiusMinX = 0;
int radiusMaxX = 0;
int radiusMinZ = 0;
int radiusMaxZ = 0;
boolean stopMinX = false;
boolean stopMaxX = false;
boolean stopMinZ = false;
boolean stopMaxZ = false;
WallFinder wf = new WallFinder();
minX = loc.getBlockX();
maxX = loc.getBlockX();
minZ = loc.getBlockZ();
maxZ = loc.getBlockZ();
do {
// Look around player in an ever expanding cube
minX = loc.getBlockX() - radiusMinX;
maxX = loc.getBlockX() + radiusMaxX;
minZ = loc.getBlockZ() - radiusMinZ;
maxZ = loc.getBlockZ() + radiusMaxZ;
int y;
for (y = roof.getHeight() - 1; y > floor; y--) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
// Only look around outside edge
if (!((x > minX && x < maxX) && (z > minZ && z < maxZ))) {
// Look at block faces
for (BlockFace bf: ORDINALS) {
switch (bf) {
case EAST:
// positive x
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
stopMaxX = true;
}
break;
case WEST:
// negative x
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
stopMinX = true;
}
break;
case NORTH:
// negative Z
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
stopMinZ = true;
}
break;
case SOUTH:
// positive Z
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
stopMaxZ = true;
}
break;
default:
break;
}
}
}
}
}
}
if (minX < roof.getMinX()) {
stopMinX = true;
}
if (maxX > roof.getMaxX()) {
stopMaxX = true;
}
if (minZ < roof.getMinZ()) {
stopMinZ = true;
}
if (maxZ > roof.getMaxZ()) {
stopMaxZ = true;
}
// Expand the edges
if (!stopMinX) {
radiusMinX++;
}
if (!stopMaxX) {
radiusMaxX++;
}
if (!stopMinZ) {
radiusMinZ++;
}
if (!stopMaxZ) {
radiusMaxZ++;
}
} while (!stopMinX || !stopMaxX || !stopMinZ || !stopMaxZ);
lookAround(loc, wf, roof);
} while (wf.isSearching());
// We should have the largest cube we can make now
minX--;
maxX++;
@ -128,9 +65,93 @@ public class Walls extends MinMaxXZ {
maxZ++;
// Find the floor again, only looking within the walls
floor = getFloorY(world, roof.getHeight(), minX, maxX, minZ,maxZ);
return this;
}
private int getFloorY(World world, int y, int minX, int maxX, int minZ, int maxZ) {
void lookAround(Location loc, WallFinder wf, Roof roof) {
World world = loc.getWorld();
// Look around player in an ever expanding cube
minX = loc.getBlockX() - wf.radiusMinX;
maxX = loc.getBlockX() + wf.radiusMaxX;
minZ = loc.getBlockZ() - wf.radiusMinZ;
maxZ = loc.getBlockZ() + wf.radiusMaxZ;
for (int y = roof.getHeight() - 1; y > floor; y--) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
// Only look around outside edge
if (!((x > minX && x < maxX) && (z > minZ && z < maxZ))) {
// Look at block faces
lookAtBlockFaces(wf, world, x, y, z);
}
}
}
}
analyzeFindings(wf, roof);
}
void analyzeFindings(WallFinder wf, Roof roof) {
if (minX < roof.getMinX()) {
wf.stopMinX = true;
}
if (maxX > roof.getMaxX()) {
wf.stopMaxX = true;
}
if (minZ < roof.getMinZ()) {
wf.stopMinZ = true;
}
if (maxZ > roof.getMaxZ()) {
wf.stopMaxZ = true;
}
// Expand the edges
if (!wf.stopMinX) {
wf.radiusMinX++;
}
if (!wf.stopMaxX) {
wf.radiusMaxX++;
}
if (!wf.stopMinZ) {
wf.radiusMinZ++;
}
if (!wf.stopMaxZ) {
wf.radiusMaxZ++;
}
}
void lookAtBlockFaces(WallFinder wf, World world, int x, int y, int z) {
for (BlockFace bf: ORDINALS) {
switch (bf) {
case EAST:
// positive x
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
wf.stopMaxX = true;
}
break;
case WEST:
// negative x
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
wf.stopMinX = true;
}
break;
case NORTH:
// negative Z
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
wf.stopMinZ = true;
}
break;
case SOUTH:
// positive Z
if (WALL_BLOCKS.contains(world.getBlockAt(x, y, z).getRelative(bf).getType())) {
wf.stopMaxZ = true;
}
break;
default:
break;
}
}
}
int getFloorY(World world, int y, int minX, int maxX, int minZ, int maxZ) {
// Find the floor - defined as the last y under the roof where there are no wall blocks
int wallBlockCount;
do {

View File

@ -58,7 +58,7 @@ public class GreenhouseFinder {
return result;
}
// Find the walls
Walls walls = new Walls(roof);
Walls walls = new Walls().findWalls(roof);
// Make the initial greenhouse
gh = new Greenhouse(location.getWorld(), walls, roof.getHeight());
// Set the original biome

View File

@ -0,0 +1,231 @@
package world.bentobox.greenhouses.greenhouse;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.powermock.modules.junit4.PowerMockRunner;
import world.bentobox.greenhouses.greenhouse.Walls.WallFinder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
public class WallsTest {
@Mock
private Roof roof;
@Mock
private Block block;
@Mock
private Location location;
@Mock
private World world;
/**
* Class under test
*/
private Walls walls;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
walls = new Walls();
when(world.getMaxHeight()).thenReturn(255);
when(world.getBlockAt(anyInt(), anyInt(), anyInt())).thenReturn(block);
when(world.getBlockAt(any(Location.class))).thenReturn(block);
when(location.getWorld()).thenReturn(world);
when(location.getBlockX()).thenReturn(10);
when(location.getBlockY()).thenReturn(10);
when(location.getBlockZ()).thenReturn(10);
when(location.getBlock()).thenReturn(block);
when(location.clone()).thenReturn(location);
when(block.getRelative(any())).thenReturn(block);
when(block.getType()).thenReturn(Material.GLASS);
when(roof.getHeight()).thenReturn(1);
when(roof.getLocation()).thenReturn(location);
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#findWalls(world.bentobox.greenhouses.greenhouse.Roof)}.
*/
@Test
public void testFindWalls() {
walls.findWalls(roof);
assertEquals("Walls [minX=-2, maxX=11, minZ=-2, maxZ=11, floor=0]", walls.toString());
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAround(org.bukkit.Location, world.bentobox.greenhouses.greenhouse.Walls.WallFinder, world.bentobox.greenhouses.greenhouse.Roof)}.
*/
@Test
public void testLookAround() {
WallFinder wf = walls.new WallFinder();
walls.lookAround(location, wf, roof);
assertTrue(wf.stopMaxX);
assertTrue(wf.stopMaxZ);
assertFalse(wf.stopMinX);
assertFalse(wf.stopMinZ);
assertEquals(1, wf.radiusMinX);
assertEquals(0, wf.radiusMaxX);
assertEquals(1, wf.radiusMinZ);
assertEquals(0, wf.radiusMaxZ);
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#analyzeFindings(world.bentobox.greenhouses.greenhouse.Walls.WallFinder, world.bentobox.greenhouses.greenhouse.Roof)}.
*/
@Test
public void testAnalyzeFindings() {
WallFinder wf = walls.new WallFinder();
walls.analyzeFindings(wf, roof);
assertFalse(wf.stopMaxX);
assertFalse(wf.stopMaxZ);
assertFalse(wf.stopMinX);
assertFalse(wf.stopMinZ);
assertEquals(1, wf.radiusMinX);
assertEquals(1, wf.radiusMaxX);
assertEquals(1, wf.radiusMinZ);
assertEquals(1, wf.radiusMaxZ);
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#analyzeFindings(world.bentobox.greenhouses.greenhouse.Walls.WallFinder, world.bentobox.greenhouses.greenhouse.Roof)}.
*/
@Test
public void testAnalyzeFindingsStop() {
walls.minX = -1;
walls.maxX = 1;
walls.minZ = -1;
walls.maxZ = 1;
WallFinder wf = walls.new WallFinder();
walls.analyzeFindings(wf, roof);
assertTrue(wf.stopMaxX);
assertTrue(wf.stopMaxZ);
assertTrue(wf.stopMinX);
assertTrue(wf.stopMinZ);
assertEquals(0, wf.radiusMinX);
assertEquals(0, wf.radiusMaxX);
assertEquals(0, wf.radiusMinZ);
assertEquals(0, wf.radiusMaxZ);
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAtBlockFaces(world.bentobox.greenhouses.greenhouse.Walls.WallFinder, org.bukkit.World, int, int, int)}.
*/
@Test
public void testLookAtBlockFaces() {
WallFinder wf = walls.new WallFinder();
walls.lookAtBlockFaces(wf, world, 0, 5, -1);
assertTrue(wf.stopMaxX);
assertTrue(wf.stopMaxZ);
assertTrue(wf.stopMinX);
assertTrue(wf.stopMinZ);
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#lookAtBlockFaces(world.bentobox.greenhouses.greenhouse.Walls.WallFinder, org.bukkit.World, int, int, int)}.
*/
@Test
public void testLookAtBlockFacesNoGlass() {
when(block.getType()).thenReturn(Material.AIR);
WallFinder wf = walls.new WallFinder();
walls.lookAtBlockFaces(wf, world, 0, 5, -1);
assertFalse(wf.stopMaxX);
assertFalse(wf.stopMaxZ);
assertFalse(wf.stopMinX);
assertFalse(wf.stopMinZ);
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(org.bukkit.World, int, int, int, int, int)}.
*/
@Test
public void testGetFloorYZeroY() {
assertEquals(0, walls.getFloorY(world, 10, 0, 1, 0, 1));
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloorY(org.bukkit.World, int, int, int, int, int)}.
*/
@Test
public void testGetFloorY() {
when(block.getType()).thenReturn(Material.GLASS, Material.GLASS,
Material.GLASS, Material.GLASS,
Material.GLASS, Material.GLASS,
Material.AIR);
assertEquals(8, walls.getFloorY(world, 10, 0, 1, 0, 1));
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#wallBlocks(org.bukkit.Material)}.
*/
@Test
public void testWallBlocks() {
assertFalse(Walls.wallBlocks(Material.ACACIA_BOAT));
assertTrue(Walls.wallBlocks(Material.GLASS));
assertTrue(Walls.wallBlocks(Material.ACACIA_DOOR));
assertTrue(Walls.wallBlocks(Material.HOPPER));
assertTrue(Walls.wallBlocks(Material.PURPLE_STAINED_GLASS_PANE));
assertFalse(Walls.wallBlocks(Material.BIRCH_TRAPDOOR));
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getFloor()}.
*/
@Test
public void testGetFloor() {
assertEquals(0, walls.getFloor());
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getWidth()}.
*/
@Test
public void testGetWidth() {
assertEquals(0, walls.getWidth());
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#getLength()}.
*/
@Test
public void testGetLength() {
assertEquals(0, walls.getLength());
}
/**
* Test method for {@link world.bentobox.greenhouses.greenhouse.Walls#toString()}.
*/
@Test
public void testToString() {
assertEquals("Walls [minX=0, maxX=0, minZ=0, maxZ=0, floor=0]", walls.toString());
}
}