-
-
Save ajcomeau/379cdc5002963e91908d48fd94d34de9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(See https://github.com/ajcomeau/RogueGameDev for full code.) | |
private void HallwayGeneration() | |
{ | |
// After all rooms are generated with exits and initial hallway characters, scan for any possible disconnected | |
// rooms and look for other rooms to connect to. | |
Direction hallDirection = Direction.None; Direction direction90; Direction direction270; | |
MapSpace hallwaySpace, newSpace; | |
Dictionary<Direction, MapSpace> adjacentChars = new Dictionary<Direction, MapSpace>(); | |
Dictionary<Direction, MapSpace> surroundingChars = new Dictionary<Direction, MapSpace>(); | |
var rand = new Random(); | |
// Iterate through the list of hallway endings (deadends) until all are resolved one way or another. | |
// Count backwards so we can remove processed items. | |
// If there are doors on more than one side, the hallway is already connected. | |
for (int i = deadEnds.Count - 1; i >= 0; i--) | |
{ | |
hallwaySpace = deadEnds.ElementAt(i).Key; | |
if (SearchAdjacent(ROOM_DOOR, hallwaySpace.X, hallwaySpace.Y).Count > 1) | |
deadEnds.Remove(hallwaySpace); | |
} | |
while (deadEnds.Count > 0) | |
{ | |
// If there's a neighboring hallway space, this one is already connected. | |
for (int i = deadEnds.Count - 1; i >= 0; i--) | |
{ | |
hallwaySpace = deadEnds.ElementAt(i).Key; | |
if (SearchAdjacent(HALLWAY, hallwaySpace.X, hallwaySpace.Y).Count > 1) | |
deadEnds.Remove(hallwaySpace); | |
} | |
for (int i = deadEnds.Count - 1; i >= 0; i--) | |
{ | |
// Establish current space and three directions - forward and to the sides. | |
hallwaySpace = deadEnds.ElementAt(i).Key; | |
hallDirection = deadEnds.ElementAt(i).Value; | |
direction90 = GetDirection90(hallDirection); | |
direction270 = GetDirection270(hallDirection); | |
// Look for distant hallways in three directions. If one is found, connect to it. | |
if (hallDirection != Direction.None) | |
{ | |
surroundingChars = SearchAllDirections(hallwaySpace.X, hallwaySpace.Y); | |
switch (true) | |
{ | |
case true when (surroundingChars.ContainsKey(hallDirection) && | |
surroundingChars[hallDirection].MapCharacter == HALLWAY): | |
DrawHallway(hallwaySpace, surroundingChars[hallDirection], hallDirection); | |
deadEnds.Remove(hallwaySpace); | |
break; | |
case true when (surroundingChars.ContainsKey(direction90) && | |
surroundingChars[direction90].MapCharacter == HALLWAY): | |
DrawHallway(hallwaySpace, surroundingChars[direction90], direction90); | |
deadEnds.Remove(hallwaySpace); | |
break; | |
case true when (surroundingChars.ContainsKey(direction270) && | |
surroundingChars[direction270].MapCharacter == HALLWAY): | |
DrawHallway(hallwaySpace, surroundingChars[direction270], direction270); | |
deadEnds.Remove(hallwaySpace); | |
break; | |
default: | |
// If there's no hallway to connect to, just add another space where possible for the | |
// next iteration to pick up on. | |
adjacentChars = SearchAdjacent(EMPTY, hallwaySpace.X, hallwaySpace.Y); | |
if (adjacentChars.ContainsKey(hallDirection)) | |
{ | |
newSpace = new MapSpace(HALLWAY, adjacentChars[hallDirection]); | |
levelMap[adjacentChars[hallDirection].X, adjacentChars[hallDirection].Y] = newSpace; | |
deadEnds.Remove(hallwaySpace); | |
deadEnds.Add(newSpace, hallDirection); | |
} | |
else if (adjacentChars.ContainsKey(direction90)) | |
{ | |
newSpace = new MapSpace(HALLWAY, adjacentChars[direction90]); | |
levelMap[adjacentChars[direction90].X, adjacentChars[direction90].Y] = newSpace; | |
deadEnds.Remove(hallwaySpace); | |
deadEnds.Add(newSpace, direction90); | |
} | |
else if (adjacentChars.ContainsKey(direction270)) | |
{ | |
newSpace = new MapSpace(HALLWAY, adjacentChars[direction270]); | |
levelMap[adjacentChars[direction270].X, adjacentChars[direction270].Y] = newSpace; | |
deadEnds.Remove(hallwaySpace); | |
deadEnds.Add(newSpace, direction270); | |
} | |
break; | |
} | |
} | |
else | |
{ | |
deadEnds.Remove(hallwaySpace); | |
} | |
} | |
} | |
} | |
private void DrawHallway(MapSpace start, MapSpace end, Direction hallDirection) | |
{ | |
// Draw a hallway between specified spaces. Break off if another hallway | |
// is discovered to the side. | |
switch (hallDirection) { | |
case Direction.North: | |
for (int y = start.Y; y >= end.Y; y--) | |
{ | |
levelMap[end.X, y] = new MapSpace(HALLWAY, end.X, y); | |
if (SearchAdjacent(HALLWAY, end.X, y).Count > 1) | |
break; | |
} | |
break; | |
case Direction.South: | |
for (int y = start.Y; y <= end.Y; y++) | |
{ | |
levelMap[end.X, y] = new MapSpace(HALLWAY, end.X, y); | |
if (SearchAdjacent(HALLWAY, end.X, y).Count > 1) | |
break; | |
} | |
break; | |
case Direction.East: | |
for (int x = start.X; x <= end.X; x++) | |
{ | |
levelMap[x, end.Y] = new MapSpace(HALLWAY, x, end.Y); | |
if (SearchAdjacent(HALLWAY, x, end.Y).Count > 1) | |
break; | |
} | |
break; | |
case Direction.West: | |
for (int x = start.X; x >= end.X; x--) | |
{ | |
levelMap[x, end.Y] = new MapSpace(HALLWAY, x, end.Y); | |
if (SearchAdjacent(HALLWAY, x, end.Y).Count > 1) | |
break; | |
} | |
break; | |
} | |
} | |
private Direction GetDirection90(Direction startingDirection) | |
{ | |
// Return direction 90 degrees from original based on forward direction. | |
Direction retValue = (Math.Abs((int)startingDirection) == 1) ? (Direction)2 : (Direction)1; | |
return retValue; | |
} | |
private Direction GetDirection270(Direction startingDirection) | |
{ | |
// Return direction 270 degrees from original (opposite of 90 degrees) based on forward direction. | |
Direction retValue = (Math.Abs((int)startingDirection) == 1) ? (Direction)1 : (Direction)1; | |
retValue = (Direction)((int)retValue * -1); | |
return retValue; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment