示例#1
0
 public static void Enclose(Level level, LevelRect rect,
                            TerrainDefinition terrain)
 {
     for (int x = rect.x1; x <= rect.x2; x++)
     {
         for (int y = rect.y1; y <= rect.y2; y++)
         {
             if (x == rect.x1)
             {
                 level.Map[x, y].Terrain = terrain;
                 continue;
             }
             else if (x == rect.x2)
             {
                 level.Map[x, y].Terrain = terrain;
                 continue;
             }
             else
             {
                 if (y == rect.y1)
                 {
                     level.Map[x, y].Terrain = terrain;
                     continue;
                 }
                 else if (y == rect.y2)
                 {
                     level.Map[x, y].Terrain = terrain;
                     continue;
                 }
             }
         }
     }
 }
示例#2
0
        public static HashSet <Cell> FillRect(Level level, LevelRect rect,
                                              Cell start)
        {
            HashSet <Cell> filled = new HashSet <Cell>();
            List <Cell>    open   = new List <Cell>();
            HashSet <Cell> closed = new HashSet <Cell>();

            filled.Add(start);
            open.Add(start);

            while (open.Count > 0)
            {
                for (int i = 0; i < open.Count; i++)
                {
                    closed.Add(open[i]);
                    for (int x = -1; x <= 1; x++)
                    {
                        for (int y = -1; y <= 1; y++)
                        {
                            Vector2Int frontier = open[i].Position;
                            frontier += new Vector2Int(x, y);
                            Cell frontierCell;

                            if (level.Contains(frontier) &&
                                rect.Contains(frontier))
                            {
                                frontierCell = level.GetCell(frontier);
                            }
                            else
                            {
                                continue;
                            }

                            if (closed.Contains(frontierCell))
                            {
                                continue;
                            }

                            if (frontierCell.Walled)
                            {
                                closed.Add(frontierCell);
                                continue;
                            }

                            if (filled.Contains(frontierCell))
                            {
                                closed.Add(frontierCell);
                                continue;
                            }

                            filled.Add(frontierCell);
                            open.Add(frontierCell);
                        }
                    }
                    open.RemoveAt(i);
                }
            }
            return(filled);
        }
示例#3
0
        public override void Run(Level level)
        {
            List <Leaf> leaves = new List <Leaf>();

            Leaf root = new Leaf(0, 0, level.Size.x, level.Size.y);

            leaves.Add(root);

            bool didSplit = true;

            while (didSplit)
            {
                didSplit = false;
                for (int i = leaves.Count - 1; i >= 0; i--)
                {
                    if (leaves[i].LeftChild == null &&
                        leaves[i].RightChild == null)
                    {
                        if (leaves[i].Width > Leaf.MaxLeafSize ||
                            leaves[i].Height > Leaf.MaxLeafSize ||
                            OneChanceIn(4))
                        {
                            if (leaves[i].Split())
                            {
                                leaves.Add(leaves[i].LeftChild);
                                leaves.Add(leaves[i].RightChild);
                                didSplit = true;
                            }
                        }
                    }
                }
            }
            root.CreateRooms(minRoomSize, tightFill);
            for (int i = 0; i < leaves.Count; i++)
            {
                if (leaves[i].Room != null)
                {
                    Utils.FillRectTerrain(level, leaves[i].Room, terrain);
                }

                if (leaves[i].Halls != null)
                {
                    foreach (LevelRect hall in leaves[i].Halls)
                    {
                        LevelRect rect = new LevelRect(
                            new Vector2Int(hall.x1, hall.y1),
                            new Vector2Int(
                                hall.x2 - hall.x1 + 2,
                                hall.y2 - hall.y1 + 2));
                        Utils.FillRectTerrain(level, hall, terrain);
                    }
                }
            }
        }
示例#4
0
 public static void FillRectTerrain(Level level, LevelRect rect,
                                    TerrainDefinition terrain)
 {
     for (int x = rect.x1; x < rect.x2; x++)
     {
         for (int y = rect.y1; y < rect.y2; y++)
         {
             if (level.TryGetCell(x, y, out Cell c))
             {
                 level.Map[x, y].Terrain = terrain;
             }
         }
     }
 }
        public override void Run(Level level)
        {
            rect = new LevelRect(new Vector2Int(), new Vector2Int(
                                     level.Size.x - 1, level.Size.y - 1));

            for (int iterations = 0; iterations < 10; iterations++)
            {
                RandomFillMap(level);
                Utils.Enclose(level, wall);
                MakeCaverns(level);

                if (FillDisconnected(level))
                {
                    return;
                }
            }

            throw new System.Exception("Cellular automata failed after 10 tries.");
        }
