コード例 #1
0
    /// <summary>
    ///
    /// </summary>
    /// <param name="startRoom"></param>
    /// <param name="exitRoom"></param>
    private int ResolveRoomConnections(StartRoom startRoom, ExitRoom exitRoom)
    {
        // Put walls around the edge of the map
        for (var x = 0; x < GridSize; ++x)
        {
            for (var y = 0; y < GridSize; ++y)
            {
                foreach (var direction in RoomConnection.Directions)
                {
                    var room = GetRoom(x, y);
                    if (room?.HasConnection(direction) != true)
                    {
                        continue;
                    }

                    var adjacentRoom = GetAdjacentRoom(x, y, direction);

                    // Adjacent room has no connection point at the opposite side, set to a wall.
                    if (adjacentRoom != null && !adjacentRoom.HasConnection(direction.GetOpposite()))
                    {
                        room.SetConnection(direction, RandomArrayItem(WallConnectionPrefabs));
                        continue;
                    }

                    // adjacent it out of bounds, set to a wall.
                    if (adjacentRoom == null)
                    {
                        room.SetConnection(direction, RandomArrayItem(WallConnectionPrefabs));
                    }
                }
            }
        }

        // Find a route from start to exit.
        var      maxPathResolve = (GridSize * GridSize) * RoomConnection.Directions.Length;
        BaseRoom currentRoom    = startRoom;
        var      roomRoute      = new Stack <BaseRoom>();

        while (currentRoom != exitRoom)
        {
            var openDirections = currentRoom.GetFreeConnectionDirections();
            if (!openDirections.Any())
            {
                if (roomRoute.Count == 0)
                {
                    Debug.LogError($"The room '{currentRoom.name}' has no open connections.");
                    break;
                }

                currentRoom = roomRoute.Pop();
                continue;
            }

            var moveDirection = openDirections[Random.Range(0, openDirections.Count)];
            var nextRoom      = GetAdjacentRoom(currentRoom, moveDirection);

            var doorPrefabs = DoorConnectionPrefabs;
            if (currentRoom == startRoom)
            {
                doorPrefabs = doorPrefabs.Where(x => x.Type == DoorConnector.DoorType.Normal).ToArray();
            }

            var doorConnection = RandomArrayItem(doorPrefabs);
            currentRoom.SetConnection(moveDirection, doorConnection);
            nextRoom.SetConnection(moveDirection.GetOpposite(), doorConnection);

            roomRoute.Push(currentRoom);
            currentRoom = nextRoom;

            if (--maxPathResolve == 0)
            {
                Debug.LogError("Failed to generate a path from start to finish within the maximum number of moves.");
                break;
            }
        }

        // Fill all open connections with walls.
        for (var x = 0; x < GridSize; ++x)
        {
            for (var y = 0; y < GridSize; ++y)
            {
                var room = GetRoom(x, y);
                if (room == null)
                {
                    continue;
                }

                foreach (var direction in room.GetFreeConnectionDirections())
                {
                    var wallPrefab = RandomArrayItem(WallConnectionPrefabs);
                    room.SetConnection(direction, wallPrefab);

                    var adjacentRoom = GetAdjacentRoom(x, y, direction);
                    if (adjacentRoom?.HasConnection(direction.GetOpposite()) == true)
                    {
                        adjacentRoom.SetConnection(direction.GetOpposite(), wallPrefab);
                    }
                }
            }
        }

        // Remove completely walled rooms
        for (var x = 0; x < GridSize; ++x)
        {
            for (var y = 0; y < GridSize; ++y)
            {
                var room = GetRoom(x, y);
                if (room?.IsBoxedIn() == true)
                {
                    Destroy(room.gameObject);
                    m_tiles[x, y] = null;
                }
            }
        }

        return(CalculateShortestRoute(startRoom, exitRoom, 0, new HashSet <BaseRoom>()));
    }