Posted By

goldenratio on 08/11/09

Statistics

Viewed 252 times
Favorited by 0 user(s)

random dungeon generator

/ Published in: Python  Copy this code and paste it in your HTML
1. import math
2. import random
3. import pygame
4. from random import randint
5. from GameObjects import Vector
6.
7. class DungeonGenerator(object):
8.
9. def __init__(self, rows, cols, num_features, num_specials): # number of rooms too
10. def rcell():
11. return (randint(0, cols - 1), randint(0, rows - 1))
12. def rcellin(rect):
13. return ( (randint(rect.x,rect.x+rect.width-1), randint(rect.y,rect.y+rect.height-1)) )
14. def cell(pos):
15. return self.level[pos][pos]
16. def setcell(pos, val):
17. self.level[pos][pos] = val
18. def feature(pos, size):
19. return pygame.Rect(pos, pos, size, size)
20. def canbuild(feature):
21. # make sure it's not outside the screen
22. if feature.x < 0 or feature.y < 0:
23. return False
24. if feature.x + feature.width > cols:
25. return False
26. if feature.y + feature.height > rows:
27. return False
28. # make sure it doesn't cross another feature
29. # for x in range(feature.width):
30. # for y in range(feature.height):
31. # if cell((x,y)) == 1:
32. # return False
33. return True
34. def build(rect):
35. cur = pygame.Rect(rect)
36. for x in range(rect.width):
37. for y in range(rect.height):
38. setcell((cur.x, cur.y), 1) # space
39. cur.top += 1
40. cur.left += 1
41. cur.top = rect.top
42. def connect(start, end):
43. v = Vector.from_points((start.x, start.y), (end.x, end.y))
44. cur = feature((start.x,start.y), 1)
45. if random.getrandbits(1) == 0:
46. for x in range(int(math.fabs(v.x))): # total number of steps in x direction
47. setcell(cur, 1)
48. cur.x += 1 if v.x > 0 else -1
49. for y in range(int(math.fabs(v.y))):
50. setcell(cur, 1)
51. cur.y += 1 if v.y > 0 else -1
52. else:
53. for y in range(int(math.fabs(v.y))):
54. setcell(cur, 1)
55. cur.y += 1 if v.y > 0 else -1
56. for x in range(int(math.fabs(v.x))): # total number of steps in x direction
57. setcell(cur, 1)
58. cur.x += 1 if v.x > 0 else -1
59.
60. # create multidimensional array of ints:
61. # 0 = cannot walk
62. # 1 = can walk
63. # 2 = start
64. # 3 = exit
65. # 4 = item
66. zeros =  * cols;
67. self.level = [zeros[:] for x in range(rows)]
68. del zeros
69.
70. # place "features"
71. features = []
72. farthest = []
73. highest_mag = 0
74. for x in range(num_features):
75. # pick random feature
76. f = feature(rcell(), randint(2, 6))
77. # see if we can build it
78. while not canbuild(f):
79. # if not, pick another random feature
80. f = feature(rcell(), randint(2, 6))
81. # build it
82. build(f)
83. # check for farthest features
84. for f2 in features:
85. # calc magnitude between new feature and all old ones
86. mag = Vector.from_points( (f.x, f.y), (f2.x, f2.y) ).magnitude()
87. if mag > highest_mag:
88. highest_mag = mag
89. farthest = [f, f2]
90. # append to list of built features
91. features.append(f)
92.
93. # connect "features" together
94. last_feature = feature(( features.x, features.y ), 1)
95. for f in features:
96. connect(last_feature, f)
97. last_feature = feature((f.x,f.y),1)
98. del last_feature
99.
100. # place start and end points
101. start, end = farthest, farthest
102. setcell(rcellin(start), 2)
103. setcell(rcellin(end), 3)
104.
105. # place special points
106. for x in range(num_specials):
107. f = random.choice(features)
108. spec = rcellin(f)
109. while cell(spec) != 1: # open space
110. f = random.choice(features)
111. spec = rcellin(f)
112. setcell(spec, 4)
113.
114. del features Subscribe to comments