1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
|
# Class to produce random map layouts
from random import randrange
class dMap:
def __init__(self):
self.roomList = []
self.cList = []
def makeMap(self, xsize, ysize, fail, b1, mrooms):
"""
Generate random layout of rooms, corridors and other features
"""
# makeMap can be modified to accept arguments for values of failed,
# and percentile of features.
# Create first room
self.size_x = xsize
self.size_y = ysize
# initialize map to all walls
self.mapArr = []
for y in range(ysize):
tmp = []
for x in range(xsize):
tmp.append(1)
self.mapArr.append(tmp)
w, l, t = self.makeRoom()
while len(self.roomList) == 0:
# Ligne originale
# y = randrange(ysize - 1 - l) + 1
y = randrange(max(1, ysize - 1 - l)) + 1
# ligne originale
# x = randrange(xsize - 1 - w) + 1
x = randrange(max(1, xsize - 1 - w)) + 1
p = self.placeRoom(l, w, x, y, xsize, ysize, 6, 0)
failed = 0
# The lower the value that failed < , the smaller the dungeon
while failed < fail:
chooseRoom = randrange(len(self.roomList))
ex, ey, ex2, ey2, et = self.makeExit(chooseRoom)
feature = randrange(100)
# Begin feature choosing (more features to be added here)
if feature < b1:
w, l, t = self.makeCorridor()
else:
w, l, t = self.makeRoom()
roomDone = self.placeRoom(l, w, ex2, ey2, xsize, ysize, t, et)
# If placement failed increase possibility map is full
if roomDone == 0:
failed += 1
# Possiblilty of linking rooms
elif roomDone == 2:
if self.mapArr[ey2][ex2] == 0:
if randrange(100) < 7:
self.makePortal(ex, ey)
failed += 1
# Otherwise, link up the 2 rooms
else:
self.makePortal(ex, ey)
failed = 0
if t < 5:
tc = [len(self.roomList)-1, ex2, ey2, t]
self.cList.append(tc)
self.joinCorridor(len(self.roomList)-1, ex2, ey2, t, 50)
if len(self.roomList) == mrooms:
failed = fail
self.finalJoins()
def makeRoom(self):
"""
Randomly produce room size
"""
rtype = 5
rwide = randrange(8) + 3
rlong = randrange(8) + 3
return rwide, rlong, rtype
def makeCorridor(self):
"""
Randomly produce corridor length and heading
"""
clength = randrange(18) + 3
heading = randrange(4)
# north
if heading == 0:
wd = 1
lg = - clength
# east
elif heading == 1:
wd = clength
lg = 1
# south
elif heading == 2:
wd = 1
lg = clength
# west
elif heading == 3:
wd = - clength
lg = 1
return wd, lg, heading
def placeRoom(self, ll, ww, xposs, yposs, xsize, ysize, rty, ext):
"""
Place feature if enough space and return canPlace as true or false
"""
# Determine room position and size
xpos = max(1, xposs)
ypos = max(1, yposs)
ww = abs(ww)
ll = abs(ll)
if rty == 5:
if ext == 0 or ext == 2:
offset = randrange(ww)
xpos -= offset
else:
offset = randrange(ll)
ypos -= offset
# Check if there is enough space for the room
if ww + xpos + 1 > xsize or ll + ypos + 1 > ysize:
return False
# Check if the space is not already occupied
for j in range(ll):
for k in range(ww):
if self.mapArr[ypos+j][xpos+k] != 1:
return False
# Add the room to the list of rooms
temp = [ll, ww, xpos, ypos]
self.roomList.append(temp)
# Build walls and floor
for j in range(ll + 2):
for k in range(ww + 2):
self.mapArr[ypos-1+j][xpos-1+k] = 2
for j in range(ll):
for k in range(ww):
self.mapArr[ypos+j][xpos+k] = 0
return True
def makeExit(self, rn):
"""
Pick random wall and random point along that wall
"""
room = self.roomList[rn]
while True:
rw = randrange(4)
# north wall
if rw == 0:
rx = randrange(room[1]) + room[2]
ry = room[3] - 1
rx2 = rx
ry2 = ry - 1
# esat wall
elif rw == 1:
ry = randrange(room[0]) + room[3]
rx = room[2] + room[1]
rx2 = rx + 1
ry2 = ry
# south wall
elif rw == 2:
rx = randrange(room[1]) + room[2]
ry = room[3] + room[0]
rx2 = rx
ry2 = ry + 1
# west wall
elif rw == 3:
ry = randrange(room[0]) + room[3]
rx = room[2] - 1
rx2 = rx - 1
ry2 = ry
# If space is a wall, exit
if self.mapArr[ry][rx] == 2:
break
return rx, ry, rx2, ry2, rw
def makePortal(self, px, py):
"""
Create doors in walls
"""
ptype = randrange(100)
# secret door
if ptype > 90:
self.mapArr[py][px] = 5
return
# closed door
elif ptype > 75:
self.mapArr[py][px] = 4
return
# open door
elif ptype > 40:
self.mapArr[py][px] = 3
return
# hole in the wall
else:
self.mapArr[py][px] = 0
def joinCorridor(self, cno, xp, yp, ed, psb):
"""
Check corridor endpoint and make an exit if it links to another room
"""
cArea = self.roomList[cno]
# Find the corridor endpoint
endx = xp - (cArea[1] - 1) if xp != cArea[2] or yp != cArea[3] else xp + (cArea[1] - 1)
endy = yp - (cArea[0] - 1) if xp != cArea[2] or yp != cArea[3] else yp + (cArea[0] - 1)
checkExit = []
# north corridor
if ed == 0:
checkExit.append((
[endx - 2, endy, endx - 1, endy],
[endx, endy - 2, endx, endy - 1],
[endx + 2, endy, endx + 1, endy]))
# east corridor
elif ed == 1:
checkExit.append((
[endx, endy - 2, endx, endy - 1],
[endx + 2, endy, endx + 1, endy],
[endx, endy + 2, endx, endy + 1]))
# south corridor
elif ed == 2:
checkExit.append((
[endx + 2, endy, endx + 1, endy],
[endx, endy + 2, endx, endy + 1],
[endx - 2, endy, endx - 1, endy]))
# west corridor
elif ed == 3:
checkExit.append((
[endx - 2, endy, endx - 1, endy],
[endx, endy - 2, endx, endy - 1],
[endx, endy + 2, endx, endy + 1]))
# Loop through possible exits
for exits in checkExit:
for coords in exits:
xxx, yyy, xxx1, yyy1 = coords
# Check if (yyy, xxx) is within the bounds of mapArr
if yyy >= 0 and yyy < len(self.mapArr) and xxx >= 0 and xxx < len(self.mapArr[yyy]):
# If joins to a room
if self.mapArr[yyy][xxx] == 0:
# Possibility of linking rooms
if randrange(100) < psb:
self.makePortal(xxx1, yyy1)
return
def finalJoins(self):
"""
Final stage, loops through all the corridors to see if any can be
joined to other rooms
"""
for x in self.cList:
self.joinCorridor(x[0], x[1], x[2], x[3], 10) |
Partager