python实现地牢迷宫生成

python实现地牢迷宫生成

  • 基本属性
  • 生成房间
  • 生成墙壁
  • 生成门口
  • 生成通道

基本属性

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

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

生成房间

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

    def initRoom(self):count = 0roomCount = 1while True:count += 1if count > 300:breakif roomCount > self.roomNum:breakx = 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 = 1if r2 >= self.heigh - 1:r2 = self.heigh - 2if c1 < 1:c1 = 1if c2 >= self.width - 1:c2 = self.width - 2w = c2 - c1 + 1h = r2 - r1 + 1if h / w >= 3 or w / h >= 3: #保证房间不是细长的continuejudge = self.isValidRoom(r1,r2,c1,c2)if judge == 0:roomCount += 1self.room.append(Room(r1,r2,c1,c2))for i in range(r1,r2):for j in range(c1,c2):self.map[i,j] = 1def 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 2for i in range(c1,c2):if self.map[r1-1,i] == 1 or self.map[r2+1,i] == 1:return 2return 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 = 0for 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:continueif 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 - c1h = r2 - r1self.width = wself.height = hself.cx = c1 + ceil(w/2)self.cy = r1 + ceil(h/2)self.xStart = c1self.xEnd = c2 - 1self.yStart = r1self.yEnd = r2 - 1def 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][0] + dir[direction][2]y = self.yStart + y_off*dir[direction][1] + dir[direction][3]if y == 0 or x == 0:return self.randomTile()else:return [y,x]
class Map:def initPath(self):#初始化门rm = self.room.copy()while len(rm) > 1:r1 = random.choice(rm)rm.remove(r1)r2 = random.choice(rm)rm.remove(r2)point0 = r1.randomTile()while point0[0] == self.heigh-1 or point0[1] == self.width-1:point0 = r1.randomTile()self.map[point0[0],point0[1]] = 2self.door.append(point0)self.breakTile(point0)point1 = r2.randomTile()while point1[0] == self.heigh-1 or point1[1] == self.width-1:point1 = r2.randomTile()self.map[point1[0],point1[1]] = 2self.breakTile(point1)self.door.append(point1)rn = random.randint(0,1)#a*算法寻找从point0到point1的路径#self.aStar(point0,point1)if rn == 0:rm.append(r1)else:rm.append(r2)def breakTile(self,p):# 打通堵住的周围的墙壁if self.map[p[0] - 1, p[1]] == 1 and self.map[p[0] + 1, p[1]] == 3:self.map[p[0] + 1, p[1]] = 2elif self.map[p[0], p[1] - 1] == 1 and self.map[p[0], p[1] + 1] == 3:self.map[p[0], p[1] + 1] = 2elif self.map[p[0] + 1, p[1]] == 1 and self.map[p[0] - 1, p[1]] == 3:self.map[p[0] - 1, p[1]] = 2elif self.map[p[0], p[1] + 1] == 1 and self.map[p[0], p[1] - 1] == 3:self.map[p[0], p[1] - 1] = 2

看下效果
有房门的房间

生成通道

