Пример #1
0
        public override IsaacRoomLayout GenerateLayout(IsaacRoom room, System.Random random, int roomWidth, int roomHeight)
        {
            var doors  = room.doorPositions;
            var layout = new IsaacRoomLayout();

            layout.InitializeTiles(roomWidth, roomHeight, IsaacRoomTileType.Empty);

            if (doors.Count > 1)
            {
                for (int i = 0; i < doors.Count; i++)
                {
                    for (int j = i + 1; j < doors.Count; j++)
                    {
                        var brushSize = random.Range(minBrushSize, maxBrushSize + 1);
                        ConnectDoors(layout, doors[i], doors[j], brushSize);
                    }
                }
            }
            else
            {
                var brushSize = random.Range(minBrushSize, maxBrushSize + 1);
                ConnectDoors(layout, doors[0], doors[0], brushSize);
            }

            return(layout);
        }
Пример #2
0
        protected Ray GetRandomRayDownWithinArea(Vector2 size, Vector3 origin)
        {
            var pos = origin;

            pos.y  = maxWorldHeight;
            pos.x += size.x * mainSeed.Range(-0.5f, 0.5f) * transform.lossyScale.x;
            pos.z += size.y * mainSeed.Range(-0.5f, 0.5f) * transform.lossyScale.z;

            Ray ray = new Ray(pos, FastMath.Down);

            return(ray);
        }
Пример #3
0
    public static float Range(this System.Random random, float min, float max, float step)
    {
        float value = random.Range(min, max);

        value = (value - min).RoundTo(step) + min;
        return(value);
    }
Пример #4
0
        public void GetLineNo_Passes()
        {
            var br = System.Environment.NewLine;

            {
                var text = "a\n"
                           + "b\n"
                           + "c\n"
                           + "d"
                ;

                var lineNo = 1;
                for (var i = 0; i < text.Length; ++i)
                {
                    Assert.AreEqual(lineNo, text.GetLineNo(i), $"Fail... pos={i}");
                    if (text[i] == '\n')
                    {
                        lineNo++;
                    }
                }
            }

            var rnd = new System.Random();

            for (var i = 0; i < 1000; ++i)
            {
                var newlineCount = rnd.Range(1, 20);
                var text         = Enumerable.Range(0, newlineCount)
                                   .Select(_i => rnd.RandomString(rnd.Range(1, 10)))
                                   .Aggregate("", (_s, _c) => _s + _c + br);
                Assert.AreEqual(newlineCount, text.GetLineNo(), $"Fail...");

                var pos           = rnd.Range(0, text.Length);
                var newlineCount2 = 1;
                for (var j = 0; j < pos; ++j)
                {
                    if (text[j] == '\n')
                    {
                        newlineCount2++;
                    }
                }
                Assert.AreEqual(newlineCount2, text.GetLineNo(pos), $"Fail to specify pos({pos})...");
            }
        }
Пример #5
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="rnd"></param>
 /// <param name="length"></param>
 /// <returns></returns>
 public static string RandomString(this System.Random rnd, int length)
 {
     return(Enumerable.Range(0, length)
            .Select(_ =>
     {
         char ch;
         do
         {
             ch = (char)rnd.Range(1, byte.MaxValue);
         } while ((char.IsControl(ch) || (ch & 0x80) != 0));
         return ch;
     })
            .Aggregate("", (_s, _c) => _s + _c));
 }
Пример #6
0
        public void FixedLengthPropertyPasses()
        {
            var aspectLayout = new AspectSizeFitter();
            var rnd          = new System.Random();

            for (var i = 0; i < 1000; ++i)
            {
                var prev   = aspectLayout.AspectRatio;
                var length = rnd.Range(-10, 1000);
                aspectLayout.FixedLength = length;

                var errorMessage = $"Fail test... ratio={aspectLayout.FixedLength}, set length={length}, prevLength={prev}";
                Assert.IsTrue(0f <= aspectLayout.AspectRatio, errorMessage);
            }
        }
