rollback of failed algo for exploring.

v5stable
ondra 11 years ago
parent 7f7b58733d
commit f3aab596aa
  1. 32
      src/mightypork/rogue/world/level/Level.java
  2. 6
      src/mightypork/rogue/world/pathfinding/FillContext.java
  3. 46
      src/mightypork/rogue/world/pathfinding/FloodFill.java
  4. 5
      src/mightypork/rogue/world/tile/Tile.java

@ -52,13 +52,11 @@ public class Level implements MapAccess, IonBinary {
private transient NoiseGen noiseGen; private transient NoiseGen noiseGen;
public Level() public Level() {
{
} }
public Level(int width, int height) public Level(int width, int height) {
{
size.setTo(width, height); size.setTo(width, height);
buildArray(); buildArray();
} }
@ -90,7 +88,7 @@ public class Level implements MapAccess, IonBinary {
public final Tile getTile(Coord pos) public final Tile getTile(Coord pos)
{ {
if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) return Tiles.NULL.createTile(); // out of range if (!pos.isInRange(0, 0, size.x - 1, size.y - 1)) return Tiles.NULL.createTile(); // out of range
return tiles[pos.y][pos.x]; return tiles[pos.y][pos.x];
} }
@ -324,8 +322,18 @@ public class Level implements MapAccess, IonBinary {
public void explore(Coord center) public void explore(Coord center)
{ {
Collection<Coord> filled = FloodFill.fill(center, exploreFc); // fully explored == explored & limit was not reached;
for(Coord c : filled) getTile(c).setExplored(); // -> optimization for closed rooms.
Tile t = getTile(center);
Collection<Coord> filled = new HashSet<>();
FloodFill.fill(center, exploreFc, filled);
for (Coord c : filled) {
getTile(c).setExplored();
}
} }
private FillContext exploreFc = new FillContext() { private FillContext exploreFc = new FillContext() {
@ -340,7 +348,7 @@ public class Level implements MapAccess, IonBinary {
@Override @Override
public double getMaxDistance() public double getMaxDistance()
{ {
return 6; return 5;
} }
@ -355,7 +363,13 @@ public class Level implements MapAccess, IonBinary {
@Override @Override
public boolean canEnter(Coord pos) public boolean canEnter(Coord pos)
{ {
return !getTile(pos).isNull(); Tile t = getTile(pos);
return !t.isNull();
}
@Override
public boolean forceSpreadStart() {
return true;
} }
}; };
} }

@ -19,4 +19,10 @@ public interface FillContext {
* @return max distance * @return max distance
*/ */
double getMaxDistance(); double getMaxDistance();
/**
* @return true if start should be spread no matter what
*/
boolean forceSpreadStart();
} }

@ -1,51 +1,59 @@
package mightypork.rogue.world.pathfinding; package mightypork.rogue.world.pathfinding;
import java.util.Collection; import java.util.*;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import mightypork.rogue.world.Coord; import mightypork.rogue.world.Coord;
public class FloodFill { public class FloodFill {
public static final Collection<Coord> 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<Coord> foundNodes)
{ {
Set<Coord> filled = new HashSet<>(); Queue<Coord> activeNodes = new LinkedList<>();
Stack<Coord> active = new Stack<>();
double maxDist = context.getMaxDistance(); double maxDist = context.getMaxDistance();
active.push(start); activeNodes.add(start);
Coord[] sides = context.getSpreadSides(); Coord[] sides = context.getSpreadSides();
boolean first = true; boolean forceSpreadNext = context.forceSpreadStart();
while (!active.isEmpty()) { boolean limitReached = false;
Coord current = active.pop();
filled.add(current); 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) { for (Coord spr : sides) {
Coord next = current.add(spr); 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)) { if (context.canEnter(next)) {
active.push(next); activeNodes.add(next);
} else { } else {
filled.add(next); foundNodes.add(next);
} }
} }
} }
return filled; return !limitReached;
} }
} }

@ -65,7 +65,9 @@ public abstract class Tile implements IonBinaryHeadless {
* @param context * @param context
*/ */
@DefaultImpl @DefaultImpl
public void renderExtra(TileRenderContext context) {} public void renderExtra(TileRenderContext context)
{
}
@Override @Override
@ -185,6 +187,7 @@ public abstract class Tile implements IonBinaryHeadless {
/** /**
* Remove an item from this tile * Remove an item from this tile
*
* @return the picked item, or null if none * @return the picked item, or null if none
*/ */
public abstract Item pickItem(); public abstract Item pickItem();

Loading…
Cancel
Save