Class MixedGenerator

java.lang.Object
squidpony.squidgrid.mapping.MixedGenerator
All Implemented Interfaces:
IDungeonGenerator
Direct Known Subclasses:
SymmetryDungeonGenerator

public class MixedGenerator
extends Object
implements IDungeonGenerator
A dungeon generator that can use a mix of techniques to have part-cave, part-room dungeons. Not entirely intended for normal use outside of this library, though it can be very useful when you want to make a dungeon match a specific path and existing generators that use MixedGenerator aren't sufficient. You may want to use a simpler generator based on this, like SerpentMapGenerator, which generates a long, winding path that loops around on itself. This supports the getEnvironment() method, which can be used in conjunction with RoomFinder to find where separate room, corridor, and cave areas have been placed.
Based on Michael Patraw's excellent Drunkard's Walk dungeon generator. http://mpatraw.github.io/libdrunkard/
See Also:
a normal use for MixedGenerator that makes winding dungeons, uses MixedGenerator as it makes a multi-level dungeon Created by Tommy Ettinger on 10/22/2015.
  • Field Summary

    Fields 
    Modifier and Type Field Description
    static int BOX  
    static int BOX_WALLED  
    protected double[] carvers  
    protected WeightedTable carverTable  
    static int CAVE  
    static int CAVE_FLOOR
    Constant for environment tiles that are floors for a cave.
    static int CAVE_WALL
    Constant for environment tiles that are walls near a cave.
    static int CORRIDOR_FLOOR
    Constant for environment tiles that are floors for a corridor.
    static int CORRIDOR_WALL
    Constant for environment tiles that are walls near a corridor.
    protected char[][] dungeon  
    protected int[][] environment  
    protected boolean[][] fixedRooms  
    protected boolean generated  
    protected int height  
    protected boolean[][] marked  
    protected IntVLA points  
    IRNG rng  
    static int ROOM_FLOOR
    Constant for environment tiles that are floors for a room.
    static int ROOM_WALL
    Constant for environment tiles that are walls near a room.
    protected float roomHeight  
    protected float roomWidth  
    static int ROUND  
    static int ROUND_WALLED  
    protected int totalPoints  
    static int UNTOUCHED
    Constant for environment tiles that are not near a cave, room, or corridor.
    protected boolean[][] walled  
    protected int width  
  • Constructor Summary

    Constructors 
    Constructor Description
    MixedGenerator​(int width, int height, IRNG rng)
    This prepares a map generator that will generate a map with the given width and height, using the given RNG.
    MixedGenerator​(int width, int height, IRNG rng, List<Coord> sequence)
    This prepares a map generator that will generate a map with the given width and height, using the given RNG.
    MixedGenerator​(int width, int height, IRNG rng, Map<Coord,​List<Coord>> connections)
    This prepares a map generator that will generate a map with the given width and height, using the given IRNG.
    MixedGenerator​(int width, int height, IRNG rng, Map<Coord,​List<Coord>> connections, float roomSizeMultiplier)
    This prepares a map generator that will generate a map with the given width and height, using the given IRNG.
  • Method Summary

    Modifier and Type Method Description
    static OrderedSet<Coord> basicPoints​(int width, int height, IRNG rng)
    Mainly for internal use; this is used by MixedGenerator(int, int, IRNG) to get its room positions.
    static List<Coord> cleanPoints​(int width, int height, IRNG rng)
    Mainly for internal use; this was used by MixedGenerator(int, int, IRNG) to get its room positions, and you can choose to use it with new MixedGenerator(width, height, rng, cleanPoints(width, height, rng)).
    char[][] generate()
    Uses the added carvers (or just makes caves if none were added) to carve from point to point in sequence, if it was provided by the constructor, or evenly-spaced randomized points if it was not.
    char[][] getDungeon()
    Gets the most recently-produced dungeon as a 2D char array, usually produced by calling IDungeonGenerator.generate() or some similar method present in a specific implementation.
    int[][] getEnvironment()  
    boolean[][] getFixedRooms()  
    boolean hasGenerated()  
    protected boolean mark​(int x, int y)
    Internal use.
    protected boolean mark​(Coord pos)
    Internal use.
    protected void markEnvironment​(int x, int y, int kind)
    Internal use.
    protected void markEnvironmentCave​(int x, int y)
    Internal use.
    protected void markEnvironmentCorridor​(int x, int y)
    Internal use.
    protected void markEnvironmentRoom​(int x, int y)
    Internal use.
    protected void markEnvironmentWalls()
    Internal use.
    protected void markPiercing​(int x, int y)
    Internal use.
    protected void markPiercing​(Coord pos)
    Internal use.
    protected void markPiercingCave​(Coord pos)
    Internal use.
    protected void markPiercingRoom​(int x, int y)
    Internal use.
    void putBoxRoomCarvers​(int count)
    Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a box shape at the start and end, and a small room at the corner if there is one.
    void putCaveCarvers​(int count)
    Changes the number of "carvers" that will create caves from one room to the next.
    void putRoundRoomCarvers​(int count)
    Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a circle shape at the start and end, and a small circular room at the corner if there is one.
    void putWalledBoxRoomCarvers​(int count)
    Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a box shape at the start and end, and a small room at the corner if there is one, enforcing the presence of walls around the rooms even if another room is already there or would be placed there.
    void putWalledRoundRoomCarvers​(int count)
    Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a circle shape at the start and end, and a small circular room at the corner if there is one, enforcing the presence of walls around the rooms even if another room is already there or would be placed there.
    void setFixedRooms​(boolean[][] fixedRooms)  
    protected void store()
    Internal use.
    protected void wallOff​(int x, int y)
    Internal use.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

  • Constructor Details

    • MixedGenerator

      public MixedGenerator​(int width, int height, IRNG rng)
      This prepares a map generator that will generate a map with the given width and height, using the given RNG. This version of the constructor uses a sub-random point sequence to generate the points it will draw caves and corridors between, helping to ensure a minimum distance between points, but it does not ensure that paths between points will avoid overlapping with rooms or other paths. You call the different carver-adding methods to affect what the dungeon will look like, putCaveCarvers(), putBoxRoomCarvers(), and putRoundRoomCarvers(), defaulting to only caves if none are called. You call generate() after adding carvers, which returns a char[][] for a map.
      Parameters:
      width - the width of the final map in cells
      height - the height of the final map in cells
      rng - an RNG object to use for random choices; this make a lot of random choices.
      See Also:
      used to ensure spacing for the points.
    • MixedGenerator

      public MixedGenerator​(int width, int height, IRNG rng, List<Coord> sequence)
      This prepares a map generator that will generate a map with the given width and height, using the given RNG. This version of the constructor uses a List of Coord points from some other source to determine the path to add rooms or caves to and then connect. You call the different carver-adding methods to affect what the dungeon will look like, putCaveCarvers(), putBoxRoomCarvers(), and putRoundRoomCarvers(), defaulting to only caves if none are called. You call generate() after adding carvers, which returns a char[][] for a map.
      Parameters:
      width - the width of the final map in cells
      height - the height of the final map in cells
      rng - an RNG object to use for random choices; this make a lot of random choices.
      sequence - a List of Coord to connect in order; index 0 is the start, index size() - 1 is the end.
      See Also:
      a class that uses this technique
    • MixedGenerator

      public MixedGenerator​(int width, int height, IRNG rng, Map<Coord,​List<Coord>> connections)
      This prepares a map generator that will generate a map with the given width and height, using the given IRNG. This version of the constructor uses a Map with Coord keys and Coord array values to determine a branching path for the dungeon to take; each key will connect once to each of the Coords in its value, and you usually don't want to connect in both directions. You call the different carver-adding methods to affect what the dungeon will look like, putCaveCarvers(), putBoxRoomCarvers(), and putRoundRoomCarvers(), defaulting to only caves if none are called. You call generate() after adding carvers, which returns a char[][] for a map.
      Parameters:
      width - the width of the final map in cells
      height - the height of the final map in cells
      rng - an IRNG object to use for random choices; this make a lot of random choices.
      connections - a Map of Coord keys to arrays of Coord to connect to next; shouldn't connect both ways
      See Also:
      a class that uses this technique
    • MixedGenerator

      public MixedGenerator​(int width, int height, IRNG rng, Map<Coord,​List<Coord>> connections, float roomSizeMultiplier)
      This prepares a map generator that will generate a map with the given width and height, using the given IRNG. This version of the constructor uses a Map with Coord keys and Coord array values to determine a branching path for the dungeon to take; each key will connect once to each of the Coords in its value, and you usually don't want to connect in both directions. You call the different carver-adding methods to affect what the dungeon will look like, putCaveCarvers(), putBoxRoomCarvers(), and putRoundRoomCarvers(), defaulting to only caves if none are called. You call generate() after adding carvers, which returns a char[][] for a map.
      Parameters:
      width - the width of the final map in cells
      height - the height of the final map in cells
      rng - an IRNG object to use for random choices; this make a lot of random choices.
      connections - a Map of Coord keys to arrays of Coord to connect to next; shouldn't connect both ways
      roomSizeMultiplier - a float multiplier that will be applied to each room's width and height
      See Also:
      a class that uses this technique
  • Method Details

    • basicPoints

      public static OrderedSet<Coord> basicPoints​(int width, int height, IRNG rng)
      Mainly for internal use; this is used by MixedGenerator(int, int, IRNG) to get its room positions. This is (and was) the default for generating a List of Coord if no other collection of Coord was supplied to the constructor. For some time this was not the default, and cleanPoints(int, int, IRNG) was used instead. Both are still options, but this technique seems to keep corridors shorter and makes connections between rooms more relevant to the current area.
      Preview map.
      Parameters:
      width - dungeon width in cells
      height - dungeon height in cells
      rng - rng to use
      Returns:
      evenly spaced Coord points in a list made by PoissonDisk, trimmed down so they aren't all used
      See Also:
      used to make the list
    • cleanPoints

      public static List<Coord> cleanPoints​(int width, int height, IRNG rng)
      Mainly for internal use; this was used by MixedGenerator(int, int, IRNG) to get its room positions, and you can choose to use it with new MixedGenerator(width, height, rng, cleanPoints(width, height, rng)). It produces a fairly rigid layout of rooms that should have less overlap between rooms and corridors; the downside to this is that corridors can become extremely long. The exact technique used here is to get points from a Halton-like sequence, formed using VanDerCorputQRNG to get a van der Corput sequence, for the x axis and a scrambled van der Corput sequence for the y axis. MixedGenerator will connect these points in pairs. The current method is much better at avoiding "clumps" of closely-positioned rooms in the center of the map.
      Preview maps, with and without box drawing characters. Note that one of the dungeons in that gist was produced as a fallback by DungeonGenerator with no arguments (using DEFAULT_DUNGEON as the dungeon style), because the map this method produced in one case had too few floor cells to be used.
      Parameters:
      width - dungeon width in cells; must be at least 3 because the edges will be walls
      height - dungeon height in cells; must be at least 3 because the edges will be walls
      rng - IRNG to use, such as an RNG, StatefulRNG, or GWTRNG
      Returns:
      erratically-positioned but generally separated Coord points to pass to a MixedGenerator constructor
      See Also:
      used to get separated positions
    • putCaveCarvers

      public void putCaveCarvers​(int count)
      Changes the number of "carvers" that will create caves from one room to the next. If count is 0 or less, no caves will be made. If count is at least 1, caves are possible, and higher numbers relative to the other carvers make caves more likely. Carvers are shuffled when used, then repeat if exhausted during generation. Since typically about 30-40 rooms are carved, large totals for carver count aren't really needed; aiming for a total of 10 between the count of putCaveCarvers(), putBoxRoomCarvers(), putRoundRoomCarvers(), putWalledBoxRoomCarvers(), and putWalledRoundRoomCarvers() is reasonable.
      Parameters:
      count - the number of carvers making caves between rooms; only matters in relation to other carvers
    • putBoxRoomCarvers

      public void putBoxRoomCarvers​(int count)
      Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a box shape at the start and end, and a small room at the corner if there is one. If count is 0 or less, no box-shaped rooms will be made. If count is at least 1, box-shaped rooms are possible, and higher numbers relative to the other carvers make box-shaped rooms more likely. Carvers are shuffled when used, then repeat if exhausted during generation. Since typically about 30-40 rooms are carved, large totals for carver count aren't really needed; aiming for a total of 10 between the count of putCaveCarvers(), putBoxRoomCarvers(), putRoundRoomCarvers(), putWalledBoxRoomCarvers(), and putWalledRoundRoomCarvers() is reasonable.
      Parameters:
      count - the number of carvers making box-shaped rooms and corridors between them; only matters in relation to other carvers
    • putRoundRoomCarvers

      public void putRoundRoomCarvers​(int count)
      Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a circle shape at the start and end, and a small circular room at the corner if there is one. If count is 0 or less, no circular rooms will be made. If count is at least 1, circular rooms are possible, and higher numbers relative to the other carvers make circular rooms more likely. Carvers are shuffled when used, then repeat if exhausted during generation. Since typically about 30-40 rooms are carved, large totals for carver count aren't really needed; aiming for a total of 10 between the count of putCaveCarvers(), putBoxRoomCarvers(), putRoundRoomCarvers(), putWalledBoxRoomCarvers(), and putWalledRoundRoomCarvers() is reasonable.
      Parameters:
      count - the number of carvers making circular rooms and corridors between them; only matters in relation to other carvers
    • putWalledBoxRoomCarvers

      public void putWalledBoxRoomCarvers​(int count)
      Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a box shape at the start and end, and a small room at the corner if there is one, enforcing the presence of walls around the rooms even if another room is already there or would be placed there. Corridors can always pass through enforced walls, but caves will open at most one cell in the wall. If count is 0 or less, no box-shaped rooms will be made. If count is at least 1, box-shaped rooms are possible, and higher numbers relative to the other carvers make box-shaped rooms more likely. Carvers are shuffled when used, then repeat if exhausted during generation. Since typically about 30-40 rooms are carved, large totals for carver count aren't really needed; aiming for a total of 10 between the count of putCaveCarvers(), putBoxRoomCarvers(), putRoundRoomCarvers(), putWalledBoxRoomCarvers(), and putWalledRoundRoomCarvers() is reasonable.
      Parameters:
      count - the number of carvers making box-shaped rooms and corridors between them; only matters in relation to other carvers
    • putWalledRoundRoomCarvers

      public void putWalledRoundRoomCarvers​(int count)
      Changes the number of "carvers" that will create right-angle corridors from one room to the next, create rooms with a random size in a circle shape at the start and end, and a small circular room at the corner if there is one, enforcing the presence of walls around the rooms even if another room is already there or would be placed there. Corridors can always pass through enforced walls, but caves will open at most one cell in the wall. If count is 0 or less, no circular rooms will be made. If count is at least 1, circular rooms are possible, and higher numbers relative to the other carvers make circular rooms more likely. Carvers are shuffled when used, then repeat if exhausted during generation. Since typically about 30-40 rooms are carved, large totals for carver count aren't really needed; aiming for a total of 10 between the count of putCaveCarvers(), putBoxRoomCarvers(), putRoundRoomCarvers(), putWalledBoxRoomCarvers(), and putWalledRoundRoomCarvers() is reasonable.
      Parameters:
      count - the number of carvers making circular rooms and corridors between them; only matters in relation to other carvers
    • generate

      public char[][] generate()
      Uses the added carvers (or just makes caves if none were added) to carve from point to point in sequence, if it was provided by the constructor, or evenly-spaced randomized points if it was not. This will never carve out cells on the very edge of the map. Uses the numbers of the various kinds of carver that were added relative to each other to determine how frequently to use a given carver type.
      Specified by:
      generate in interface IDungeonGenerator
      Returns:
      a char[][] where '#' is a wall and '.' is a floor or corridor; x first y second
    • getDungeon

      public char[][] getDungeon()
      Description copied from interface: IDungeonGenerator
      Gets the most recently-produced dungeon as a 2D char array, usually produced by calling IDungeonGenerator.generate() or some similar method present in a specific implementation. This normally passes a direct reference and not a copy, so you can normally modify the returned array to propagate changes back into this IDungeonGenerator.
      Specified by:
      getDungeon in interface IDungeonGenerator
      Returns:
      the most recently-produced dungeon/map as a 2D char array
    • getEnvironment

      public int[][] getEnvironment()
    • hasGenerated

      public boolean hasGenerated()
    • getFixedRooms

      public boolean[][] getFixedRooms()
    • setFixedRooms

      public void setFixedRooms​(boolean[][] fixedRooms)
    • store

      protected void store()
      Internal use. Takes cells that have been previously marked and permanently stores them as floors in the dungeon.
    • markEnvironmentWalls

      protected void markEnvironmentWalls()
      Internal use. Finds all floor cells by environment and marks untouched adjacent (8-way) cells as walls, using the appropriate type for the nearby floor.
    • mark

      protected boolean mark​(int x, int y)
      Internal use. Marks a point to be made into floor.
      Parameters:
      x - x position to mark
      y - y position to mark
      Returns:
      false if everything is normal, true if and only if this failed to mark because the position is walled
    • markPiercing

      protected void markPiercing​(int x, int y)
      Internal use. Marks a point to be made into floor.
      Parameters:
      x - x position to mark
      y - y position to mark
    • markEnvironment

      protected void markEnvironment​(int x, int y, int kind)
      Internal use. Marks a point's environment type as the appropriate kind of environment.
      Parameters:
      x - x position to mark
      y - y position to mark
      kind - an int that should be one of the constants in MixedGenerator for environment types.
    • markEnvironmentCorridor

      protected void markEnvironmentCorridor​(int x, int y)
      Internal use. Marks a point's environment type as a corridor floor.
      Parameters:
      x - x position to mark
      y - y position to mark
    • markEnvironmentRoom

      protected void markEnvironmentRoom​(int x, int y)
      Internal use. Marks a point's environment type as a room floor.
      Parameters:
      x - x position to mark
      y - y position to mark
    • markEnvironmentCave

      protected void markEnvironmentCave​(int x, int y)
      Internal use. Marks a point's environment type as a cave floor.
      Parameters:
      x - x position to mark
      y - y position to mark
    • wallOff

      protected void wallOff​(int x, int y)
      Internal use. Marks a point to be considered a hard wall.
      Parameters:
      x - x position to mark
      y - y position to mark
    • mark

      protected boolean mark​(Coord pos)
      Internal use. Marks a point to be made into floor.
      Parameters:
      pos - position to mark
      Returns:
      false if everything is normal, true if and only if this failed to mark because the position is walled
    • markPiercing

      protected void markPiercing​(Coord pos)
      Internal use. Marks a point to be made into floor, piercing walls.
      Parameters:
      pos - position to mark
    • markPiercingCave

      protected void markPiercingCave​(Coord pos)
      Internal use. Marks a point to be made into floor, piercing walls, and also marks the point as a cave floor.
      Parameters:
      pos - position to mark
    • markPiercingRoom

      protected void markPiercingRoom​(int x, int y)
      Internal use. Marks a point to be made into floor, piercing walls, and also marks the point as a room floor.
      Parameters:
      x - x coordinate of position to mark
      y - y coordinate of position to mark