Ejemplo n.º 1
0
        private LabyrinthDungeon CreateDenseMaze(int rows, int columns, double changeDirectionModifier)
        {
            var map = new LabyrinthDungeon(rows, columns);

            map.MarkCellsUnvisited();
            var currentLocation   = map.PickRandomCellAndMarkItVisited(_random);
            var previousDirection = Direction.North;

            while (!map.AllCellsVisited)
            {
                var directionPicker = new DirectionPicker(_random, previousDirection, changeDirectionModifier);
                var direction       = directionPicker.GetNextDirection();

                while (!map.HasAdjacentCellInDirection(currentLocation, direction) || map.AdjacentCellInDirectionIsVisited(currentLocation, direction))
                {
                    if (directionPicker.HasNextDirection)
                    {
                        direction = directionPicker.GetNextDirection();
                    }
                    else
                    {
                        currentLocation = map.GetRandomVisitedCell(currentLocation, _random);                       // get a new previously visited location
                        directionPicker = new DirectionPicker(_random, previousDirection, changeDirectionModifier); // reset the direction picker
                        direction       = directionPicker.GetNextDirection();                                       // get a new direction.
                    }
                }

                currentLocation = map.CreateCorridor(currentLocation, direction);

                map.FlagCellAsVisited(currentLocation);
                previousDirection = direction;
            }

            return(map);
        }
        protected virtual IEnumerable <PathFindingNode> GetNodeNeighbours(TerrainMap terrain, IList <IActor> actors,
                                                                          IMovementProfile movementProfile,
                                                                          PathFindingNode node, Point locationTo)
        {
            var picker = new DirectionPicker(Direction.Northwest, 100, movementProfile.AvailableDirections);

            while (picker.HasDirectionToPick)
            {
                Direction direction = picker.PickRandomDirection();
                if (terrain.HasAdjacentLocation(node.Location, direction))
                {
                    Point targetLocation = terrain.GetTargetLocation(node.Location, direction).Value;

                    if (LocationIsTraversable(terrain, actors, movementProfile, targetLocation, locationTo))
                    {
                        yield return
                            new PathFindingNode
                            {
                                Location     = direction.ApplyTransform(node.Location),
                                Direction    = direction,
                                MovementCost = CalculateLocationMovementCost(terrain, actors, movementProfile, targetLocation, locationTo)
                            }
                    }
                    ;
                }
            }
        }
Ejemplo n.º 3
0
    override public void StartDigging(VirtualMap map, CellLocation starting_location, int directionChangeModifier)
    {
        CellLocation currentLocation = starting_location;

        map.MarkAsVisited(currentLocation);

        // Pick a starting previous direction
        VirtualMap.DirectionType previousDirection = VirtualMap.DirectionType.North;

        List <CellLocation> previousLocations = new List <CellLocation>();

        // Repeat until all cells have been visited
        while (!map.AllCellsVisited)
        {
            // Get a starting direction
            DirectionPicker          directionPicker = new DirectionPicker(map, currentLocation, directionChangeModifier, previousDirection);
            VirtualMap.DirectionType direction       = directionPicker.GetNextDirection(map, currentLocation);

            if (direction != VirtualMap.DirectionType.None)
            {
                // Create a corridor in the current cell and flag it as visited
                previousLocations.Add(currentLocation);
                previousDirection = direction;
                currentLocation   = map.CreateCorridor(currentLocation, direction);
                map.FlagCellAsVisited(currentLocation);
            }
            else
            {
                // Backtrack
                currentLocation = previousLocations[previousLocations.Count - 1];
                previousLocations.RemoveAt(previousLocations.Count - 1);
            }
        }
    }
        private void CreateDenseMaze(CellDungeon dungeon)
        {
            var currentLocation   = dungeon.PickRandomCellAndSetItAsVisited();
            var previousDirection = Direction.North;

            while (!dungeon.AllCellsAreVisited)
            {
                var directionPicker = new DirectionPicker(previousDirection, ChangeDirectionModifier);
                var direction       = directionPicker.PickRandomDirection();

                while (!dungeon.HasAdjacentCell(currentLocation, direction) ||
                       dungeon.AdjacentCellIsVisited(currentLocation, direction))
                {
                    if (directionPicker.HasDirectionToPick)
                    {
                        direction = directionPicker.PickRandomDirection();
                    }
                    else
                    {
                        currentLocation = dungeon.GetRandomVisitedCell(currentLocation);                   // Get a new previously visited location
                        directionPicker = new DirectionPicker(previousDirection, ChangeDirectionModifier); // Reset the direction picker
                        direction       = directionPicker.PickRandomDirection();                           // Get a new direction
                    }
                }

                currentLocation = dungeon.CreateCorridor(currentLocation, direction);
                dungeon.SetCellAsVisited(currentLocation);
                previousDirection = direction;
            }
        }
        private void RemoveDeadEnds(CellDungeon dungeon)
        {
            foreach (var deadEndLocation in dungeon.DeadEndCellLocations)
            {
                if (ShouldRemoveDeadend())
                {
                    var currentLocation = deadEndLocation;

                    do
                    {
                        // Initialize the direction picker not to select the dead-end corridor direction
                        var directionPicker =
                            new DirectionPicker(dungeon[currentLocation].CalculateDeadEndCorridorDirection(), 100);
                        var direction = directionPicker.PickRandomDirection();

                        while (!dungeon.HasAdjacentCell(currentLocation, direction))
                        {
                            if (directionPicker.HasDirectionToPick)
                            {
                                direction = directionPicker.PickRandomDirection();
                            }
                            else
                            {
                                throw new InvalidOperationException("This should not happen");
                            }
                        }
                        // Create a corridor in the selected direction
                        currentLocation = dungeon.CreateCorridor(currentLocation, direction);
                    } while (dungeon[currentLocation].IsDeadEnd); // Stop when you intersect an existing corridor.
                }
            }
        }
