From f3aab596aaeeb17983d48309da029155c0f3857b Mon Sep 17 00:00:00 2001 From: ondra Date: Mon, 28 Apr 2014 14:23:44 +0200 Subject: [PATCH] rollback of failed algo for exploring. --- src/mightypork/rogue/world/level/Level.java | 32 +++++++++---- .../rogue/world/pathfinding/FillContext.java | 6 +++ .../rogue/world/pathfinding/FloodFill.java | 46 +++++++++++-------- src/mightypork/rogue/world/tile/Tile.java | 5 +- 4 files changed, 60 insertions(+), 29 deletions(-) diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 8697ff4..40d682e 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -52,13 +52,11 @@ public class Level implements MapAccess, IonBinary { private transient NoiseGen noiseGen; - public Level() - { + public Level() { } - public Level(int width, int height) - { + public Level(int width, int height) { size.setTo(width, height); buildArray(); } @@ -90,7 +88,7 @@ public class Level implements MapAccess, IonBinary { public final Tile getTile(Coord pos) { if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) return Tiles.NULL.createTile(); // out of range - + return tiles[pos.y][pos.x]; } @@ -324,8 +322,18 @@ public class Level implements MapAccess, IonBinary { public void explore(Coord center) { - Collection filled = FloodFill.fill(center, exploreFc); - for(Coord c : filled) getTile(c).setExplored(); + // fully explored == explored & limit was not reached; + // -> optimization for closed rooms. + + Tile t = getTile(center); + + Collection filled = new HashSet<>(); + + FloodFill.fill(center, exploreFc, filled); + + for (Coord c : filled) { + getTile(c).setExplored(); + } } private FillContext exploreFc = new FillContext() { @@ -340,7 +348,7 @@ public class Level implements MapAccess, IonBinary { @Override public double getMaxDistance() { - return 6; + return 5; } @@ -355,7 +363,13 @@ public class Level implements MapAccess, IonBinary { @Override public boolean canEnter(Coord pos) { - return !getTile(pos).isNull(); + Tile t = getTile(pos); + return !t.isNull(); + } + + @Override + public boolean forceSpreadStart() { + return true; } }; } diff --git a/src/mightypork/rogue/world/pathfinding/FillContext.java b/src/mightypork/rogue/world/pathfinding/FillContext.java index 1f6c1d8..01775c1 100644 --- a/src/mightypork/rogue/world/pathfinding/FillContext.java +++ b/src/mightypork/rogue/world/pathfinding/FillContext.java @@ -19,4 +19,10 @@ public interface FillContext { * @return max distance */ double getMaxDistance(); + + + /** + * @return true if start should be spread no matter what + */ + boolean forceSpreadStart(); } diff --git a/src/mightypork/rogue/world/pathfinding/FloodFill.java b/src/mightypork/rogue/world/pathfinding/FloodFill.java index 0c2dc88..ec1c402 100644 --- a/src/mightypork/rogue/world/pathfinding/FloodFill.java +++ b/src/mightypork/rogue/world/pathfinding/FloodFill.java @@ -1,51 +1,59 @@ package mightypork.rogue.world.pathfinding; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import java.util.Stack; +import java.util.*; import mightypork.rogue.world.Coord; public class FloodFill { - public static final Collection fill(Coord start, FillContext context) + /** + * Fill an area + * @param start start point + * @param context filling context + * @param foundNodes collection to put filled coords in + * @return true if fill was successful; false if max range was reached. + */ + public static final boolean fill(Coord start, FillContext context, Collection foundNodes) { - Set filled = new HashSet<>(); - Stack active = new Stack<>(); + Queue activeNodes = new LinkedList<>(); double maxDist = context.getMaxDistance(); - active.push(start); + activeNodes.add(start); Coord[] sides = context.getSpreadSides(); - boolean first = true; + boolean forceSpreadNext = context.forceSpreadStart(); - while (!active.isEmpty()) { - Coord current = active.pop(); - filled.add(current); + boolean limitReached = false; + + while (!activeNodes.isEmpty()) { + Coord current = activeNodes.poll(); + foundNodes.add(current); - if(!context.canSpreadFrom(current) && !first) continue; + if(!context.canSpreadFrom(current) && !forceSpreadNext) continue; - first = false; + forceSpreadNext = false; for (Coord spr : sides) { Coord next = current.add(spr); - if(active.contains(next) || filled.contains(next)) continue; + if(activeNodes.contains(next) || foundNodes.contains(next)) continue; - if (next.dist(start) > maxDist) continue; + if (next.dist(start) > maxDist) { + limitReached = true; + continue; + } if (context.canEnter(next)) { - active.push(next); + activeNodes.add(next); } else { - filled.add(next); + foundNodes.add(next); } } } - return filled; + return !limitReached; } } diff --git a/src/mightypork/rogue/world/tile/Tile.java b/src/mightypork/rogue/world/tile/Tile.java index 85c1520..ce7b8ae 100644 --- a/src/mightypork/rogue/world/tile/Tile.java +++ b/src/mightypork/rogue/world/tile/Tile.java @@ -65,7 +65,9 @@ public abstract class Tile implements IonBinaryHeadless { * @param context */ @DefaultImpl - public void renderExtra(TileRenderContext context) {} + public void renderExtra(TileRenderContext context) + { + } @Override @@ -185,6 +187,7 @@ public abstract class Tile implements IonBinaryHeadless { /** * Remove an item from this tile + * * @return the picked item, or null if none */ public abstract Item pickItem();