接着完善上述函数,在随机选取房门后,连接两个房门。
在这我选择的是A星算法,打通两个房门,直接上代码

    def aStar(self,p0,p1):open_list = []close_list = []offset = [[-1,0],[0,-1],[1,0],[0,1]]f = h = abs(p0[0] - p1[0]) * 10 + abs(p0[1] - p1[1]) * 10g = 0def isInClose(p):for it in close_list:if it.value[3] == p:return Truereturn Falsedef isInOpen(p):for it in open_list:if it.value[3] == p:return Truereturn Falsedef findFather(p):for it in close_list:if it.value[3] == p:return it.value[4]return [-1,-1]def findInOpen(p):for it in open_list:if it.value[3] == p:return itreturn Noneopen_list.append(Node([f,g,h,p0,[-1,-1]]))while open_list:#for it in open_list:#    print(it.value)open_list.sort(key=(lambda x:x.value[0]))f_min = open_list[0]close_list.append(f_min)open_list.remove(f_min)for it in offset:p2 = [f_min.value[3][0]+it[0], f_min.value[3][1]+it[1]]if p2[0] == p1[0] and p2[1] == p1[1]:#找到close_list.append(Node([f,g,h,p2,f_min]))p_father = f_min.value[3]while True:self.map[p_father[0],p_father[1]] = 2p_father = findFather(p_father)if p_father[0] == -1:breakself.map[p0[0], p0[1]] = 4returnif p2[0] < 0 or p2[0] >= self.heigh or p2[1] < 0 or p2[1] >= self.width:continueif (self.map[p2[0],p2[1]] != 0 and self.map[p2[0],p2[1]] != 2 and self.map[p2[0],p2[1]] != 4) or isInClose(p2):continueh = abs(p2[0] - p1[0]) * 10 + abs(p2[1] - p1[1]) * 10g = f_min.value[1] + 10f = h + gif not isInOpen(p2):open_list.append(Node([f,g,h,p2,f_min.value[3]]))else:#比较最小的G 值temp = findInOpen(p2)if g < temp.value[1]:open_list.remove(temp)open_list.append(Node([f,g,h,p2,f_min.value[3]]))

效果
在这里插入图片描述
这样,一个随机房间的地牢就已经生成,贴上完整代码

