Пример #1
0
        /// <summary>
        /// Tries to find a place for the wall in the specified rectangle.
        /// </summary>
        /// <returns>An integer which describes the x coordinate where the wall should be placed</returns>
        private int TryPlaceWallVertical(MazeCoordinate recUpperleft, MazeCoordinate recDownright, Strategy strategy)
        {
            // first collect all possible coordinates
            int from  = recUpperleft.X + 2;
            int to    = recDownright.X - 2;
            int count = to - from;

            if (count <= 0)
            {
                return(-1);
            }

            var possibleVerticalCoordinates = Enumerable.Range(from, to - from).ToList();

            while (possibleVerticalCoordinates.Count() > 0)
            {
                //try them one by one
                int coordinateToTest = ChooseCoordinateBasedOnStrategy(strategy, possibleVerticalCoordinates);

                // will it cover a corridor?
                if (!(CurrentMaze.IsCorridor(new MazeCoordinate(coordinateToTest, recUpperleft.Y)) ||
                      CurrentMaze.IsCorridor(new MazeCoordinate(coordinateToTest, recDownright.Y))))
                {
                    // found valid coordinate
                    return(coordinateToTest);
                }
                possibleVerticalCoordinates.Remove(coordinateToTest);
            }

            // Failed to find a good coordinate.
            return(-1);
        }
Пример #2
0
        internal override MazeTransformationStep TryPlaceExit()
        {
            List <MazeCoordinate> possibleExits = new List <MazeCoordinate>();

            // collect all possible exits
            for (int y = CurrentMaze.GetHeight() - 2; y >= CurrentMaze.GetHeight() / 2; y--)
            {
                possibleExits.Add(new MazeCoordinate(0, y));
            }

            // check in random order if exit is valid
            while (possibleExits.Count > 0)
            {
                var possibleExit = possibleExits.ElementAt(Random.Next(possibleExits.Count));

                if (this.CurrentMaze.GetMazeTypeOnPos(1, possibleExit.Y) == MazeFieldType.Corridor)
                {
                    return(this.CurrentMaze.SetMazeTypeOnPos(0, possibleExit.Y, MazeFieldType.Exit));
                }
                else
                {
                    possibleExits.Remove(possibleExit);
                }
            }

            throw new Exception("Could not place a valid exit.");
        }
