private IEnumerable <RoomPrototype> GetPossibleRoomsForConnection(RoomPrototypeConnection baseConnection, DungeonNode nextStructureElement)
        {
            var baseRoom = baseConnection.ParentRoomPrototype;

            foreach (var newRoom in GetRandomOrderedRooms(nextStructureElement))
            {
                IEnumerable <RoomConnector> possibleNextConnections = newRoom
                                                                      .GetConnections()
                                                                      .Where(x => x.size.Equals(baseConnection.ParentConnection.size) && x.type == baseConnection.ParentConnection.type)
                                                                      .ToList().Shuffle(_random);

                foreach (var nextRoomConnection in possibleNextConnections)
                {
                    var nextRoomConnectionTransform = nextRoomConnection.transform;
                    var selectedConnectionTransform = baseConnection.ParentConnection.transform;

                    GetNewRoomPosAndRot(baseRoom.GlobalPosition, baseRoom.Rotation, selectedConnectionTransform, nextRoomConnectionTransform, out var newRoomPosition, out var rotationDiff);

                    var nextRoomWrapper = new RoomPrototype(nextStructureElement, newRoom, newRoomPosition, rotationDiff);

                    if (!TryAddRoomToVirtualSpace(nextRoomWrapper, baseRoom))
                    {
                        continue;
                    }

                    nextRoomWrapper.ConnectToParent(nextRoomConnection, baseConnection);

                    yield return(nextRoomWrapper);
                }
            }
        }
        private bool BuildPrototypeRoomRecur(RoomPrototype room)
        {
#if TAURUS_DEBUG_LOG
            Debug.Log($"Room {room.RoomResource} is built");
#endif
            DungeonNode actualGraphElement = room.ActualGraphElement;

            if (actualGraphElement.IsEndNode)
            {
                return(true);
            }

            var subElements = actualGraphElement.SubElements.Where(sub => GetGenMetaData(sub.MetaData).NodeRequired).ToList();

            if (room.ChildRoomConnections.Count < actualGraphElement.ChildNodes.Count())
            {
                throw new Exception($"Room {room.RoomResource.name} has {room.ChildRoomConnections.Count} connections, yet the graph element {actualGraphElement.Style} requires {actualGraphElement.ChildNodes.Count()}");
            }

            for (int connectionsToMake = subElements.Count; connectionsToMake > 0; connectionsToMake--)
            {
                IList <RoomPrototypeConnection> availableConnections = room.ChildRoomConnections
                                                                       .Where(x => x.State == PrototypeConnectionState.FREE)
                                                                       .ToList()
                                                                       .Shuffle(_random);

                DungeonNode nextStructureElement = subElements[connectionsToMake - 1];

                bool failed = availableConnections.Count < connectionsToMake;
                RoomPrototypeConnection successfulConnection = null;
                if (!failed)
                {
                    foreach (var selectedConnection in availableConnections)
                    {
                        if (GetPossibleRoomsForConnection(selectedConnection, nextStructureElement).Any(BuildPrototypeRoomRecur))
                        {
                            successfulConnection = selectedConnection;
                            break;
                        }
                    }

                    if (successfulConnection == null)
                    {
                        failed = true;
                    }
                }

                // building cannot be successful
                if (failed)
                {
#if TAURUS_DEBUG_LOG
                    Debug.LogWarning($"Failed to make room {room} of element {actualGraphElement.Style}");
#endif
                    RemoveRoomAndChildrenRecur(room);
                    room.ParentRoomConnection?.ClearChild();
                    _stepBackCounter.StepBack();
                    return(false);
                }
                else
                {
                    availableConnections.Remove(successfulConnection);
                }
            }

            return(true);
        }