void ApplyRoom(int x, int y, RoomGenerator generator)
        {
            int rowCount = gridDesc.GetLength(0);
            int colCount = gridDesc.GetLength(1);

            for (int i = 0; i < rowCount; ++i)
            {
                for (int j = 0; j < colCount; ++j)
                {
                    if (gridDesc[i, j])
                    {
                        var grid = generator.GetGrid(x + i, y + j);
                        grid.owner = this;
                        gridList.Add(grid);
                    }
                }
            }
        }
        public bool IsSingleConnected(int x, int y, RoomGenerator generator)
        {
            int connectCount = 0;
            int rowCount     = gridDesc.GetLength(0);
            int colCount     = gridDesc.GetLength(1);

            for (int i = 0; i < rowCount; ++i)
            {
                for (int j = 0; j < colCount; ++j)
                {
                    if (gridDesc[i, j])
                    {
                        var up = generator.GetGrid(x + i, y + j + 1);

                        if (up != null && up.owner != null && up.owner != this)
                        {
                            ++connectCount;
                        }

                        var down = generator.GetGrid(x + i, y + j - 1);
                        if (down != null && down.owner != null && down.owner != this)
                        {
                            ++connectCount;
                        }

                        var left = generator.GetGrid(x + i - 1, y + j);
                        if (left != null && left.owner != null && left.owner != this)
                        {
                            ++connectCount;
                        }

                        var right = generator.GetGrid(x + i + 1, y + j);
                        if (right != null && right.owner != null && right.owner != this)
                        {
                            ++connectCount;
                        }
                    }
                }
            }

            return(connectCount == 1);
        }
        bool IsConnectToRooms(int x, int y, RoomGenerator generator, HashSet <RoomType> roomTypes)
        {
            int rowCount = gridDesc.GetLength(0);
            int colCount = gridDesc.GetLength(1);

            for (int i = 0; i < rowCount; ++i)
            {
                for (int j = 0; j < colCount; ++j)
                {
                    if (gridDesc[i, j])
                    {
                        var up = generator.GetGrid(x + i, y + j + 1);

                        if (up != null && up.owner != null && roomTypes.Contains(up.owner.roomType))
                        {
                            return(true);
                        }

                        var down = generator.GetGrid(x + i, y + j - 1);
                        if (down != null && down.owner != null && roomTypes.Contains(down.owner.roomType))
                        {
                            return(true);
                        }

                        var left = generator.GetGrid(x + i - 1, y + j);
                        if (left != null && left.owner != null && roomTypes.Contains(left.owner.roomType))
                        {
                            return(true);
                        }

                        var right = generator.GetGrid(x + i + 1, y + j);
                        if (right != null && right.owner != null && roomTypes.Contains(right.owner.roomType))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public bool BeyondBossRoom(int x, int y, RoomGenerator generator)
        {
            int rowCount = gridDesc.GetLength(0);
            int colCount = gridDesc.GetLength(1);

            for (int i = 0; i < rowCount; ++i)
            {
                for (int j = 0; j < colCount; ++j)
                {
                    if (gridDesc[i, j])
                    {
                        var up = generator.GetGrid(x + i, y + j + 1);
                        if (up != null && up.owner != null && up.owner.roomType == RoomType.Boss)
                        {
                            return(true);
                        }

                        var down = generator.GetGrid(x + i, y + j - 1);
                        if (down != null && down.owner != null && down.owner.roomType == RoomType.Boss)
                        {
                            return(true);
                        }

                        var left = generator.GetGrid(x + i - 1, y + j);
                        if (left != null && left.owner != null && left.owner.roomType == RoomType.Boss)
                        {
                            return(true);
                        }
                        var right = generator.GetGrid(x + i + 1, y + j);
                        if (right != null && right.owner != null && right.owner.roomType == RoomType.Boss)
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
        public bool IsFitSize(int x, int y, RoomGenerator generator)
        {
            int rowCount = gridDesc.GetLength(0);
            int colCount = gridDesc.GetLength(1);

            for (int i = 0; i < rowCount; ++i)
            {
                for (int j = 0; j < colCount; ++j)
                {
                    if (gridDesc[i, j])
                    {
                        var grid = generator.GetGrid(x + i, y + j);
                        if (grid == null || grid.owner != null)
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }
        //return is there exist an offset of gridDesc, can place the room
        public bool Place(int x, int y, RoomGenerator generator, bool singleConnected = false, HashSet <RoomType> avoidConnectRoom = null)
        {
            int rowCount = gridDesc.GetLength(0);
            int colCount = gridDesc.GetLength(1);

            for (int offsetX = 0; offsetX < rowCount; ++offsetX)
            {
                for (int offsetY = 0; offsetY < colCount; ++offsetY)
                {
                    //x,y must be filled with a non-empty grid
                    if (gridDesc[offsetX, offsetY] && IsFitSize(x - offsetX, y - offsetY, generator))
                    {
                        if (singleConnected && !IsSingleConnected(x - offsetX, y - offsetY, generator))
                        {
                            continue;
                        }

                        if (avoidConnectRoom != null && IsConnectToRooms(x, y, generator, avoidConnectRoom))
                        {
                            continue;
                        }

                        ApplyRoom(x - offsetX, y - offsetY, generator);
                        MarkUnborderDoors();

                        if (roomType != RoomType.Init && !CheckConnectable(generator))
                        {
                            Revert();
                            return(false);
                        }

                        return(true);
                    }
                }
            }

            return(false);
        }
        public bool CheckConnectable(RoomGenerator generator)
        {
            var hset = generator.GetConnectedRoom(this);

            return(hset.Count > 0);
        }