Python script to generate simple "dungeon maps"
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

procgen.py 4.1KB

před 7 roky
před 7 roky
před 7 roky
před 7 roky
před 7 roky
před 7 roky
před 7 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import random as r
  2. import sys, os
  3. from PIL import Image
  4. def createDungeon(x=None, y=None, seed=None):
  5. """ Initializes an x by y grid.
  6. x is width, y is height
  7. seed is the chance that a given cell will be "live" and should be an integer between 1-99.
  8. If True is equivalent to "walkable", then lower seeds make more walls.
  9. """
  10. x = 10 if x == None else int(x)
  11. y = 10 if y == None else int(y)
  12. seed = 45 if seed == None else int(seed)
  13. new_map = []
  14. for j in range(y):
  15. new_row = []
  16. for i in range(x):
  17. new_row.append(False if r.randint(1,99) > seed else True)
  18. new_map.append(new_row)
  19. return new_map
  20. def refineDungeon(d_map, d_lmt=None, a_lmt=None):
  21. """ Refines the grid.
  22. """
  23. d_lmt = 4 if d_lmt == None else int(d_lmt)
  24. a_lmt = 4 if a_lmt == None else int(a_lmt)
  25. new_map = []
  26. for j in range(len(d_map)):
  27. new_line = []
  28. for i in range(len(d_map[j])):
  29. x, y = i, j
  30. n_count = countAliveNeighbors(d_map, x, y)
  31. if d_map[y][x]:
  32. if n_count >= a_lmt:
  33. new_line.append(False)
  34. else:
  35. new_line.append(True)
  36. else:
  37. if n_count <= d_lmt:
  38. new_line.append(True)
  39. else:
  40. new_line.append(False)
  41. new_map.append(new_line)
  42. return new_map
  43. def countAliveNeighbors(d_map, x, y):
  44. count = 0
  45. for j in range(-1,2):
  46. for i in range(-1,2):
  47. n_x, n_y = x+i, y+j
  48. if i == 0 and j == 0:
  49. continue
  50. if n_x < 0 or n_x >= len(d_map[j]) or n_y == 0 or n_y >= len(d_map):
  51. count += 1
  52. elif d_map[n_y][n_x]:
  53. count += 1
  54. return count
  55. def printDungeon(d_map, wall=None, path=None):
  56. wall = "II" if wall == None else wall
  57. path = " " if path == None else path
  58. for line in d_map:
  59. print("".join([wall if x == True else path for x in line]))
  60. print()
  61. def createImage(d_map, color=None, chunky=None):
  62. color = False if color == None else bool(color)
  63. chunky = False if chunky == None else bool(chunky)
  64. x, y = len(d_map[0]), len(d_map)
  65. if chunky:
  66. true_x, true_y = x*2, y*2
  67. else:
  68. true_x, true_y = x, y
  69. img = Image.new("RGB",(true_x,true_y),(0,0,0))
  70. lst = []
  71. c_wall = [r.randint(0,255), r.randint(0,255), r.randint(0,255)] if color else [0,0,0]
  72. c_space = [255-x for x in c_wall]
  73. if chunky:
  74. for line in d_map:
  75. for _ in range(2):
  76. for val in line:
  77. for _ in range(2):
  78. lst.append(tuple(c_space) if val else tuple(c_wall))
  79. else:
  80. for line in d_map:
  81. for val in line:
  82. lst.append(tuple(c_space) if val else tuple(c_wall))
  83. img.putdata(lst)
  84. hexes = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
  85. a_filename = []
  86. for _ in range(16):
  87. a_filename.append(r.choice(hexes))
  88. filename = "".join(a_filename)
  89. if not os.path.exists("maps"):
  90. os.makedirs("maps")
  91. img.save('maps/{}.png'.format(filename))
  92. print("Saved maps/{}.png".format(filename))
  93. def main(x=None, y=None, seed=None, d_lmt=None, a_lmt=None, reps=None, out=None, color=None, chunky=None):
  94. # Initialize
  95. x = 20 if x == None else int(x)
  96. y = 20 if y == None else int(y)
  97. seed = 45 if seed == None else int(seed)
  98. d_lmt = 4 if d_lmt == None else int(d_lmt)
  99. a_lmt = 4 if a_lmt == None else int(a_lmt)
  100. reps = 2 if reps == None else int(reps)
  101. out = False if out == None else bool(out)
  102. color = False if color == None else bool(color)
  103. chunky = False if chunky == None else bool(chunky)
  104. my_map = createDungeon(x,y,seed)
  105. for _ in range(reps):
  106. my_map = refineDungeon(my_map, d_lmt, a_lmt)
  107. if out:
  108. createImage(my_map, color, chunky)
  109. else:
  110. printDungeon(my_map)
  111. def parseArgs(args):
  112. flags = {
  113. "--height" : 20,
  114. "--width" : 20,
  115. "--seed" : 45,
  116. "--death" : 4,
  117. "--birth" : 4,
  118. "--reps" : 2,
  119. "--out" : False,
  120. "--color" : False,
  121. "--chunky" : False,
  122. }
  123. for flag, default in flags.items():
  124. if flag in args:
  125. if flag == "--out":
  126. flags["--out"] = True
  127. elif flag == "--color":
  128. flags["--color"] = True
  129. elif flag == "--chunky":
  130. flags["--chunky"] = True
  131. else:
  132. flags[flag] = args[args.index(flag) + 1]
  133. return flags
  134. if __name__ == "__main__":
  135. flags = parseArgs(sys.argv)
  136. main(flags["--width"],
  137. flags["--height"],
  138. flags["--seed"],
  139. flags["--death"],
  140. flags["--birth"],
  141. flags["--reps"],
  142. flags["--out"],
  143. flags["--color"],
  144. flags["--chunky"])