Class MixedGenerator

java.lang.Object
com.github.yellowstonegames.place.MixedGenerator
All Implemented Interfaces:
PlaceGenerator
Direct Known Subclasses:
SymmetryDungeonGenerator

public class MixedGenerator extends Object implements PlaceGenerator
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.
See Also:
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
     
    static final int
     
    protected float[]
     
    protected com.github.yellowstonegames.core.WeightedTable
     
    static final int
     
    protected char[][]
     
    protected int[][]
     
    protected boolean[][]
     
    protected boolean
     
    protected int
     
    protected boolean[][]
     
    protected com.github.tommyettinger.ds.IntList
     
    com.github.tommyettinger.random.EnhancedRandom
     
    protected float
     
    protected float
     
    static final int
     
    static final int
     
    protected int
     
    protected boolean[][]
     
    protected int
     
  • Constructor Summary

    Constructors
    Constructor
    Description
    This prepares a map generator that will generate a map with width 80 and height 80, using a random seed.
    MixedGenerator(int width, int height, com.github.tommyettinger.random.EnhancedRandom 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, com.github.tommyettinger.random.EnhancedRandom rng, List<com.github.yellowstonegames.grid.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, com.github.tommyettinger.random.EnhancedRandom rng, Map<com.github.yellowstonegames.grid.Coord, ? extends List<com.github.yellowstonegames.grid.Coord>> connections)
    This prepares a map generator that will generate a map with the given width and height, using the given EnhancedRandom.
    MixedGenerator(int width, int height, com.github.tommyettinger.random.EnhancedRandom rng, Map<com.github.yellowstonegames.grid.Coord, ? extends List<com.github.yellowstonegames.grid.Coord>> connections, float roomSizeMultiplier)
    This prepares a map generator that will generate a map with the given width and height, using the given EnhancedRandom.
  • Method Summary

    Modifier and Type
    Method
    Description
    static com.github.yellowstonegames.grid.CoordObjectOrderedMap<com.github.tommyettinger.ds.ObjectList<com.github.yellowstonegames.grid.Coord>>
    basicPoints(int width, int height, com.github.tommyettinger.random.EnhancedRandom rng)
    Mainly for internal use; this is used by MixedGenerator(int, int, EnhancedRandom) to get its room positions.
    char[][]
    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.
    int[][]
    Gets the most recently-produced place's environment as a 2D int array, where each int is typically a constant in DungeonTools like DungeonTools.NATURAL_WALL or DungeonTools.ROOM_FLOOR.
    boolean[][]
     
    char[][]
    Gets the most recently-produced place as a 2D char array, usually produced by calling PlaceGenerator.generate() or some similar method present in a specific implementation.
    boolean
     
    protected boolean
    mark(int x, int y)
    Internal use.
    protected boolean
    mark(com.github.yellowstonegames.grid.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
    Internal use.
    protected void
    markPiercing(int x, int y)
    Internal use.
    protected void
    markPiercing(com.github.yellowstonegames.grid.Coord pos)
    Internal use.
    protected void
    markPiercingCave(com.github.yellowstonegames.grid.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
    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
    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
    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
    Internal use.
     
    protected void
    wallOff(int x, int y)
    Internal use.

    Methods inherited from class Object

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

    • CAVE

      public static final int CAVE
      See Also:
    • BOX

      public static final int BOX
      See Also:
    • ROUND

      public static final int ROUND
      See Also:
    • BOX_WALLED

      public static final int BOX_WALLED
      See Also:
    • ROUND_WALLED

      public static final int ROUND_WALLED
      See Also:
    • carvers

      protected float[] carvers
    • carverTable

      protected com.github.yellowstonegames.core.WeightedTable carverTable
    • width

      protected int width
    • height

      protected int height
    • roomWidth

      protected float roomWidth
    • roomHeight

      protected float roomHeight
    • rng

      public com.github.tommyettinger.random.EnhancedRandom rng
    • dungeon

      protected char[][] dungeon
    • generated

      protected boolean generated
    • environment

      protected int[][] environment
    • marked

      protected boolean[][] marked
    • walled

      protected boolean[][] walled
    • fixedRooms

      protected boolean[][] fixedRooms
    • points

      protected com.github.tommyettinger.ds.IntList points
    • totalPoints

      protected int totalPoints
  • Constructor Details

    • MixedGenerator

      public MixedGenerator()
      This prepares a map generator that will generate a map with width 80 and height 80, using a random seed. 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.
    • MixedGenerator

      public MixedGenerator(int width, int height, com.github.tommyettinger.random.EnhancedRandom 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, com.github.tommyettinger.random.EnhancedRandom rng, List<com.github.yellowstonegames.grid.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.
    • MixedGenerator

      public MixedGenerator(int width, int height, com.github.tommyettinger.random.EnhancedRandom rng, Map<com.github.yellowstonegames.grid.Coord, ? extends List<com.github.yellowstonegames.grid.Coord>> connections)
      This prepares a map generator that will generate a map with the given width and height, using the given EnhancedRandom. 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 EnhancedRandom object to use for random choices; this makes a lot of random choices.
      connections - a Map of Coord keys to arrays of Coord to connect to next; shouldn't connect both ways
    • MixedGenerator

      public MixedGenerator(int width, int height, com.github.tommyettinger.random.EnhancedRandom rng, Map<com.github.yellowstonegames.grid.Coord, ? extends List<com.github.yellowstonegames.grid.Coord>> connections, float roomSizeMultiplier)
      This prepares a map generator that will generate a map with the given width and height, using the given EnhancedRandom. 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 EnhancedRandom object to use for random choices; this makes 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
  • Method Details

    • basicPoints

      public static com.github.yellowstonegames.grid.CoordObjectOrderedMap<com.github.tommyettinger.ds.ObjectList<com.github.yellowstonegames.grid.Coord>> basicPoints(int width, int height, com.github.tommyettinger.random.EnhancedRandom rng)
      Mainly for internal use; this is used by MixedGenerator(int, int, EnhancedRandom) to get its room positions. This is the default for generating a List of Coord if no other collection of Coord was supplied to the constructor.
      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
    • 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 PlaceGenerator
      Returns:
      a char[][] where '#' is a wall and '.' is a floor or corridor; x first y second
    • getPlaceGrid

      public char[][] getPlaceGrid()
      Description copied from interface: PlaceGenerator
      Gets the most recently-produced place as a 2D char array, usually produced by calling PlaceGenerator.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 IPlaceGenerator.
      Specified by:
      getPlaceGrid in interface PlaceGenerator
      Returns:
      the most recently-produced dungeon/place as a 2D char array
    • getEnvironment

      public int[][] getEnvironment()
      Description copied from interface: PlaceGenerator
      Gets the most recently-produced place's environment as a 2D int array, where each int is typically a constant in DungeonTools like DungeonTools.NATURAL_WALL or DungeonTools.ROOM_FLOOR.
      Specified by:
      getEnvironment in interface PlaceGenerator
      Returns:
      the environment of the most recently-produced place, as a 2D int array
    • 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(com.github.yellowstonegames.grid.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(com.github.yellowstonegames.grid.Coord pos)
      Internal use. Marks a point to be made into floor, piercing walls.
      Parameters:
      pos - position to mark
    • markPiercingCave

      protected void markPiercingCave(com.github.yellowstonegames.grid.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
    • toString

      public String toString()
      Overrides:
      toString in class Object