random dungeon generator


/ Published in: Python
Save to your folder(s)



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[1]][pos[0]]
  16. def setcell(pos, val):
  17. self.level[pos[1]][pos[0]] = val
  18. def feature(pos, size):
  19. return pygame.Rect(pos[0], pos[1], 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 = [0] * 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[0].x, features[0].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[0], farthest[1]
  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

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.