Example #1
0
        //Connect all completely unconnected points to a connected point, making sure all cells are reachable.
        void ConnectUnconnectedPoints(LevelBlockRequirements[,] basicGrid)
        {
            int hBlocks = Width / BlockWidth, vBlocks = Height / BlockHeight;

            //Store which blocks weren't connected.
            bool[,] isConnected = new bool[hBlocks, vBlocks];
            List<Point> unconnectedPoints = new List<Point>();
            for (int i = 0; i < hBlocks; i++)
            {
                for (int j = 0; j < vBlocks; j++)
                {
                    isConnected[i, j] = ! basicGrid[i, j].IsOnlyWalls();
                    if (! isConnected[i, j])
                        unconnectedPoints.Add(new Point(i, j));
                }
            }

            bool connectedAnythingThisRound;

            while (unconnectedPoints.Count > 0)
            {
                connectedAnythingThisRound = false;

                List<Point> removedUnconnectedPoints = new List<Point>(); //A list to store points we remove as changing a list during foreach is impossible

                unconnectedPoints.Shuffle(); //Shuffle the points so that they connect in a more random way.

                foreach (Point point in unconnectedPoints)
                {
                    int i = point.X, j = point.Y; //Temporary store the x and y of this point.

                    List<Point> possiblePoints = new List<Point>(); //Points to connect to.
                    if (i > 0 && isConnected[i - 1, j])
                        possiblePoints.Add(new Point(i - 1, j));
                    if (i < hBlocks - 1 && isConnected[i + 1, j])
                        possiblePoints.Add(new Point(i + 1, j));
                    if (j > 0 && isConnected[i, j - 1])
                        possiblePoints.Add(new Point(i, j - 1));
                    if (j < vBlocks - 1 && isConnected[i, j + 1])
                        possiblePoints.Add(new Point(i, j + 1));

                    if (possiblePoints.Count != 0)
                    {
                        //Connect this point to a random other one.
                        ConnectPoints(basicGrid, new List<Point>() { point, possiblePoints.GetRandomItem() });
                        isConnected[i, j] = true; //Mark this point as connected.
                        connectedAnythingThisRound = true;
                        removedUnconnectedPoints.Add(point);
                    }
                }

                foreach (Point point in removedUnconnectedPoints)
                    unconnectedPoints.Remove(point);

                //Give up if we couldn't connect anything at all.
                if (! connectedAnythingThisRound)
                    break;
            }
        }
Example #2
0
        //Connect any number of points on the level grid.
        void ConnectPoints(LevelBlockRequirements[,] basicGrid, List<Point> points)
        {
            if (points.Count == 0)
                return;

            //Choose a random point and connect that to each other point.
            //This automatically guarantees that each point is connected to each other point, as
            //you can always travel to the first point and then to the target point.
            Point point = points.GetRandomItem();

            for (int i = 0; i < points.Count; i++)
            {
                Point otherPoint = points[i];
                if (point == otherPoint)
                    continue;

                //Check how far we have to travel
                Point distanceDifference = new Point(otherPoint.X - point.X, otherPoint.Y - point.Y);

                //And store the directions we have to take into a RandomCollection of directions
                RandomCollection<Direction> directionsToTravel = new RandomCollection<Direction>();

                if (distanceDifference.X < 0)
                    directionsToTravel.Add(Direction.Left, -distanceDifference.X);
                if (distanceDifference.X > 0)
                    directionsToTravel.Add(Direction.Right, distanceDifference.X);
                if (distanceDifference.Y < 0)
                    directionsToTravel.Add(Direction.Up, -distanceDifference.Y);
                if (distanceDifference.Y > 0)
                    directionsToTravel.Add(Direction.Down, distanceDifference.Y);

                //Then actually travel from the first point to the second one.
                Point position = point;
                while (directionsToTravel.Count != 0)
                {
                    switch (directionsToTravel.Take())
                    {
                        case Direction.Left:
                            basicGrid[position.X, position.Y].LeftSideType = SideType.Exit;
                            position.X -= 1;
                            basicGrid[position.X, position.Y].RightSideType = SideType.Exit;
                            break;
                        case Direction.Right:
                            basicGrid[position.X, position.Y].RightSideType = SideType.Exit;
                            position.X += 1;
                            basicGrid[position.X, position.Y].LeftSideType = SideType.Exit;
                            break;
                        case Direction.Up:
                            basicGrid[position.X, position.Y].TopSideType = SideType.Exit;
                            position.Y -= 1;
                            basicGrid[position.X, position.Y].BottomSideType = SideType.Exit;
                            break;
                        case Direction.Down:
                            basicGrid[position.X, position.Y].BottomSideType = SideType.Exit;
                            position.Y += 1;
                            basicGrid[position.X, position.Y].TopSideType = SideType.Exit;
                            break;
                    }
                }
            }
        }