//Place a hidden room that can reduce the other 2 rooms' "Graph Distance"
        void PlaceHiddenRoom()
        {
            List <Type> pools = generateConfig.hiddenRoomPools;

            if (pools.Count < 1)
            {
                return;
            }

            RoomNode room = null;
            int      rnd  = UnityEngine.Random.Range(0, pools.Count);

            room          = (RoomNode)Activator.CreateInstance(pools[rnd]);
            room.roomType = RoomType.Hidden;

            HashSet <RoomType> avoidConnectTo = new HashSet <RoomType>()
            {
                RoomType.Boss,
            };

            CalculateRoomDistance();
            int         canReduceLength  = 0;
            List <Grid> connectableGrids = GetConnectableGrids();

            for (int i = 0; i < connectableGrids.Count; ++i)
            {
                var gridIndex = connectableGrids[i].index;
                var tmpRoom   = (RoomNode)Activator.CreateInstance(pools[rnd]);
                if (tmpRoom.Place(gridIndex.x, gridIndex.y, this, false, avoidConnectTo))
                {
                    var        hset  = GetConnectedRoom(tmpRoom);
                    RoomNode[] rooms = new RoomNode[hset.Count];
                    hset.CopyTo(rooms);

                    if (room.gridList.Count <= 0)
                    {
                        room = tmpRoom;

                        for (int fromRoom = 0; fromRoom < rooms.Length; ++fromRoom)
                        {
                            for (int toRoom = fromRoom + 1; toRoom < rooms.Length; ++toRoom)
                            {
                                canReduceLength = Mathf.Max(canReduceLength, roomDistanceMap[fromRoom, toRoom]);
                            }
                        }
                    }
                    else
                    {
                        int tmpCanreduce = 0;
                        for (int fromRoom = 0; fromRoom < rooms.Length; ++fromRoom)
                        {
                            for (int toRoom = fromRoom + 1; toRoom < rooms.Length; ++toRoom)
                            {
                                tmpCanreduce = Mathf.Max(tmpCanreduce, roomDistanceMap[fromRoom, toRoom]);
                            }
                        }

                        if (tmpCanreduce > canReduceLength)
                        {
                            room.Revert();
                            room            = tmpRoom;
                            canReduceLength = tmpCanreduce;
                        }
                        else
                        {
                            tmpRoom.Revert();
                        }
                    }
                }
            }

            if (room.gridList.Count > 0)
            {
                room.roomType = RoomType.Hidden;
                ++curGenerateInfo.hiddenRoomCount;
                usedGrid += room.gridList.Count;
                roomList.Add(room);
                room.SetPosition(room.gridList[0].position);
                room.RepositionDoors();
                room.CalculateTransportPos();
            }
            else
            {
                Debug.LogError("Generate Hidden Room failed");
            }
        }
        void PlaceSuperHiddenRoom()
        {
            RoomNode    bossRoom = GetBossRoom();
            List <Type> pools    = generateConfig.spHiddenRoomPools;

            if (pools.Count < 1)
            {
                return;
            }
            RoomNode room = null;

            int rnd = UnityEngine.Random.Range(0, pools.Count);

            room = (RoomNode)Activator.CreateInstance(pools[rnd]);

            HashSet <RoomType> avoidConnectTo = new HashSet <RoomType>()
            {
                RoomType.Reward,
                RoomType.Shop,
                RoomType.Hidden,
                RoomType.Boss,
            };

            float       maxDis           = 0f;
            List <Grid> connectableGrids = GetConnectableGrids();

            //make it 0~n : Far from boss room to Near boss room
            connectableGrids.Sort((a, b) =>
            {
                float disA = Vector3.Distance(bossRoom.gridList[0].position, a.position);
                float disB = Vector3.Distance(bossRoom.gridList[0].position, b.position);

                maxDis = Mathf.Max(maxDis, disA);
                maxDis = Mathf.Max(maxDis, disB);

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

            for (int i = 0; i < connectableGrids.Count; ++i)
            {
                var gridIndex = connectableGrids[i].index;
                var tmpRoom   = (RoomNode)Activator.CreateInstance(pools[rnd]);
                if (tmpRoom.Place(gridIndex.x, gridIndex.y, this, true))
                {
                    if (room.gridList.Count <= 0)
                    {
                        room = tmpRoom;
                    }
                    else
                    {
                        int   rndDis = Random(0, (int)maxDis);
                        float disA   = Vector3.Distance(bossRoom.gridList[0].position, tmpRoom.gridList[0].position);
                        if (rndDis > disA)
                        {
                            room.Revert();
                            room = tmpRoom;
                        }
                    }
                }
            }

            if (room.gridList.Count > 0)
            {
                room.roomType = RoomType.SuperHidden;
                ++curGenerateInfo.spHiddenRoomCount;
                usedGrid += room.gridList.Count;
                roomList.Add(room);
                room.SetPosition(room.gridList[0].position);
                room.RepositionDoors();
                room.CalculateTransportPos();
            }
            else
            {
                Debug.LogError("Generate SPHidden Room failed");
            }
        }