python实现地牢迷宫生成

本文介绍了如何使用Python实现地牢迷宫的生成,包括定义地牢的基本属性,随机生成不会重叠的房间,创建包围房间和通道的墙壁,设计门口,并通过A*算法连接通道,最终实现一个完整的地牢迷宫生成过程。文中还展示了各阶段生成的效果。
摘要由CSDN通过智能技术生成

基本属性

定义当前地牢的等级,地图长宽,房间数量,房间的最小最大长度,如下

class Map:
    def __init__(self):
        self.width = 30
        self.heigh = 30
        self.level = 1
        self.roomNum = 5
        self.map = np.zeros((self.heigh,self.width))
        self.roomMin = 3
        self.roomMax = 11

生成房间

编写initRoom()随机生成房间,限制最多循环次数,为了简单起见,先做一个不会重叠的房间。基本思路是:随机房间的中心点,随机房间的长宽,再进行判断房间有无重叠(在后续会生成通道,简单起见在这里也保证房间不会紧贴),若无重叠,房间有效,房间数加1。贴代码

    def initRoom(self):
        count = 0
        roomCount = 1
        while True:
            count += 1
            if count > 300:
                break
            if roomCount > self.roomNum:
                break
            x = random.randint(1,self.width-1)
            y = random.randint(1,self.heigh-1)
            wd = random.randint(self.roomMin,self.roomMax)
            ht = random.randint(self.roomMin, self.roomMax)
            r1 = ceil(y - ht/2)
            r2 = ceil(y + ht/2)
            c1 = ceil(x - wd/2)
            c2 = ceil(x + wd/2)
            if r1 < 1:
                r1 = 1
            if r2 >= self.heigh - 1:
                r2 = self.heigh - 2
            if c1 < 1:
                c1 = 1
            if c2 >= self.width - 1:
                c2 = self.width - 2
            w = c2 - c1 + 1
            h = r2 - r1 + 1
            if h / w >= 3 or w / h >= 3: #保证房间不是细长的
                continue
            judge = self.isValidRoom(r1,r2,c1,c2)
            if judge == 0:
                roomCount += 1
                self.room.append(Room(r1,r2,c1,c2))
                for i in range(r1,r2):
                    for j in range(c1,c2):
                        self.map[i,j] = 1
                        
    def isValidRoom(self,r1,r2,c1,c2):
        #检测有无覆盖
        for i in range(r1,r2):
            for j in range(c1,c2):
                if self.map[i,j] == 1:
                    return -1
        #检测有无紧贴房间
        for i in range(r1,r2):
            if self.map[i,c1-1] == 1 or self.map[i,c2+1] == 1:
                return 2
        for i in range(c1,c2):
            if self.map[r1-1,i] == 1 or self.map[r2+1,i] == 1:
                return 2
        return 0

看一下效果
生成五个房间

生成墙壁

编写initTile()生成包围房间和通道的墙壁,直接贴代码

    def initTile(self):
        offset = [[-1,0],[0,-1],[1,0],[0,1],[-1,-1],[1,1],[1,-1],[-1,1]]
        for i in range(self.heigh):
            for j in range(self.width):
                if self.map[i,j] == 0:
                    tag = 0
                    for it in offset:
                        if i+it[0] >= self.heigh or j+it[1] >= self.width or i+it[0] < 0 or j+it[1] < 0:
                            continue
                        if self.map[i+it[0],j+it[1]] != 3 and self.map[i+it[0],j+it[1]] != 4:
                            tag += self.map[i+it[0],j+it[1]]
                    if tag:
                        self.map[i,j] = 3

效果
有墙壁的房间

生成门口

随机选取房间的一个外围点当做房门,思路是在房间的长宽内随机两个数作为偏移量,预定义好四个方向的覆盖模板对偏移量进行加权和偏置,在这里我编写房间的类,加进地图的属性列表里。
除此之外,房间连通的思路是:在所有房间列表中随机抽出两个房间,将这两个房间连通,再随机选一个房间加回原来的房间列表,直至最后列表里只剩下一个房间。那么现在先来生成房门,代码如下

class Room():
    def __init__(self,r1,r2,c1,c2):
        w = c2 - c1
        h = r2 - r1
        self.width = w
        self.height = h
        self.cx = c1 + ceil(w/2)
        self.cy = r1 + ceil(h/2)
        self.xStart = c1
        self.xEnd = c2 - 1
        self.yStart = r1
        self.yEnd = r2 - 1

    def randomTile(self):
        direction = random.randint(0,3)
        dir = [[0,1,-1,0],[1,0,0,-1],[1,0,0,self.height],[0,1,self.width,0]]
        x_off = random.randint(0,self.width-1)
        y_off = random.randint(0,self.height-1)
        x = self.xStart + x_off*dir[direction
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值