Posted By

goldenratio on 08/11/09


Tagged

dungeon


Versions (?)

random dungeon generator


 / Published in: Python
 

  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  

You need to login to post a comment.