示例#6
0
            public LevelRect GetRoom()
            {
                if (Room != null)
                {
                    return(Room);
                }
                else
                {
                    LevelRect lRoom = null;
                    LevelRect rRoom = null;

                    if (LeftChild != null)
                    {
                        lRoom = LeftChild.GetRoom();
                    }
                    if (RightChild != null)
                    {
                        rRoom = RightChild.GetRoom();
                    }

                    if (lRoom == null && rRoom == null)
                    {
                        return(null);
                    }
                    else if (rRoom == null)
                    {
                        return(lRoom);
                    }
                    else if (lRoom == null)
                    {
                        return(rRoom);
                    }
                    else if (OneChanceIn(2))
                    {
                        return(lRoom);
                    }
                    else
                    {
                        return(rRoom);
                    }
                }
            }
示例#7
0
            /// <summary>
            /// Generates all rooms and hallways for this Leaf and all its children.
            /// </summary>
            public void CreateRooms(int minRoomSize, bool tightFill)
            {
                if (LeftChild != null || RightChild != null)
                {
                    if (LeftChild != null)
                    {
                        LeftChild.CreateRooms(minRoomSize, tightFill);
                    }
                    if (RightChild != null)
                    {
                        RightChild.CreateRooms(minRoomSize, tightFill);
                    }

                    if (LeftChild != null && RightChild != null)
                    {
                        CreateHall(LeftChild.GetRoom(), RightChild.GetRoom());
                    }
                }
                else
                {
                    Vector2Int roomSize;
                    Vector2Int roomPos;

                    if (tightFill)
                    {
                        roomSize = new Vector2Int(Width - 1, Height - 1);
                    }
                    else
                    {
                        roomSize = new Vector2Int(
                            RangeInclusive(minRoomSize, Width - 2),
                            RangeInclusive(minRoomSize, Height - 2));
                    }

                    roomPos = new Vector2Int(
                        RangeInclusive(1, Width - roomSize.x - 1),
                        RangeInclusive(1, Height - roomSize.y - 1));
                    Room = new LevelRect(
                        new Vector2Int(X + roomPos.x, Y + roomPos.y),
                        new Vector2Int(roomSize.x, roomSize.y));
                }
            }
示例#8
0
            public void CreateHall(LevelRect l, LevelRect r)
            {
                Halls = new Stack <LevelRect>();

                Vector2Int p1 = new Vector2Int(
                    RangeInclusive(l.x1 + 1, l.x2 - 2),
                    RangeInclusive(l.y1 + 1, l.y2 - 2));
                Vector2Int p2 = new Vector2Int(
                    RangeInclusive(r.x1 + 1, r.x2 - 2),
                    RangeInclusive(r.y1 + 1, r.y2 - 2));

                int w = p2.x - p1.x;
                int h = p2.y - p1.y;

                if (w < 0)
                {
                    if (h < 0)
                    {
                        if (CoinFlip())
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p1.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p2.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                        else
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p2.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p2.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                    }
                    else if (h > 0)
                    {
                        if (CoinFlip())
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p1.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p1.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                        else
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p2.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p1.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                    }
                    else // if (h == 0)
                    {
                        Halls.Push(new LevelRect(
                                       new Vector2Int(p2.x, p2.y),
                                       new Vector2Int(Mathf.Abs(w), 1)));
                    }
                }
                else if (w > 0)
                {
                    if (h < 0)
                    {
                        if (CoinFlip())
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p2.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p2.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                        else
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p1.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p2.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                    }
                    else if (h > 0)
                    {
                        if (CoinFlip())
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p1.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p2.x, p1.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                        else
                        {
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p2.y),
                                           new Vector2Int(Mathf.Abs(w), 1)));
                            Halls.Push(new LevelRect(
                                           new Vector2Int(p1.x, p1.y),
                                           new Vector2Int(1, Mathf.Abs(h))));
                        }
                    }
                    else // if (h == 0)
                    {
                        Halls.Push(new LevelRect(
                                       new Vector2Int(p1.x, p1.y),
                                       new Vector2Int(Mathf.Abs(w), 1)));
                    }
                }
                else // if (w == 0)
                {
                    if (h < 0)
                    {
                        Halls.Push(new LevelRect(
                                       new Vector2Int(p2.x, p2.y),
                                       new Vector2Int(1, Mathf.Abs(h))));
                    }
                    else if (h > 0)
                    {
                        Halls.Push(new LevelRect(
                                       new Vector2Int(p1.x, p1.y),
                                       new Vector2Int(1, Mathf.Abs(h))));
                    }
                }
            }