001package fr.aumgn.dac2.game.colonnisation; 002 003import java.util.ArrayDeque; 004import java.util.Deque; 005import java.util.HashSet; 006import java.util.Set; 007 008import org.bukkit.World; 009import org.bukkit.block.Block; 010 011import fr.aumgn.bukkitutils.geom.Vector2D; 012import fr.aumgn.dac2.arena.Arena; 013import fr.aumgn.dac2.arena.regions.Pool; 014import fr.aumgn.dac2.config.Color; 015import fr.aumgn.dac2.shape.FlatShape; 016 017public class PoolVisitor { 018 019 private final Color color; 020 private final World world; 021 private final FlatShape shape; 022 private final int y; 023 private final Set<Vector2D> visited; 024 private final Deque<Vector2D> queue; 025 026 private int count; 027 028 public PoolVisitor(Arena arena, Color color) { 029 this(arena.getWorld(), arena.getPool(), color); 030 } 031 032 public PoolVisitor(World world, Pool pool, Color color) { 033 this.color = color; 034 this.world = world; 035 this.shape = pool.getShape(); 036 this.y = (int) shape.getMaxY() - 1; 037 this.visited = new HashSet<Vector2D>(); 038 this.queue = new ArrayDeque<Vector2D>(); 039 040 } 041 042 public int visit(Vector2D pos) { 043 visited.clear(); 044 queue.clear(); 045 count = 0; 046 047 visited.add(pos); 048 pushNeighbors(pos); 049 while (!queue.isEmpty()) { 050 visit(); 051 } 052 053 return count + 1; 054 } 055 056 private boolean isValid(Vector2D pos) { 057 if (!shape.contains2D(pos)) { 058 return false; 059 } 060 061 return isValidBlock(pos); 062 } 063 064 private boolean isValidBlock(Vector2D pos) { 065 Block block = pos.to3D(y).toBlock(world); 066 return block.getType() == color.block && block.getData() == color.data; 067 } 068 069 private void visit() { 070 Vector2D pos = queue.poll(); 071 if (visited.contains(pos)) { 072 return; 073 } 074 075 visited.add(pos); 076 if (!isValid(pos)) { 077 return; 078 } 079 080 count++; 081 pushNeighbors(pos); 082 } 083 084 private void pushNeighbors(Vector2D pos) { 085 queue.add(pos.subtractX(1)); 086 queue.add(pos.addX(1)); 087 queue.add(pos.subtractZ(1)); 088 queue.add(pos.addZ(1)); 089 } 090}