Random map algorithm (optimization algorithm dungeon)

1 Introduction

If, when reading this article, it is recommended not understand the dungeon to see what the algorithm, the algorithm dungeon Not here, just talk about the bad dungeon algorithm places, how to expand and optimize the dungeon algorithm, the following is a link to the dungeon algorithm : https://www.cnblogs.com/sufferingStriver/p/8834862.html

2. dungeon algorithm shortcomings

After seen the dungeon algorithm, now several needs, such as is necessary to generate a map with n the room, but the room dungeon algorithm will not satisfy the condition removed in the calculation, there is such a requirement must have some room only one entrance, dungeon algorithm at this time there is no way to get this demand, since the minimum spanning tree is no way to solve this particular point, it is necessary to find ways to expand it.

3. Optimization and expansion algorithm

It should be optimization dispersed room location, the method first thought is a random area randomly put n rooms, if and room location before setting crashed on re-randomized, so how to judge the random size of the area, if the random the maximum area directly, no matter how many rooms before so will not overlap, but not so designated, the room density will be too scattered, one room to another room may be too far, not so designated, it can determine how to best random size of the area? The first idea is to add all the width of the room is the greatest width of the random region, all add up to a high maximum height is random region, as shown:

 

But this area is the best it random? This is the worst case will be able to put down all the rooms, can be seen in this area is too big, so need to find ways to optimize this random size of the area, so after some thought, so you can optimize the size of the random area, is to find room n the maximum width and the maximum height value, FIG 3 is above the maximum height of the room, the maximum width of the room, as shown below:

房间1放在(MaxWidth,MaxHeight),房间2,3放在(2*MaxWidth,2*MaxHeight),房间4,5,6放在(3*MaxWidth,3*MaxHeight),房间7,8,9,10放在(4*MaxWidth,4*MaxHeight),房间11,12,13,14,15放在(5*MaxWidth,5*MaxHeight),这样就算出现最坏情况,也没有问题的,慢慢增加随机区域,为什么一定可以容下所有房间?大家可以自己思考一下,代码如下:

    bool SetRandomRoom(int i, int MaxWidth, int MaxHeight,uint Count)
    {
        int x = Random.Range(0, MaxWidth);
        int y = Random.Range(0, MaxHeight);

        Rooms[i].SetLocation(x, y);
        if(Count == 0x0fff)//栈溢出保护
            return false;

        for (int j = 0; j < i - 1; j++)
        {
            if (isOverLap(Rooms[i], Rooms[j]))//如果重叠
            {
                SetRandomRoom(i, MaxWidth, MaxHeight, Count+1);
                break;
            }
        }
        return true;
    }

    void SetMapPoint()
    {
        int i,j,k = 0,k1=1,MaxHeight=0,MaxWidth=0,MaxWidthCell=0,MaxHeightCell=0;
        for (i = 0; i < Rooms.Count; i++)//打散房间
        {
            for (j = i + 1; j < Rooms.Count; j++)
            {
                if (Random.Range(0, 2) == 1)
                    SwapRoomInfo(i, j);                
            }
            if (MaxWidthCell < Room[i].Rect.Width)
                MaxWidthCell = Room[i].Rect.Width;
            if (MaxHeightCell < Room[i].Rect.Height)
                MaxHeightCell = Room[i].Rect.Height;
        }

        for (i = 0; i < Room.Count; i++)
        {
            if (k == i)//控制房间密度
            {
                k = k + k1;
                k1 = k1 + 1;
                MaxWidth = MaxWidth + MaxWidthCell;
                MaxHeightCell = MaxHeight + MaxHeightCell;
            }
            if (SetRandomRoom(i, MaxWidth, MaxHeight, 0) == false)
            {
                //TODO 防止意外(回滚所有随机)
                k = 0;k1 = 1;
                MaxWidth = MaxHeight = 0;
                i = 0;
            }
        }          
    }

这样就可以把房间位置散开,而且比较密集。之后最小生成树连接这些点,然后如何去添加只有单个入口的房间呢,需要在这个最小生成树里用贪心算法去添加这些点,随机这些特殊点(确保这些和之前的房间和路线碰撞),然后连接这些特殊点,但是这里有一个问题,因为随机函数的问题,可能多次随机都有无法找到连接的路线,这样的话尝试了一定次数之后,这样我们需要遍历随机范围将将剩余的特殊点都连接进去

4.终结

如果有更好的方法或者疑问,大家可以留言讨论一下,如果需要demo工程的小伙伴,请大家留言一下~,笔者会抽空用unity写一个demo出来提供下载。

发布了26 篇原创文章 · 获赞 3 · 访问量 1万+

Guess you like

Origin blog.csdn.net/m0_37920739/article/details/100183861