Пример #1
0
        private void TryPartition(Point minPartitionSize)
        {
            var horizontalBias = Math.Min(Bounds.Width / Bounds.Height, 1);
            var verticalBias   = Math.Min(Bounds.Height / Bounds.Width, 1);
            int splitAt;
            int tries = 0, maxRetries = 5;

            bool isValidSplit;
            bool isHorizontalSplit;

            do
            {
                isHorizontalSplit = RNG.Chance(50 + horizontalBias * 20 - verticalBias * 20);
                var splitPercent = 0.5f + 0.5f * (RNG.NextFloat() - 0.5f);

                if (isHorizontalSplit)
                {
                    tries++;

                    splitAt = (int)Mathf.Lerp(0, Bounds.Width, splitPercent);
                    var remainder = Bounds.Width - splitAt;

                    isValidSplit = splitAt >= minPartitionSize.X && remainder >= minPartitionSize.X;
                }
                else
                {
                    splitAt = (int)Mathf.Lerp(0, Bounds.Height, splitPercent);
                    var remainder = Bounds.Height - splitAt;

                    isValidSplit = splitAt >= minPartitionSize.Y && remainder >= minPartitionSize.Y;
                }
                tries++;
            } while (!isValidSplit && tries < maxRetries);

            if (!isValidSplit)
            {
                Console.WriteLine($"Reached minimum space constraints {Bounds.Width} x {Bounds.Height}");
                return;
            }

            if (isHorizontalSplit)
            {
                SubPartitions    = new BinarySpacePartition[2];
                SubPartitions[0] = new BinarySpacePartition(Bounds.X, Bounds.Y,
                                                            splitAt, Bounds.Height);
                SubPartitions[1] = new BinarySpacePartition(Bounds.X + splitAt,
                                                            Bounds.Y, Bounds.Width - splitAt, Bounds.Height);
                Console.WriteLine($"Split width {Bounds.Width} into {SubPartitions[0].Bounds.Width} + {SubPartitions[1].Bounds.Width}");
            }
            else
            {
                SubPartitions    = new BinarySpacePartition[2];
                SubPartitions[0] = new BinarySpacePartition(Bounds.X, Bounds.Y,
                                                            Bounds.Width, splitAt);
                SubPartitions[1] = new BinarySpacePartition(Bounds.X, Bounds.Y + splitAt,
                                                            Bounds.Width, Bounds.Height - splitAt);
                Console.WriteLine($"Split height {Bounds.Height} into {SubPartitions[0].Bounds.Height} + {SubPartitions[1].Bounds.Height}");
            }
        }
Пример #2
0
        /// <summary>
        /// For each partition, fit a rectangle into it, leaving a certain space around it for variation
        /// </summary>
        /// <param name="partition"></param>
        /// <returns></returns>
        private Room FitRectangleIntoPartition(BinarySpacePartition partition)
        {
            var wiggleWidth  = (partition.Bounds.Width - _settings.MinRoomSize.X) / 2;
            var wiggleHeight = (partition.Bounds.Height - _settings.MinRoomSize.Y) / 2;

            var width  = _settings.MinRoomSize.X + RNG.NextInt(wiggleWidth);
            var height = _settings.MinRoomSize.Y + RNG.NextInt(wiggleHeight);

            var x = RNG.NextInt(wiggleWidth);
            var y = RNG.NextInt(wiggleHeight);


            var bounds = new Rectangle(partition.Bounds.X + x, partition.Bounds.Y + y, width, height);
            var room   = new Room()
            {
                Bounds = bounds
            };

            return(room);
        }
Пример #3
0
 /// <summary>
 /// Generate space partitions
 /// </summary>
 private void Stage1()
 {
     _tree = new BinarySpacePartition(0, 0, _settings.Width, _settings.Height);
     _tree.Split(_settings.MinRoomSize, _settings.MaxRoomSize);
 }