import random
import numpy as np
from math import ceilclass Node():def __init__(self, val=None):if val is None:val = [0, 0, 0, [-1, -1], [-1, -1]]self.value = valclass Room():def __init__(self,r1,r2,c1,c2):w = c2 - c1h = r2 - r1self.width = wself.height = hself.cx = c1 + ceil(w/2)self.cy = r1 + ceil(h/2)self.xStart = c1self.xEnd = c2 - 1self.yStart = r1self.yEnd = r2 - 1def info(self):print('r1 c1 r2 c2:  ',self.yStart,self.xStart,self.yEnd,self.xEnd)print('cx    cy:     ',self.cx,self.cy)print('width height: ',self.width,self.height)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][0] + dir[direction][2]y = self.yStart + y_off*dir[direction][1] + dir[direction][3]if y == 0 or x == 0:return self.randomTile()else:return [y,x]class Map:def __init__(self):self.width = 30self.heigh = 30self.level = 1self.roomNum = 5#0 is null, 1 is room, 2 is path, 3 is wall, 4 is door, 5 is up stair, 6 is downstairself.map = np.zeros((self.width,self.heigh))self.roomMin = 3self.roomMax = 11self.room = []self.door = []self.initRoom()self.initTile()self.initPath()#self.initTile()#self.initDoor()def initRoom(self):count = 0roomCount = 1while True:count += 1if count > 300:breakif roomCount > self.roomNum:breakx = random.randint(1,self.width-1)y = random.randint(1,self.heigh-1)wd = random.randint(self.roomMin,self.roomMax)if wd % 2 == 0:wd += 1ht = random.randint(self.roomMin, self.roomMax)if ht % 2 == 0:ht += 1r1 = ceil(y - ht/2)r2 = ceil(y + ht/2)c1 = ceil(x - wd/2)c2 = ceil(x + wd/2)if r1 < 1:r1 = 1if r2 >= self.heigh - 1:r2 = self.heigh - 2if c1 < 1:c1 = 1if c2 >= self.width - 1:c2 = self.width - 2w = c2 - c1 + 1h = r2 - r1 + 1if w == 0:continueif h == 0:continueif h / w >= 3 or w / h >= 3:continuejudge = self.isValidRoom(r1,r2,c1,c2)if judge == 0:roomCount += 1self.room.append(Room(r1,r2,c1,c2))for i in range(r1,r2):for j in range(c1,c2):self.map[i,j] = 1def initPath(self):#初始化门rm = self.room.copy()while len(rm) > 1:r1 = random.choice(rm)rm.remove(r1)r2 = random.choice(rm)rm.remove(r2)point0 = r1.randomTile()while point0[0] == self.heigh-1 or point0[1] == self.width-1:point0 = r1.randomTile()self.map[point0[0],point0[1]] = 2self.door.append(point0)self.breakTile(point0)point1 = r2.randomTile()while point1[0] == self.heigh-1 or point1[1] == self.width-1:point1 = r2.randomTile()self.map[point1[0],point1[1]] = 2self.breakTile(point1)self.door.append(point1)rn = random.randint(0,1)#a*算法寻找从point0到point1的路径self.aStar(point0,point1)if rn == 0:rm.append(r1)else:rm.append(r2)def initDoor(self):for it in self.door:self.map[it[0],it[1]] = 4def breakTile(self,p):# 打通堵住的周围的墙壁if self.map[p[0] - 1, p[1]] == 1 and self.map[p[0] + 1, p[1]] == 3:self.map[p[0] + 1, p[1]] = 2elif self.map[p[0], p[1] - 1] == 1 and self.map[p[0], p[1] + 1] == 3:self.map[p[0], p[1] + 1] = 2elif self.map[p[0] + 1, p[1]] == 1 and self.map[p[0] - 1, p[1]] == 3:self.map[p[0] - 1, p[1]] = 2elif self.map[p[0], p[1] + 1] == 1 and self.map[p[0], p[1] - 1] == 3:self.map[p[0], p[1] - 1] = 2def 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 = 0for 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:continueif 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] = 3def 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 2for i in range(c1,c2):if self.map[r1-1,i] == 1 or self.map[r2+1,i] == 1:return 2return 0def aStar(self,p0,p1):open_list = []close_list = []offset = [[-1,0],[0,-1],[1,0],[0,1]]f = h = abs(p0[0] - p1[0]) * 10 + abs(p0[1] - p1[1]) * 10g = 0def isInClose(p):for it in close_list:if it.value[3] == p:return Truereturn Falsedef isInOpen(p):for it in open_list:if it.value[3] == p:return Truereturn Falsedef findFather(p):for it in close_list:if it.value[3] == p:return it.value[4]return [-1,-1]def findInOpen(p):for it in open_list:if it.value[3] == p:return itreturn Noneopen_list.append(Node([f,g,h,p0,[-1,-1]]))while open_list:#for it in open_list:#    print(it.value)open_list.sort(key=(lambda x:x.value[0]))f_min = open_list[0]close_list.append(f_min)open_list.remove(f_min)for it in offset:p2 = [f_min.value[3][0]+it[0], f_min.value[3][1]+it[1]]if p2[0] == p1[0] and p2[1] == p1[1]:#找到close_list.append(Node([f,g,h,p2,f_min]))p_father = f_min.value[3]while True:self.map[p_father[0],p_father[1]] = 2p_father = findFather(p_father)if p_father[0] == -1:breakself.map[p0[0], p0[1]] = 4returnif p2[0] < 0 or p2[0] >= self.heigh or p2[1] < 0 or p2[1] >= self.width:continueif (self.map[p2[0],p2[1]] != 0 and self.map[p2[0],p2[1]] != 2 and self.map[p2[0],p2[1]] != 4) or isInClose(p2):continueh = abs(p2[0] - p1[0]) * 10 + abs(p2[1] - p1[1]) * 10g = f_min.value[1] + 10f = h + gif not isInOpen(p2):open_list.append(Node([f,g,h,p2,f_min.value[3]]))else:#比较最小的G 值temp = findInOpen(p2)if g < temp.value[1]:open_list.remove(temp)open_list.append(Node([f,g,h,p2,f_min.value[3]]))def printMap(self):for i in range(self.heigh):for j in range(self.width):print(int(self.map[i,j]),end='')print()def printRoom(self):for r in self.room:r.info()if __name__ == '__main__':map = Map()map.printMap()