Пример #7
0
        public void AspectRatioPropertyPasses()
        {
            var aspectLayout = new AspectSizeFitter();
            var rnd          = new System.Random();

            for (var i = 0; i < 1000; ++i)
            {
                var prevRatio = aspectLayout.AspectRatio;
                var ratio     = rnd.Range(-10, 1000);
                aspectLayout.AspectRatio = ratio;

                var errorMessage = $"Fail test... ratio={aspectLayout.AspectRatio}, set ratio={ratio}, prevRatio={prevRatio}";
                Assert.IsTrue(LayoutDefines.NUMBER_PRECISION <= aspectLayout.AspectRatio, errorMessage);
            }
        }
Пример #8
0
        public void OrderInGroupPropertyPasses()
        {
            var info = new LayoutInfo();

            Assert.AreEqual(0, info.OrderInGroup, $"Default値が異なります。");

            var rnd = new System.Random();

            for (var i = 0; i < 100; ++i)
            {
                var value = rnd.Range(-100, 100);
                info.OrderInGroup = value;

                Assert.AreEqual(value, info.OrderInGroup);
            }
        }
Пример #9
0
        public void SizeGrowInGroupPropertyPasses()
        {
            var info = new LayoutInfo();

            AssertionUtils.AreNearlyEqual(1f, info.SizeGrowInGroup, LayoutDefines.NUMBER_PRECISION, $"Default値が異なります。");

            var rnd = new System.Random();

            for (var i = 0; i < 100; ++i)
            {
                var value = rnd.Range(-10, 100);
                info.SizeGrowInGroup = value;

                var correct = Max(value, 0f);
                AssertionUtils.AreNearlyEqual(correct, info.SizeGrowInGroup, LayoutDefines.NUMBER_PRECISION);
            }
        }
Пример #10
0
        public void GetLayoutSizePasses()
        {
            var rnd      = new System.Random();
            var minValue = -10f;
            var maxValue = 1000f;

            for (var i = 0; i < 100; ++i)
            {
                var info = new LayoutInfo();
                info.LayoutSize = new Vector3(
                    rnd.Range(minValue, maxValue),
                    rnd.Range(minValue, maxValue),
                    rnd.Range(minValue, maxValue)
                    );
                info.MinSize = new Vector3(
                    rnd.Range(minValue, maxValue),
                    rnd.Range(minValue, maxValue),
                    rnd.Range(minValue, maxValue)
                    );

                var target = new LayoutTargetObject();
                target.SetLocalSize(new Vector3(
                                        rnd.Range(minValue, maxValue),
                                        rnd.Range(minValue, maxValue),
                                        rnd.Range(minValue, maxValue)
                                        ));

                var errorMessage = $"Fail test... LayoutSize={info.LayoutSize:F4}, MinSize={info.MinSize:F4}, Target LocalSize={target.LocalSize: F4}";
                var result       = info.GetLayoutSize(target);
                var correct      = Vector3.Max(info.MinSize, target.LocalSize);
                correct.x = info.LayoutSize.x < 0 ? correct.x : Min(correct.x, info.LayoutSize.x);
                correct.y = info.LayoutSize.y < 0 ? correct.y : Min(correct.y, info.LayoutSize.y);
                correct.z = info.LayoutSize.z < 0 ? correct.z : Min(correct.z, info.LayoutSize.z);
                AssertionUtils.AreNearlyEqual(correct, result, LayoutDefines.NUMBER_PRECISION, errorMessage);
            }
        }
        void GenerateLevelLayout()
        {
            var queue   = new Queue <LevelGrowthNode>();
            var visited = new HashSet <IntVector>();

            var roomFactory = new IsaacRoomFactory();

            rooms.Clear();
            doors.Clear();

            var start = new LevelGrowthNode();

            start.room          = roomFactory.CreateRoom(IntVector.Zero);
            start.moveDirection = 0;
            rooms.Add(start.room);

            queue.Enqueue(start);
            visited.Add(start.room.position);

            var  numRooms    = random.Range(isaacConfig.minRooms, isaacConfig.maxRooms);
            bool isSpawnRoom = true;

            while (queue.Count > 0)
            {
                var top = queue.Dequeue();
                if (isSpawnRoom)
                {
                    // in the spawn room.  Spawn on all 4 sides
                    for (int d = 0; d < 4; d++)
                    {
                        AddNextRoomNode(roomFactory, queue, visited, numRooms, top.room, d, isaacConfig.spawnRoomBranchProbablity);
                    }
                    isSpawnRoom = false;
                }
                else
                {
                    // Grow forward
                    AddNextRoomNode(roomFactory, queue, visited, numRooms, top.room, top.moveDirection, isaacConfig.growForwardProbablity);

                    // Grow sideways
                    AddNextRoomNode(roomFactory, queue, visited, numRooms, top.room, (top.moveDirection + 1) % 4, isaacConfig.growSidewaysProbablity);
                    AddNextRoomNode(roomFactory, queue, visited, numRooms, top.room, (top.moveDirection + 3) % 4, isaacConfig.growSidewaysProbablity);
                }

                if (rooms.Count >= numRooms)
                {
                    break;
                }
            }

            // Generate the tile layout of the rooms
            var layoutBuilder = GetComponent <IsaacRoomLayoutBuilder>();

            foreach (var room in rooms)
            {
                GenerateRoomLayout(layoutBuilder, room);
            }

            isaacModel.rooms = rooms.ToArray();
            isaacModel.doors = doors.ToArray();
            rooms.Clear();
            doors.Clear();
        }
