// 맵 생성!
        private void GenerateMap(List <Party> mobs, List <Item> items, Party users)
        {
            // 맵 상의 임의의 영역에 대해서
            // 각 영역은 멤버로 자신이 생성된 방향(horizontal, verical)과 영역좌표(AABB)를 가진다
            // 부모 영역에 대한 참조와 트리에서의 depth정보도 가진다.
            // 만약 자신의 depth가 upper bound보다 작으면 아래의 작업을 수행한다
            // 자신의 반대 방향으로 임의의 위치에서 다시 잘라서 해당 영역을 자식으로 추가
            DungeonTreeNode root = new DungeonTreeNode();

            root.SetRoot(size, random, map, mobs, items, zoneList, userLevel);
            root.GenerateRecursivly();

            // player party와 ring 배치 - 맵 전체를 기반으로
            RingOfErrethAkbe ring = new RingOfErrethAkbe();

            playerPosition = root.RegisterParty(users, true);
            ringPosition   = root.RegisterGameObject(ring);
            items.Add(ring);

            zoneList[map[ringPosition.y, ringPosition.x].zoneId].items.Add(ring);

            // PrintOutMAP();

            // Console.WriteLine( "distance between player and ring" );
            // Console.WriteLine( " :" + Math.Abs( playerPosition.x - ringPosition.x ) + " / "+ Math.Abs( playerPosition.y - ringPosition.y ) );
        }
        public void GenerateRecursivly()
        {
            // Assert(depth <= upperDepth)
            int shortSpan = Math.Min(upperBoundary.x - lowerBoundary.x, upperBoundary.y - lowerBoundary.y) + 1;

            if (depth == upperDepth || shortSpan <= Config.MININUM_SPAN)
            {
                // 여기서 DungeonZone을 생성하자
                // offset을 진행하지만 나중에 통로 지역도 포함하기 위해서 zone의 범위는 offset하기 전으러 설정 = 맵 전체를 커버할 수 있어
                DungeonZone newZone = new DungeonZone(zoneList.Count, lowerBoundary, upperBoundary);
                zoneList.Add(newZone);

                // 조심해!
                // 맵 전체를 두번 순회하고 있음
                // zone id 기록
                for (int i = lowerBoundary.y; i <= upperBoundary.y; ++i)
                {
                    for (int j = lowerBoundary.x; j <= upperBoundary.x; ++j)
                    {
                        map[i, j].zoneId = newZone.zoneId;
                    }
                }

                // leafNode이므로 Bake하고
                // 일정 거리를 offset
                int offset = Math.Min(random.Next(0, Config.MAX_OFFSET), (shortSpan - 3) / 2);

                Offset(offset);

                // 실제 맵에다가 타일과 벽을 기록
                BakeMap();

                // 플레이어, ring, 몹, 아이템들 생성 및 배치
                AllocateObjects(newZone);
            }
            else
            {
                // leafNode가 아니므로 분할한다
                leftChild  = new DungeonTreeNode();
                rightChild = new DungeonTreeNode();

                // children 멤버 변수들 초기화
                leftChild.parent = rightChild.parent = this;

                leftChild.siblingDirection = rightChild.siblingDirection = !siblingDirection;
                leftChild.depth            = rightChild.depth = depth + 1;
                leftChild.upperDepth       = rightChild.upperDepth = upperDepth;
                leftChild.isLeft           = true;
                rightChild.isLeft          = false;

                leftChild.random     = rightChild.random = random;
                leftChild.map        = rightChild.map = map;
                leftChild.mobs       = rightChild.mobs = mobs;
                leftChild.items      = rightChild.items = items;
                leftChild.zoneList   = rightChild.zoneList = zoneList;
                leftChild.usersLevel = rightChild.usersLevel = usersLevel;

                // 실제로 영역 분할
                SliceArea();

                // 조심해!
                // children 단계에서 다시 반복하도록 호출
                // 나중에 task로 처리할까...
                leftChild.GenerateRecursivly();
                rightChild.GenerateRecursivly();

                // 자식 노드들을 연결한다!
                LinkArea();
            }
        }