From 5f8e8fae9960280837f13a5fff5fd8dca0105524 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 11 Oct 2020 09:03:13 -0700 Subject: [PATCH] Refactored Walls and added test class --- .../greenhouses/greenhouse/Walls.java | 187 +++++++------- .../managers/GreenhouseFinder.java | 2 +- .../greenhouses/greenhouse/WallsTest.java | 231 ++++++++++++++++++ 3 files changed, 336 insertions(+), 84 deletions(-) create mode 100644 src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java diff --git a/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java b/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java index 1e68d63..bd7c271 100644 --- a/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java +++ b/src/main/java/world/bentobox/greenhouses/greenhouse/Walls.java @@ -29,98 +29,35 @@ public class Walls extends MinMaxXZ { private static final List 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 { diff --git a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java index 24bc7f6..e70556f 100644 --- a/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java +++ b/src/main/java/world/bentobox/greenhouses/managers/GreenhouseFinder.java @@ -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 diff --git a/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java b/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java new file mode 100644 index 0000000..67e5adf --- /dev/null +++ b/src/test/java/world/bentobox/greenhouses/greenhouse/WallsTest.java @@ -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()); + } + +}