Пример #12
0
        /// <summary>
        /// Generate a layout and save it in the model
        /// </summary>
        void GenerateCityLayout()
        {
            var width  = random.Range(demoConfig.minSize, demoConfig.maxSize);
            var length = random.Range(demoConfig.minSize, demoConfig.maxSize);

            demoModel.CityWidth  = width;
            demoModel.CityHeight = length;

            demoModel.Cells = new SimpleCityCell[width, length];

            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < length; z++)
                {
                    var cell = new SimpleCityCell();
                    cell.Position         = new IntVector(x, 0, z);
                    cell.CellType         = SimpleCityCellType.House;
                    cell.Rotation         = GetRandomRotation();
                    demoModel.Cells[x, z] = cell;
                }
            }


            // Build a road network by removing some houses
            // First build roads along the edge of the map
            for (int x = 0; x < width; x++)
            {
                MakeRoad(x, 0);
                MakeRoad(x, length - 1);
            }
            for (int z = 0; z < length; z++)
            {
                MakeRoad(0, z);
                MakeRoad(width - 1, z);
            }

            // Create roads in-between
            for (int x = GetRandomBlockSize() + 1; x < width; x += GetRandomBlockSize() + 1)
            {
                if (width - x <= 2)
                {
                    continue;
                }
                for (int z = 0; z < length; z++)
                {
                    MakeRoad(x, z);
                }
            }
            for (int z = GetRandomBlockSize() + 1; z < length; z += GetRandomBlockSize() + 1)
            {
                if (length - z <= 2)
                {
                    continue;
                }
                for (int x = 0; x < width; x++)
                {
                    MakeRoad(x, z);
                }
            }

            // Insert 2x houses (bigger houses)
            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < length; z++)
                {
                    if (CanContainBiggerHouse(x, z))
                    {
                        if (random.NextFloat() < demoConfig.biggerHouseProbability)
                        {
                            InsertBiggerHouse(x, z);
                        }
                    }
                }
            }

            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < length; z++)
                {
                    var cell = demoModel.Cells[x, z];
                    if (cell.CellType == SimpleCityCellType.House)
                    {
                        FaceHouseTowardsRoad(cell);
                    }
                }
            }


            // Create padding cells

            var padding     = demoConfig.cityWallPadding;
            var paddedCells = new List <SimpleCityCell>();

            for (int p = 1; p <= padding; p++)
            {
                var currentPadding = p;

                var sx = -currentPadding;
                var sz = -currentPadding;
                var ex = width + currentPadding - 1;
                var ez = length + currentPadding - 1;

                // Fill it with city wall padding marker
                for (int x = sx; x < ex; x++)
                {
                    SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding;

                    paddedCells.Add(CreateCell(x, sz, cellType));
                    paddedCells.Add(CreateCell(x, ez, cellType));
                }

                for (int z = sz; z < ez; z++)
                {
                    SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding;

                    paddedCells.Add(CreateCell(sx, z, cellType));
                    paddedCells.Add(CreateCell(ex, z, cellType));
                }
            }
            demoModel.WallPaddingCells = paddedCells.ToArray();
        }