Ejemplo n.º 6
0
        private Point MoveRandomDirection(Point point)
        {
            DirectionPicker directionPicker = new DirectionPicker();

            do
            {
                point = directionPicker.RandomDirection(point);
            } while (!map.IsValidLocation(point));

            return(point);
        }
Ejemplo n.º 7
0
        /// <param name="deadEndRemovalModifier">Percentage value (0.0 - 1.0) of dead ends to convert into loops.</param>
        private void RemoveDeadEnds(LabyrinthDungeon map, double deadEndRemovalModifier)
        {
            var noOfDeadEndCellsToRemove = (int)System.Math.Ceiling(deadEndRemovalModifier * map.Rows * map.Columns);
            var deadEndLocations         = map.DeadEndCellLocations;

            for (var i = 0; i < noOfDeadEndCellsToRemove; i++)
            {
                if (deadEndLocations.Count == 0)
                {
                    break;
                }

                var index           = _random.Next(0, deadEndLocations.Count);
                var deadEndLocation = deadEndLocations[index];
                deadEndLocations.RemoveAt(index);
                if (map[deadEndLocation].IsDeadEnd)
                {
                    var currentLocation = deadEndLocation;

                    do
                    {
                        // Initialize the direction picker not to select the dead-end corridor direction.
                        var directionPicker = new DirectionPicker(_random, map[currentLocation].CalculateDeadEndCorridorDirection(), 1);
                        var direction       = directionPicker.GetNextDirection();

                        while (!map.HasAdjacentCellInDirection(currentLocation, direction))
                        {
                            if (directionPicker.HasNextDirection)
                            {
                                direction = directionPicker.GetNextDirection();
                            }
                            else
                            {
                                throw new InvalidOperationException("This should not happen.");
                            }
                        }

                        // Create a corridor in the selected direction:
                        currentLocation = map.CreateCorridor(currentLocation, direction);
                    }while (map[currentLocation].IsDeadEnd);                    // stop when you intersect an existing corridor
                }
            }
        }
    override public void StartDigging(VirtualMap map, CellLocation starting_location, int directionChangeModifier)
    {
        CellLocation currentLocation = starting_location;

        map.MarkAsVisited(currentLocation);

        // Pick a previous direction
        VirtualMap.DirectionType previousDirection = VirtualMap.DirectionType.North;

        // Repeat until all cells have been visited
        while (!map.AllCellsVisited)
        {
            // Get a starting direction
            DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, directionChangeModifier, previousDirection);

            VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation);

            if (direction != VirtualMap.DirectionType.None)
            {
                // Create a corridor in the current cell and flag it as visited
                currentLocation = map.CreateCorridor(currentLocation, direction);
                map.FlagCellAsVisited(currentLocation);
                previousDirection = direction;
            }
            // or start from another visited cell
            // NOTE: This may be less performant!
            else
            {
                currentLocation = map.GetRandomVisitedCell(currentLocation);

                // No visited cell available: proceed from a random unvisited cell
                if (currentLocation.x == -1)
                {
                    currentLocation = map.PickRandomUnvisitedLocation();
                    map.MarkAsVisited(currentLocation);
                }
            }
        }
    }
    // Open dead ends by linking them to rooms
    private void OpenDeadEnds(VirtualMap map)
    {
        //		Console.WriteLine("DEAD END MOD: " + openDeadEndModifier);
        if (openDeadEndModifier == 0)
        {
            return;
        }

        IEnumerable <CellLocation> deads = map.DeadEndCellLocations;

        foreach (CellLocation deadEnd in deads)
        {
            if (DungeonGenerator.Random.Instance.Next(1, 99) < openDeadEndModifier)
            {
                CellLocation currentLocation = deadEnd;
                //				int count=0;
                do
                {
                    // Initialize the direction picker not to select the dead-end corridor direction
                    DirectionPicker directionPicker = new DirectionPicker(map, currentLocation, map.CalculateDeadEndCorridorDirection(currentLocation));
                    //                    Debug.Log("We have a dead and " + directionPicker);
                    VirtualMap.DirectionType direction = directionPicker.GetNextDirection(map, currentLocation);
                    //					Debug.Log("We choose dir " + direction);
                    if (direction == VirtualMap.DirectionType.None)
                    {
                        throw new InvalidOperationException("Could not remove the dead end!");
                    }
                    //						Debug.Log("Cannot go that way!");
                    else
                    {
                        // Create a corridor in the selected direction
                        currentLocation = map.CreateCorridor(currentLocation, direction);
                    }
                    //					count++;
                } while (map.IsDeadEnd(currentLocation) && currentLocation != deadEnd); // Stop when you intersect an existing corridor, or when you end back to the starting cell (that means we could not remove the dead end, happens with really small maps
                //				Debug.Log("Dead end removed");
            }
        }
    }