Пример #3
0
        private bool IsValidWay(MazeCoordinate point, MazeCoordinate comeFrom)
        {
            if (!this.CurrentMaze.IsPointInMaze(point))
            {
                return(false);
            }

            // Already something other than a wall?
            if (this.CurrentMaze.GetMazeTypeOnPos(point) != MazeFieldType.Wall)
            {
                return(false);
            }

            // Make sure we do not create a way through a wall.
            MazeCoordinate up    = new MazeCoordinate(point.X, point.Y - 1);
            MazeCoordinate right = new MazeCoordinate(point.X + 1, point.Y);
            MazeCoordinate down  = new MazeCoordinate(point.X, point.Y + 1);
            MazeCoordinate left  = new MazeCoordinate(point.X - 1, point.Y);

            MazeCoordinate[] pointsToCheck = { up, right, down, left };

            for (int i = 0; i < pointsToCheck.Length; i++)
            {
                if (!pointsToCheck[i].Equals(comeFrom))
                {
                    if (CurrentMaze.GetMazeTypeOnPos(pointsToCheck[i]) == MazeFieldType.Corridor)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #4
0
        internal override IEnumerable <MazeTransformationStep> InternalGenerateMazeFullSize()
        {
            InitializeMaze();
            entrance = new MazeCoordinate(upperleft.X + 1 + Random.Next(this.CurrentMaze.GetWidth() - 2), upperleft.Y);

            pointStack.Push(entrance);

            Nullable <MazeCoordinate> newCorridor;

            while (pointStack.Count() != 0)
            {
                newCorridor = FindWay();

                if (newCorridor == null)
                {
                    newCorridor = pointStack.Pop(); // One step back
                    if (newCorridor != null && CurrentMaze.WouldChangeMazeFieldType(newCorridor.Value, MazeFieldType.Corridor))
                    {
                        yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor));
                    }
                }
                else
                {
                    pointStack.Push(newCorridor.Value);
                    yield return(CurrentMaze.SetMazeTypeOnPos(newCorridor.Value, MazeFieldType.Corridor));
                }
            }

            yield return(TryPlaceEntrance());

            yield return(TryPlaceExit());
        }
Пример #5
0
        internal override MazeTransformationStep TryPlaceExit()
        {
            List <MazeCoordinate> possibleExits = new List <MazeCoordinate>();

            // collect all possible exits
            for (int i = CurrentMaze.GetWidth() - 2; i >= 1; i--)
            {
                possibleExits.Add(new MazeCoordinate(i, downright.Y));
            }

            // check in random order if exit is valid
            while (possibleExits.Count > 0)
            {
                var possibleExit = possibleExits.ElementAt(Random.Next(possibleExits.Count));

                if (CurrentMaze.GetMazeTypeOnPos(possibleExit.X, possibleExit.Y + 1) == MazeFieldType.Corridor)
                {
                    return(CurrentMaze.SetMazeTypeOnPos(possibleExit, MazeFieldType.Exit));
                }
                else
                {
                    possibleExits.Remove(possibleExit);
                }
            }

            // TODO Maybe not the best way to handle this, but the maze is useless without valid exit.
            throw new Exception("Could not find a suitable exit position.");
        }
Пример #6
0
        public override IEnumerable <MazeTransformationStep> InitializeMaze()
        {
            downright = new MazeCoordinate(CurrentMaze.GetWidth() - 1, 0);
            upperleft = new MazeCoordinate(0, CurrentMaze.GetHeight() - 1);

            CurrentMaze.OverrideAllMazeFields(MazeFieldType.Wall);
            return(null);
        }
Пример #7
0
        // This method will handle the room traversal. Find the chosen room, check it to
        // see if it's close to the current. Check for locks, monsters, is it final, etc.
        // At last remove 5 health from the user.
        public void GoRoom(string room)
        {
            Room desiredLocation = (Room)CurrentMaze.GetRoom(room);

            if (desiredLocation != null)
            {
                if (CurrentMaze.IsNeighbor(desiredLocation, (Room)CurrentLocation))
                {
                    if (desiredLocation.IsLocked == true)
                    {
                        Console.WriteLine("--------------LOCKED----------------");
                        Console.WriteLine("Room is locked. You need a key to enter.");
                        Console.WriteLine("--------------LOCKED----------------");
                        return;
                    }
                    this.Health -= 5;
                    if (this.Health <= 0)
                    {
                        this.Die();
                        return;
                    }
                    CurrentLocation = desiredLocation;
                    if (CurrentLocation.HasMonster)
                    {
                        this.Fight();
                    }
                    this.ShowLocation();

                    if (CurrentLocation.IsFinalRoom) // Check for potential win.
                    {
                        CurrentMaze.LevelPassed();
                    }
                    return;
                }
                else
                {
                    Console.WriteLine("You can't walk through walls.");
                    return;
                }
            }
            Console.WriteLine("Invalid location.");
        }
Пример #8
0
        // Try to unlock the chosen room. User needs a key.
        public void Unlock(string roomName)
        {
            var chosenRoom = CurrentMaze.GetRoom(roomName);

            if (chosenRoom == null)
            {
                Console.WriteLine("No such room");
                return;
            }
            if (!CurrentMaze.IsNeighbor(chosenRoom, this.CurrentLocation))
            {
                Console.WriteLine("You can't walk through walls");
            }
            else
            {
                if (chosenRoom.IsLocked)
                {
                    foreach (var item in this.Bag)
                    {
                        if (item is ISpecial)
                        {
                            chosenRoom.IsLocked = false;
                            this.Bag.Remove(item);
                            Console.WriteLine("--------------UNLOCKED----------------");
                            Console.WriteLine("Room unlocked.");
                            Console.WriteLine("--------------UNLOCKED----------------");
                            return;
                        }
                    }
                    Console.WriteLine("You don't have a key.");
                }
                else
                {
                    Console.WriteLine("Room is not locked.");
                }
            }
        }
Пример #9
0
 internal override MazeTransformationStep TryPlaceEntrance()
 {
     // no need to check, the nature of the algorithm will guarantee that all positions on this side are valid entrances.
     return(this.CurrentMaze.SetMazeTypeOnPos(Random.Next(1, CurrentMaze.GetWidth() - 2), 0, MazeFieldType.Entrance));
 }
Пример #10
0
 public override IEnumerable <MazeTransformationStep> InitializeMaze()
 {
     CurrentMaze.OverrideAllMazeFields(MazeFieldType.Wall);
     return(null);
 }
Пример #11
0
        private bool checkIfWallDividesTwoCorridors(MazeCoordinate target)
        {
            MazeCoordinate[] temp = MazeCoordinate.GetHorizontalVerticalAdjacentCoordinates(target);

            int TargetWallAlignsWithCorridors = 0;

            foreach (MazeCoordinate c in temp)
            {
                if (this.CurrentMaze.GetMazeTypeOnPos(c) == MazeFieldType.Corridor)
                {
                    if (target.X == c.X || target.Y == c.Y)
                    {
                        TargetWallAlignsWithCorridors++;
                    }
                }
            }

            // direct connection
            if (TargetWallAlignsWithCorridors > 2)
            {
                return(true);
            }

            temp = MazeCoordinate.GetAllAdjacentCoordinates(target);

            int CorridorFieldsInCloseProximity   = 0;
            HashSet <MazeCoordinate> inProximity = new HashSet <MazeCoordinate>();

            foreach (MazeCoordinate c in temp)
            {
                if (CurrentMaze.GetMazeTypeOnPos(c) != MazeFieldType.Wall)
                {
                    CorridorFieldsInCloseProximity++;
                    inProximity.Add(c);
                }
            }
            // This value can be reduced to create more narrow sideways, maybe make it configurable ?
            if (CorridorFieldsInCloseProximity >= 3)
            {
                return(true);
            }

            if (CorridorFieldsInCloseProximity == 2)
            {
                // check if the corridors are adjacent each other then its OK.
                foreach (MazeCoordinate c in inProximity)
                {
                    var  subset      = inProximity.Where(x => x != c).AsEnumerable();
                    bool allAdjacent = subset.All(x => x.IsAdjacentTo(c));
                    if (allAdjacent)
                    {
                        return(false);
                    }
                }
                return(true);
            }

            if (TargetWallAlignsWithCorridors > 1 && CorridorFieldsInCloseProximity >= 2)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #12
0
		public void startMaze(MazeGraph theMaze)
		{
			myMaze = new CurrentMaze(theMaze);
		}
Пример #13
0
        private IEnumerable <MazeTransformationStep> RekursiveDiv(MazeCoordinate recUpperleft, MazeCoordinate recDownright, bool horizontal)
        {
            int width   = recDownright.X - recUpperleft.X;
            int height  = recUpperleft.Y - recDownright.Y;
            int minSize = 0;

            Strategy currentStrategy = CheckWhichStrategyToUse(width, height);

            if (!(width < minSize && height < minSize))
            {
                // Override the random decision for horizontal/vertical wall placement, this reduces long stretched corridors

                if (width > height)
                {
                    horizontal = false;
                }
                else
                {
                    horizontal = true;
                }

                if (horizontal)
                {// Horizontal
                    int newWallY = TryPlaceWallHorizontal(recUpperleft, recDownright, currentStrategy);
                    if (newWallY > 0)
                    {
                        for (int i = 1; i < width; i++)
                        { // Create wall
                            yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(recUpperleft.X + i, newWallY), MazeFieldType.Wall));
                        }

                        // Place corridor
                        int randX = FindHorizontalCorridor(ref recUpperleft, ref recDownright);
                        yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(randX, newWallY), MazeFieldType.Corridor));

                        // up
                        MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y);
                        MazeCoordinate downrightNew = new MazeCoordinate(recDownright.X, newWallY);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }

                        // down
                        upperleftNew = new MazeCoordinate(recUpperleft.X, newWallY);
                        downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }
                    }
                }
                else
                {// Vertical
                    int newWallX = TryPlaceWallVertical(recUpperleft, recDownright, currentStrategy);
                    if (newWallX > 0)
                    {
                        for (int i = 1; i < height; i++)
                        { // Create Wall
                            yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, recDownright.Y + i), MazeFieldType.Wall));
                        }

                        // Place corridor
                        int randY = FindVerticalCorridor(ref recUpperleft, ref recDownright);
                        yield return(CurrentMaze.SetMazeTypeOnPos(new MazeCoordinate(newWallX, randY), MazeFieldType.Corridor));

                        //left
                        MazeCoordinate upperleftNew = new MazeCoordinate(recUpperleft.X, recUpperleft.Y);
                        MazeCoordinate downrightNew = new MazeCoordinate(newWallX, recDownright.Y);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }

                        //right
                        upperleftNew = new MazeCoordinate(newWallX, recUpperleft.Y);
                        downrightNew = new MazeCoordinate(recDownright.X, recDownright.Y);

                        foreach (var recursiveResult in RekursiveDiv(upperleftNew, downrightNew, Random.Next(2) > 0))
                        {
                            yield return(recursiveResult);
                        }
                    }
                }
            }
        }