Пример #13
0
        bool FindAttachmentConfiguration(ModuleInfo TargetModule, ModuleInfo IncomingModule, ref Matrix4x4 IncomingModuleTransform,
                                         int IncomingDoorIndex, List <Bounds> OccupiedBounds, ref SnapAttachmentConfiguration OutAttachmentConfig)
        {
            int NumDoors = TargetModule.ConnectionTransforms.Length;

            if (IncomingDoorIndex >= NumDoors)
            {
                return(false);
            }

            if (IncomingDoorIndex < 0 || IncomingModule == null)
            {
                OutAttachmentConfig.AttachedModule            = TargetModule;
                OutAttachmentConfig.AttachedModuleDoorIndex   = random.Range(0, NumDoors - 1);
                OutAttachmentConfig.AttachedModuleWorldBounds = TargetModule.Bounds;
                OutAttachmentConfig.AttachedModuleTransform   = Matrix4x4.identity;
                return(true);
            }

            if (IncomingDoorIndex >= NumDoors)
            {
                return(false);
            }
            Matrix4x4 IncomingDoorTransform = IncomingModule.ConnectionTransforms[IncomingDoorIndex];
            bool      bFoundValid           = false;

            int[] ShuffledIndices = MathUtils.GetShuffledIndices(NumDoors, random);
            for (int si = 0; si < ShuffledIndices.Length; si++)
            {
                int       Index = ShuffledIndices[si];
                Matrix4x4 AttachmentDoorTransform = TargetModule.ConnectionTransforms[Index];

                // Align the module with a door that fits the incoming door
                Matrix4x4 ModuleTransform = FindAttachmentTransform(ref IncomingModuleTransform, ref IncomingDoorTransform, ref AttachmentDoorTransform);

                if (!snapConfig.RotateModulesToFit)
                {
                    // Rotation is not allowed. Check if we rotated the module
                    var moduleRotation = Matrix.GetRotation(ref ModuleTransform);
                    if (Mathf.Abs(moduleRotation.eulerAngles.y) > 0.1f)
                    {
                        // Module was rotated
                        continue;
                    }
                }

                {
                    // Calculate the bounds of the module
                    Bounds ModuleWorldBounds = TargetModule.Bounds;
                    ModuleWorldBounds = MathUtils.TransformBounds(ModuleTransform, ModuleWorldBounds);
                    Bounds ContractedModuleWorldBounds = ModuleWorldBounds;
                    ContractedModuleWorldBounds.Expand(-1 * (snapConfig.CollisionTestContraction));

                    // Check if this module would intersect with any of the existing modules
                    bool bIntersects = false;
                    foreach (var OccupiedBound in OccupiedBounds)
                    {
                        if (ContractedModuleWorldBounds.Intersects(OccupiedBound))
                        {
                            // intersects. Do not spawn a module here
                            bIntersects = true;
                            break;
                        }
                    }
                    if (bIntersects)
                    {
                        continue;
                    }

                    // We found a valid module. Use this
                    OutAttachmentConfig.AttachedModule            = TargetModule;
                    OutAttachmentConfig.AttachedModuleDoorIndex   = Index;
                    OutAttachmentConfig.AttachedModuleWorldBounds = ModuleWorldBounds;
                    OutAttachmentConfig.AttachedModuleTransform   = ModuleTransform;
                    bFoundValid = true;
                    break;
                }
            }

            return(bFoundValid);
        }
