예제 #1
0
        private static void Walk(Room room)
        {
            var entryPoint = room.entryPoint;
            room.roomBuffer.Assign(x => Sides.None);
            room.roomBuffer[entryPoint.X, entryPoint.Y, entryPoint.Z] = Sides.Bottom;

            const double MinDimensionalTraversal = 0.5;
            var minPathLength =
                (int)
                    (room.Width*MinDimensionalTraversal*room.Height*MinDimensionalTraversal*room.Depth*
                     MinDimensionalTraversal);

            var currentLocation = entryPoint;
            var possibleSides = Enum.GetValues(typeof (Sides)).Cast<Sides>().ToArray();
            var possibleDirections = Enum.GetValues(typeof (Directions)).Cast<Directions>().Where(d => d != Directions.None && d != Directions.NUM_VALUES).ToArray();

            var solutionPath = new List<Int3> {currentLocation};
            Directions lastDirection = Directions.None;

            for (var i = 0; i < minPathLength; i++)
            {
                currentLocation = StepAlongPath(room, currentLocation, possibleSides, possibleDirections, solutionPath, i, minPathLength, ref lastDirection);

                if (i == minPathLength - 1)
                {
                    room.door = currentLocation;
                    room.solutionPath = solutionPath.ToList();
                }
            }
        }
예제 #2
0
        private void InitFields()
        {
            _wireColor = Color.red;
            _pathColor = Color.magenta;
            _startColor = Color.red;
            _endColor = Color.green;

            //_pathColor.a = 0.75f;
            _wireColor.a = 0.25f;

            _room = new Room(width, height, depth, 0);
        }
예제 #3
0
        public static void GenerateSolutionPath(Room room)
        {
            while (true)
            {
                try
                {
                    Walk(room);
                    break;
                }
                catch (InvalidSolveException)
                {
                }
            }

            Diverge(room);
        }
예제 #4
0
        private static void Diverge(Room room)
        {
            var clone = room.Clone();
            for (var step = 0; step < room.solutionPath.Count; step++)
            {
                try
                {
                    var minPathTraversal = UnityEngine.Random.value;
                    var minPathLength =
                        (int)
                            (clone.Width*minPathTraversal*clone.Height*minPathTraversal*clone.Depth*
                             minPathTraversal);

                    if (minPathLength > 0)
                    {
                        var currentLocation = clone.solutionPath[step];
                        var possibleSides = Enum.GetValues(typeof (Sides)).Cast<Sides>().ToArray();
                        var possibleDirections =
                            Enum.GetValues(typeof (Directions))
                                .Cast<Directions>()
                                .Where(d => d != Directions.None && d != Directions.NUM_VALUES)
                                .ToArray();

                        var divergentPath = new List<Int3> {currentLocation};
                        Directions lastDirection = Directions.None;

                        for (var i = 0; i < minPathLength; i++)
                        {
                            currentLocation = StepAlongPath(clone, currentLocation, possibleSides, possibleDirections,
                                divergentPath, i, minPathLength, ref lastDirection);
                        }

                        clone.divergentPaths.Add(divergentPath);
                    }

                    clone.CopyInto(room);
                }
                catch (InvalidSolveException)
                {
                    
                }
            }
        }
예제 #5
0
        public void CopyInto(Room room)
        {
            for (var x = 0; x < Width; x++)
            {
                for (var y = 0; y < Height; y++)
                {
                    for (var z = 0; z < Depth; z++)
                    {
                        room.roomBuffer[x, y, z] = roomBuffer[x, y, z];
                    }
                }
            }

            for (var i = 0; i < NumKeyLockPairs; i++)
            {
                room.keys[i] = keys[i];
                room.locks[i] = locks[i];
            }

            room.entryPoint = entryPoint;
            room.door = door;
            room.solutionPath = new List<Int3>(solutionPath);
            room.divergentPaths = new List<List<Int3>>(divergentPaths);
        }
예제 #6
0
        private void InitFields(int level)
        {
            _wireColor = Color.red;
            _pathColor = Color.magenta;
            _startColor = Color.red;
            _endColor = Color.green;

            //_pathColor.a = 0.75f;
            _wireColor.a = 0.25f;

            _geoWalls = new List<GameObject>();

            List<int> levelSize = GetLevelSize(level);

            _room = new Room(levelSize[0], levelSize[1], levelSize[2], 0);
        }
