private Hall CreateHall(Room room, Door door) { //Calculate the position of the first segment List <Position> segments = new List <Position>(); Position start = new Position(room.Location); int hallLength = _randomizer.ChooseCount(2, 10); Hall result; switch (door.Wall) { case Direction.North: { start.Row--; start.Column += door.Position - 1; break; } case Direction.West: { start.Row += door.Position - 1; start.Column += room.Size.Length + 1; break; } case Direction.East: { start.Row += door.Position - 1; start.Column--; break; } case Direction.South: { start.Row += room.Size.Width + 1; start.Column += door.Position - 1; break; } default: throw new ApplicationException(string.Format("Unknown direction for wall {0}", door.Wall)); } bool hallSuccess = false; segments.Add(start); hallLength--; for (int retry = 0; retry < MaxPlacementRetries; retry++) { Position prevSegment = start; Direction backtrackDirection = GetOppositeDirection(door.Wall); Direction prevBacktrackDirection = backtrackDirection; if (segments.Count == hallLength + 1) { //success! hallSuccess = true; break; } for (int i = 0; i < hallLength; i++) { Direction nextDirection; Position nextSegment = new Position(prevSegment); do { nextDirection = _randomizer.ChooseDirection(); } while (nextDirection == backtrackDirection || nextDirection == prevBacktrackDirection); switch (nextDirection) { case Direction.North: nextSegment.Row--; break; case Direction.West: nextSegment.Column++; break; case Direction.East: nextSegment.Column--; break; case Direction.South: nextSegment.Row++; break; default: throw new ApplicationException(string.Format("Unknown next direction for hall {0}", door.Wall)); } if (CanPlaceHallSegment(nextSegment) == false) { //reset the entire hall and retry segments.Clear(); segments.Add(start); break; } else { prevSegment = nextSegment; prevBacktrackDirection = GetOppositeDirection(nextDirection); segments.Add(nextSegment); } } } if (hallSuccess == true) { //hall was successfully placed create it result = new Hall(GetNextHallName()); result.StartRoomName = room.Name; result.Segments = segments.ToArray(); door.ConnectedHallName = result.Name; } else { //hall could not be placed return null result = null; } return(result); }