Пример #14
0
 public static float Range(this System.Random random, float min, float max)
 {
     return((float)random.Range((double)min, max));
 }
        /// <summary>
        /// Generate a layout and save it in the model
        /// </summary>
        void GenerateCityLayout()
        {
            var width  = random.Range(demoConfig.minSize, demoConfig.maxSize);
            var length = random.Range(demoConfig.minSize, demoConfig.maxSize);

            demoModel.CityWidth  = width;
            demoModel.CityHeight = length;

            demoModel.Cells = new SimpleCityCell[width, length];

            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < length; z++)
                {
                    var cell = new SimpleCityCell();
                    cell.Position         = new IntVector(x, 0, z);
                    cell.CellType         = SimpleCityCellType.House;
                    cell.Rotation         = GetRandomRotation();
                    demoModel.Cells[x, z] = cell;
                }
            }


            // Build a road network by removing some houses
            // First build roads along the edge of the map
            for (int x = 0; x < width; x++)
            {
                MakeRoad(x, 0);
                MakeRoad(x, length - 1);
            }
            for (int z = 0; z < length; z++)
            {
                MakeRoad(0, z);
                MakeRoad(width - 1, z);
            }

            // Create roads in-between
            for (int x = GetRandomBlockSize() + 1; x < width; x += GetRandomBlockSize() + 1)
            {
                if (width - x <= 2)
                {
                    continue;
                }
                for (int z = 0; z < length; z++)
                {
                    MakeRoad(x, z);
                }
            }
            for (int z = GetRandomBlockSize() + 1; z < length; z += GetRandomBlockSize() + 1)
            {
                if (length - z <= 2)
                {
                    continue;
                }
                for (int x = 0; x < width; x++)
                {
                    MakeRoad(x, z);
                }
            }

            RemoveRoadEdges();


            // Insert bigger houses
            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < length; z++)
                {
                    foreach (var blockDimension in demoConfig.customBlockDimensions)
                    {
                        bool bProcess = random.NextFloat() < blockDimension.probability;
                        if (!bProcess)
                        {
                            continue;
                        }

                        int BlockWidth  = blockDimension.sizeX;
                        int BlockHeight = blockDimension.sizeZ;

                        InsertHouseDelegate InsertHouse = delegate() {
                            if (CanContainBiggerHouse(x, z, BlockWidth, BlockHeight))
                            {
                                if (random.NextFloat() < demoConfig.biggerHouseProbability)
                                {
                                    InsertBiggerHouse(x, z, BlockWidth, BlockHeight, 0, blockDimension.markerName);
                                }
                            }
                        };


                        InsertHouseDelegate InsertHouse90 = delegate()
                        {
                            // Try the 90 degrees rotated version
                            if (CanContainBiggerHouse(x, z, BlockHeight, BlockWidth))
                            {
                                if (random.NextFloat() < demoConfig.biggerHouseProbability)
                                {
                                    InsertBiggerHouse(x, z, BlockHeight, BlockWidth, 90, blockDimension.markerName);
                                }
                            }
                        };

                        if (random.NextFloat() < 0.5f)
                        {
                            InsertHouse();
                            InsertHouse90();
                        }
                        else
                        {
                            InsertHouse90();
                            InsertHouse();
                        }
                    }
                }
            }


            for (int x = 0; x < width; x++)
            {
                for (int z = 0; z < length; z++)
                {
                    var cell = demoModel.Cells[x, z];
                    if (cell.CellType == SimpleCityCellType.House)
                    {
                        FaceHouseTowardsRoad(cell);
                    }
                }
            }


            // Create padding cells

            var padding     = demoConfig.cityWallPadding;
            var paddedCells = new List <SimpleCityCell>();

            for (int p = 1; p <= padding; p++)
            {
                var currentPadding = p;

                var sx = -currentPadding;
                var sz = -currentPadding;
                var ex = width + currentPadding - 1;
                var ez = length + currentPadding - 1;

                // Fill it with city wall padding marker
                for (int x = sx; x < ex; x++)
                {
                    SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding;

                    paddedCells.Add(CreateCell(x, sz, cellType));
                    paddedCells.Add(CreateCell(x, ez, cellType));
                }

                for (int z = sz; z < ez; z++)
                {
                    SimpleCityCellType cellType = SimpleCityCellType.CityWallPadding;

                    paddedCells.Add(CreateCell(sx, z, cellType));
                    paddedCells.Add(CreateCell(ex, z, cellType));
                }
            }
            demoModel.WallPaddingCells = paddedCells.ToArray();
        }