예제 #7
0
        private static Int3 DetermineNextLocation(Room room, Int3 currentLocation, Directions[] possibleDirections, ref Directions lastDirection)
        {
            Directions invalidDirections = Directions.None;
            var foundValidDirection = false;
            var intendedLocation = currentLocation;
            var currentSide = room.roomBuffer[currentLocation.X, currentLocation.Y, currentLocation.Z];

            if (lastDirection == Directions.Left)
            {
                invalidDirections |= Directions.Right;
            }

            if (lastDirection == Directions.Right)
            {
                invalidDirections |= Directions.Left;
            }

            if (lastDirection == Directions.Up)
            {
                invalidDirections |= Directions.Down;
            }

            if (lastDirection == Directions.Down)
            {
                invalidDirections |= Directions.Up;
            }

            if (lastDirection == Directions.Forward)
            {
                invalidDirections |= Directions.Back;
            }

            if (lastDirection == Directions.Back)
            {
                invalidDirections |= Directions.Forward;
            }

            if ((currentSide & Sides.Left) > 0)
            {
                invalidDirections |= Directions.Left;
                invalidDirections |= Directions.Right;
            }
            if ((currentSide & Sides.Right) > 0)
            {
                invalidDirections |= Directions.Left;
                invalidDirections |= Directions.Right;
            }
            if ((currentSide & Sides.Top) > 0)
            {
                invalidDirections |= Directions.Up;
                invalidDirections |= Directions.Down;
            }
            if ((currentSide & Sides.Bottom) > 0)
            {
                invalidDirections |= Directions.Up;
                invalidDirections |= Directions.Down;
            }
            if ((currentSide & Sides.Front) > 0)
            {
                invalidDirections |= Directions.Back;
                invalidDirections |= Directions.Forward;
            }
            if ((currentSide & Sides.Rear) > 0)
            {
                invalidDirections |= Directions.Back;
                invalidDirections |= Directions.Forward;
            }

            while (!foundValidDirection)
            {
                intendedLocation = currentLocation;

                if (invalidDirections >= Directions.NUM_VALUES - 1)
                {
                    throw new InvalidSolveException();
                }

                var directions = invalidDirections;
                lastDirection = possibleDirections.Where(d => (directions & d) == 0).SelectRandom();
                if (lastDirection == Directions.None)
                    throw new InvalidSolveException();

                switch (lastDirection)
                {
                    case Directions.Forward:
                        intendedLocation.Z += 1;
                        if (intendedLocation.Z == room.Depth)
                        {
                            invalidDirections |= lastDirection;
                        }
                        else
                        {
                            if (room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] !=
                                Sides.None)
                            {
                                invalidDirections |= lastDirection;
                            }
                            else
                            {
                                foundValidDirection = true;
                            }
                        }
                        break;

                    case Directions.Back:
                        intendedLocation.Z -= 1;
                        if (intendedLocation.Z < 0)
                        {
                            invalidDirections |= lastDirection;
                        }
                        else
                        {
                            if (room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] !=
                                Sides.None)
                            {
                                invalidDirections |= lastDirection;
                            }
                            else
                            {
                                foundValidDirection = true;
                            }
                        }
                        break;

                    case Directions.Up:
                        intendedLocation.Y += 1;
                        if (intendedLocation.Y == room.Height)
                        {
                            invalidDirections |= lastDirection;
                        }
                        else
                        {
                            if (room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] !=
                                Sides.None)
                            {
                                invalidDirections |= lastDirection;
                            }
                            else
                            {
                                foundValidDirection = true;
                            }
                        }
                        break;

                    case Directions.Down:
                        intendedLocation.Y -= 1;
                        if (intendedLocation.Y < 0)
                        {
                            invalidDirections |= lastDirection;
                        }
                        else
                        {
                            if (room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] !=
                                Sides.None)
                            {
                                invalidDirections |= lastDirection;
                            }
                            else
                            {
                                foundValidDirection = true;
                            }
                        }
                        break;

                    case Directions.Left:
                        intendedLocation.X -= 1;
                        if (intendedLocation.X < 0)
                        {
                            invalidDirections |= lastDirection;
                        }
                        else
                        {
                            if (room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] !=
                                Sides.None)
                            {
                                invalidDirections |= lastDirection;
                            }
                            else
                            {
                                foundValidDirection = true;
                            }
                        }
                        break;

                    case Directions.Right:
                        intendedLocation.X += 1;
                        if (intendedLocation.X == room.Width)
                        {
                            invalidDirections |= lastDirection;
                        }
                        else
                        {
                            if (room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] !=
                                Sides.None)
                            {
                                invalidDirections |= lastDirection;
                            }
                            else
                            {
                                foundValidDirection = true;
                            }
                        }
                        break;
                }
            }

            return intendedLocation;
        }
예제 #8
0
        private static Int3 StepAlongPath(Room room, Int3 currentLocation, Sides[] possibleSides,
            Directions[] possibleDirections, List<Int3> solutionPath, int i, int minPathLength, ref Directions lastDirection)
        {
            var currentSide = room.roomBuffer[currentLocation.X, currentLocation.Y, currentLocation.Z];

            if (lastDirection != Directions.None && UnityEngine.Random.Range(0, 2) == 0)
            {
                var side = currentSide;
                var direction = lastDirection;

                var desirableSides = possibleSides
                    .Where(s => (s & side) == 0 && s != Sides.None &&
                                (
                                    s == Sides.Left && direction != Directions.Right
                                    || s == Sides.Right && direction != Directions.Left
                                    || s == Sides.Top && direction != Directions.Down
                                    || s == Sides.Bottom && direction != Directions.Up
                                    || s == Sides.Front && direction != Directions.Back
                                    || s == Sides.Rear && direction != Directions.Forward
                                    ));

                if (desirableSides.Any())
                {
                    currentSide = desirableSides.SelectRandom();
                    room.roomBuffer[currentLocation.X, currentLocation.Y, currentLocation.Z] |= currentSide;
                }
            }

            var intendedLocation = DetermineNextLocation(room, currentLocation, possibleDirections, ref lastDirection);

            room.roomBuffer[intendedLocation.X, intendedLocation.Y, intendedLocation.Z] |= currentSide;
            currentLocation = intendedLocation;
            solutionPath.Add(currentLocation);

            return currentLocation;
        }
예제 #9
0
 public Room Clone()
 {
     var clone = new Room(Width, Height, Depth, NumKeyLockPairs);
     CopyInto(clone);
     return clone;
 }