可视化一下
地牢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/497257.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Parameterize Method(令函数携带参数)

若干函数做了类似的工作&#xff0c;但在函数体中却包含了不同的值 重构&#xff1a;建立单一函数&#xff0c;以参数表达那些不同的值。

「谷歌大脑」提出通过对长序列进行摘要提取,AI可自动生成「维基百科」

原文来源&#xff1a;arXiv作者&#xff1a;Peter J. Liu、Mohammad Saleh、Etienne Pot、Ben Goodrich、Ryan Sepassi、Łukasz Kaiser、Noam Shazeer「雷克世界」编译&#xff1a;嗯~阿童木呀最近&#xff0c;经过研究证明&#xff0c;生成英文维基百科&#xff08;English W…

redis基本用法学习(C#调用CSRedisCore操作redis)

除了NRedisStack包&#xff0c;csredis也是常用的redis操作模块&#xff08;从EasyCaching提供的常用redis操作包来看&#xff0c;CSRedis、freeredis、StackExchange.Redis应该都属于常用redis操作模块&#xff09;&#xff0c;本文学习使用C#调用CSRedis包操作redis的基本方式…

简明Python教程学习笔记_3_模块

模块 如果你想要在其他程序中重用很多函数&#xff0c;那么你该如何编写程序呢&#xff1f;你可能已经猜到了&#xff0c;答案是使用模块。模块基本上就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块&#xff0c;模块的文件名必须以.py为扩展名。 pyt…

python: 使用socket实现局域网不同主机通信。解决ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。

目录1 socket的使用1.1 TCP方法1.2 UDP方法2 局域网内连接2.1总结1 socket的使用 1.1 TCP方法 在socket中使用socket.socket建立会话&#xff0c;如果是服务器&#xff0c;需要绑定服务器地址和端口号&#xff0c;然后进行循环监听&#xff0c;当有客户端连接时再接收数据。 …

德勤:2018年科技、传媒和电信行业未来趋势预测

来源&#xff1a;亿欧近日&#xff0c;德勤发布了《2018科技、传媒和电信行业预测》报告&#xff0c;对世界与中国的科技、传媒和电信行业在未来1-5年的趋势进行了预测。该报告通过与世界各国行业主管和评论家的数百场访谈及对世界各地数万名消费者进行的调查&#xff0c;分析了…

python: SHA256算法的实现和消息的哈希散列值计算

目录1 SHA2562 实现原理2.1 消息预处理2.2 使用的常量和循环移位函数2.3 主循环3 结果4 对中文编码1 SHA256 SHA256是SHA-2下的一个子算法&#xff0c;与之类似的还有SHA224、SHA384、SHA512&#xff0c;算法原理基本一致。 哈希算法通过对消息进行计算&#xff0c;生成一定长…

财报上的云计算战场: 巨头们垄断加剧

来源&#xff1a; 第一财经一周之内&#xff0c;四大云业务巨头公司前后脚发布财报。亚马逊的云业务&#xff08;AWS&#xff09;依然跑在了最前面&#xff0c;以174亿美元排在首位。微软、谷歌、阿里巴巴也没有放慢步伐。阿里云去年累计的营收超过了百亿&#xff1b;微软的Azu…

python实现RSA算法,对数据进行加密认证

RSA算法RSA一、数学原理二、实现代码1 生成素数2 生成秘钥3 对数据进行加密、解密总结RSA RSA是一种非对称加密体制&#xff0c;由公钥和私钥组成&#xff0c;数学原理是实数域的模余法。在使用私钥对数据进行加密后&#xff0c;可用公钥对数据进行解密。 在RSA算法中&#xf…

他研究了5000家AI公司,说人工智能应用该这么做!

来源&#xff1a;公众号InfoQ编辑&#xff1a;陈思 Eva&#xff1b;视频剪辑&#xff1a;汪春良 概要&#xff1a;本文作者 Henry Shi是美国人工智能的博士&#xff0c;连续创业者&#xff0c;专注于 AI 领域的早期投资&#xff08;AI List Capital管理合伙人&#xff09;。无…

简明Python教程学习笔记_6_面向对象编程

面向对象编程&#xff1a;https://www.liaoxuefeng.com/wiki/897692888725344/923030496738368面向对象高级编程&#xff1a;https://www.liaoxuefeng.com/wiki/897692888725344/9230305380126401、类、对象 类 和 对象 是面向对象编程的两个主要方面。 类 是创建一个 新类型&a…

哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗

前文 使用socket实现局域网不同主机通信 SHA256算法的实现和消息的哈希散列值计算 python实现RSA算法&#xff0c;对数据进行加密认证 文章目录数字签名与认证攻击类型算法选择实现流程总结数字签名与认证 什么是数字签名&#xff1f; 签名我们大家都知道&#xff0c;A在纸上签…

2017 年脑机接口研发热点回眸

来源&#xff1a;科技导报概要&#xff1a;脑机接口&#xff08;brain-computer interface&#xff0c;BCI&#xff09;通过解码人类思维活动过程中的脑神经活动信息&#xff0c;构建大脑与外部世界的直接信息传输通路&#xff0c;在神经假体、神经反馈训练、脑状态监测等领域有…

地牢房间迷宫走廊生成(二),Python实现洪水法、完美迷宫

文章目录前言1 随机房间和房门2 生成走廊2.1生成迷宫2.4 使用循环改进2.3 走廊缩减2.3 走廊再简化总结前言 前面通过随机房间、房门&#xff0c;对房门寻路生成走廊。由于使用A星算法&#xff0c;寻到的是最短路径&#xff0c;这样生成的走廊过直和简单。如果需要生成弯曲的走廊…

Introduce Parameter Object(引入参数对象)

某些参数总是很自然地同时出现 重构&#xff1a;以一个对象取代这些参数

深度解析,马斯克最新发射的先进火箭

来源&#xff1a;环球时报概要&#xff1a;就在几个小时前&#xff0c;美国人成功发射了目前全世界运载能力最强的超级火箭——“猎鹰重型”。就在几个小时前&#xff0c;美国人成功发射了目前全世界运载能力最强的超级火箭——“猎鹰重型”。虽然中芯级火箭在回收过程中坠毁&a…

技术专栏 | 两万字深度长文!从原理到趋势 解剖风口上的区块链技术

来源&#xff1a;芯师爷概要&#xff1a;区块链不是一项新技术&#xff0c;而是一个新的技术组合。其关键技术包括P2P动态组网、基于密码学的共享账本、共识机制、智能合约等技术。区块链不是一项新技术&#xff0c;而是一个新的技术组合。其关键技术包括P2P动态组网、基于密码…

Python 进阶

​Python 进阶&#xff1a;https://eastlakeside.gitbook.io/interpy-zh/ Python 经典教程 专题 系列&#xff1a;https://www.jb51.net/Special/520.htm Python 黑魔法指南&#xff1a;https://magic.iswbm.com/ Python 中文指南&#xff1a;https://python.iswbm.com/ Python…

2018年中国65家机器人产业园布局与规划汇总盘点

来源&#xff1a;机器人创新生态概要&#xff1a;“机器人换人”大潮下&#xff0c;中国已连续两年坐上世界机器人最大消费国的宝座&#xff0c;根据国际机器人联合会&#xff08;IFR&#xff09;发布的数据&#xff0c;2016年中国工业机器人的销量为9万台&#xff0c;同比增长…

人工智能与经济学:关于近期文献的一个综述

来源&#xff1a;财新网概要&#xff1a;相比于之前的历次技术进步&#xff0c;“人工智能革命”所引发的冲击更为巨大&#xff0c;其对经济学造成的影响也将更为广泛和深远。人工智能技术的突飞猛进&#xff0c;对经济社会的各个领域都产生了重大影响&#xff0c;这种影响当然…