Пример #16
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="rnd"></param>
 /// <param name="min"></param>
 /// <param name="max"></param>
 /// <returns></returns>
 public static float Range(this System.Random rnd, float min, float max)
 => (float)rnd.Range((double)min, (double)max);
Пример #17
0
        /// <summary>
        /// Creates a line for each particle to be displayed in the hologram.
        /// </summary>
        /// <param name="i">The index of the particle inside the combination.</param>
        /// <param name="particle">The particle which line is being generated.</param>
        /// <returns>The end position of the line.</returns>
        private HologramSpline CreateSpline(Particle particle)
        {
            //Setting rotation angles.
            if (particle.straight)
            {
                _theta = 0f;
                _phi   = 0f;
            }
            else
            {
                _theta = (float)_rand.Range(Mathf.PI / 6f, Mathf.PI / 3f);
                _phi   = (float)_rand.Range(Mathf.PI / 4f, Mathf.PI / 3f);

                if (particle.negative)
                {
                    _theta = -1f * _theta;
                    _phi   = -1f * _phi;
                }
            }
            //Generating the spline.
            var spline = Instantiate(_particleSplinePrefab, Vector3.zero, Quaternion.identity, transform);

            spline.transform.localPosition = Vector3.zero;
            spline.transform.localRotation = Quaternion.identity;
            spline.Reset();
            //Setting the instantiating boundaries.
            int   destination = particle.destination - 1;
            float rMax        = _rMaxCylArray[destination];
            float lMax        = _lMaxCylArray[destination];
            float rMin        = destination > 0 ? _rMaxCylArray[destination - 1] : 0.0f;
            float lMin        = destination > 0 ? _lMaxCylArray[destination - 1] : 0.0f;
            //Setting the coordinates of the spline points.
            Vector3 vDir = Vector3.zero;


            float factorTmpMin = particle.extremity ? 0.0f : _factorMin;
            float factorTmpMax = particle.extremity ? 0.0f : _factorMax;
            float lMaxFactor   = lMax - factorTmpMax * (lMax - lMin);
            float lMinFactor   = lMin + factorTmpMin * (lMax - lMin);
            float rMaxFactor   = rMax - factorTmpMax * (rMax - rMin);
            float rMinFactor   = rMin + factorTmpMin * (rMax - rMin);

            bool res = false;

            do
            {
                float r     = particle.extremity ? rMax : (float)_rand.Range(_rMaxCylArray[0], rMaxFactor);
                float alpha = (float)_rand.Range(0, Mathf.PI * 2f);

                spline.points[3].x = r * Mathf.Cos(alpha);
                spline.points[3].y = (float)_rand.Range(-lMaxFactor, lMaxFactor);
                spline.points[3].z = r * Mathf.Sin(alpha);

                spline.points[0] = Vector3.zero;

                float matrixRotation1 = (1.0f / spline.points[3].magnitude) * _amplitudeA;
                float matrixRotation2 = -(1.0f / spline.points[3].magnitude) * _amplitudeB;

                spline.points[1].x = matrixRotation1 * (spline.points[3].x * Mathf.Cos(_theta) + spline.points[3].z * Mathf.Sin(_theta));
                spline.points[1].y = matrixRotation1 * spline.points[3].y;
                spline.points[1].z = matrixRotation1 * ((-1f * spline.points[3].x) * Mathf.Sin(_theta) + spline.points[3].z * Mathf.Cos(_theta));

                vDir.x = matrixRotation2 * (spline.points[3].x * Mathf.Cos(-1f * _phi) + spline.points[3].z * Mathf.Sin(-1f * _phi));
                vDir.y = matrixRotation2 * spline.points[3].y;
                vDir.z = matrixRotation2 * ((-1f * spline.points[3].x) * Mathf.Sin(-1f * _phi) + spline.points[3].z * Mathf.Cos(-1f * _phi));

                spline.points[2].x = spline.points[3].x + vDir.x;
                spline.points[2].y = spline.points[3].y + vDir.y;
                spline.points[2].z = spline.points[3].z + vDir.z;

                res = (Mathf.Abs(spline.points[3].y) <= lMinFactor) && r <= rMinFactor;
            } while (res);

            return(new HologramSpline(spline, particle, vDir));
        }