-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMapGenerator.py
119 lines (101 loc) · 3.99 KB
/
MapGenerator.py
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
import numpy as np
from random import randint
from PIL import Image
import RoomGenerator as rm
def generateMap(size, room_size, start, show=False):
# define size of grid
cell_grid = (size[0] * 2 - 1, size[1] * 2 - 1)
# define starting position
cell_pos = np.array([start[0] * 2, start[1] * 2])
# generate image
maze = Image.new("RGBA", cell_grid, "black")
maze_pix = maze.load()
# color codes
BLACK = (0, 0, 0, 255)
WHITE = (255, 255, 255, 255)
BLUE = (0, 0, 255, 255)
def freeCells():
# Find avaliable cells around main cell
d = []
for d_x in range(-2, 3, 2):
for d_y in range(-2, 3, 2):
if abs(d_x) == abs(d_y):
continue
if not (maze.size[0] > d_x + cell_pos[0] >= 0) or not (maze.size[1] > d_y + cell_pos[1] >= 0):
continue
if maze_pix[int(d_x + cell_pos[0]), int(d_y + cell_pos[1])] != BLACK:
continue
d.append(np.array([d_x, d_y]))
return d
def backCell():
# Used when the main cell needs to go back
for d_x in range(-1, 2):
for d_y in range(-1, 2):
if not (maze.size[0] > d_x + cell_pos[0] >= 0) or not (maze.size[1] > d_y + cell_pos[1] >= 0):
continue
if maze_pix[int(d_x + cell_pos[0]), int(d_y + cell_pos[1])] == BLUE:
return np.array([d_x, d_y])
# Returns blank list if it has failed
return []
# main
generating = True
while generating:
nextCell = freeCells()
# if a neighboring cell is available
if nextCell:
cell_next = nextCell[randint(0, len(nextCell) - 1)]
maze_pix[int(cell_pos[0]), int(cell_pos[1])] = BLUE
maze_pix[int(cell_pos[0] + cell_next[0] / 2), int(cell_pos[1] + cell_next[1] / 2)] = BLUE
cell_pos += cell_next
# if there's no available cell/begin backtracking
else:
cell_next = backCell()
if list(cell_next):
maze_pix[int(cell_pos[0]), int(cell_pos[1])] = WHITE
maze_pix[int(cell_pos[0] + cell_next[0]), int(cell_pos[1] + cell_next[1])] = WHITE
cell_pos += cell_next * 2
# Will end if there's no cell to backtrack to
else:
break
# Create world
def findExits(x, y):
d = []
for d_x in range(-1, 2):
for d_y in range(-1, 2):
if abs(d_x) == abs(d_y):
continue
if not (maze.size[0] > d_x + x * 2 >= 0) or not (maze.size[1] > d_y + y * 2 >= 0):
continue
if maze_pix[int(x * 2 + d_x), int(y * 2 + d_y)] == WHITE:
d.append([d_x, d_y])
return d
world = Image.new("RGBA", (size[0] * room_size[0], size[1] * room_size[1]), "black")
rooms = []
enemies_pos = []
for y in range(0, size[1]):
rooms_temp = []
enemies_pos_temp = []
for x in range(0, size[0]):
if (x, y) == (0, 0):
typ = 'start'
elif (x + 1, y + 1) == size:
typ = 'end'
else:
typ = 'other'
room = rm.generateRoom(size=room_size,
exits=findExits(x, y),
cluster=20,
enemies=randint(1, 4),
typ=typ,
show=False)
world.paste(room.room, (x * room_size[0], y * room_size[1]))
rooms_temp.append(room)
enemies_pos_temp.append(room.enemies_pos)
rooms.append(rooms_temp)
enemies_pos.append(enemies_pos_temp)
# Display image if requested
if show:
w = world.resize((100 * world.size[0], 100 * world.size[1]), Image.NEAREST)
w.show()
return world, rooms, enemies_pos
# generateMap((5, 5), (10, 10), (3, 3),True)