/
Map.py
144 lines (127 loc) · 5.25 KB
/
Map.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import random
from Room import Room
from Vector import Vector
from Creatures import *
class Map:
def __init__(self, min_width, min_height, max_width, max_height, debug=False):
"""
Notes:
mid_width & min_height need to be binary, as in 32/64/128 etc.
"""
self.__min_width = min_width
self.__min_height = min_height
self.__max_width = max_width
self.__max_height = max_height
self.__rooms = []
self.__max_neighbours = 3
self.__show_map = debug # for debug purposes
self.__tile_size = 32
def generate(self, max_rooms, random_percentage, screen_size):
"""
Generates a list of rooms with a size of `max_rooms`
Keyword arguments:
max_rooms - an integer with the maximum number of rooms wanted
random_percentage - the percent of rooms to keep for adding randomly to the map
screen_size - a tuple of ints that represent the screen size
"""
self.__rooms = []
linear_rooms = int((max_rooms + 1) * (1 - random_percentage))
random_rooms = max_rooms - linear_rooms
center = Vector(screen_size[0]/2, screen_size[1]/2)
for i in range(linear_rooms):
if(i == 0):
r = Room(center,
random.randrange(self.__min_width, self.__max_width, self.__tile_size),
random.randrange(self.__min_height, self.__max_height, self.__tile_size),
"start" )
elif(i == linear_rooms-1):
r = Room(center,
random.randrange(self.__min_width, self.__max_width, self.__tile_size),
random.randrange(self.__min_height, self.__max_height, self.__tile_size),
"end" )
else:
r = Room(center,
random.randrange(self.__min_width, self.__max_width, self.__tile_size),
random.randrange(self.__min_height, self.__max_height, self.__tile_size)
)
heading = self.__getRandomHeading()
self.__rooms.append(r)
if(i > 0):
while(self.__rooms[i-1].headingExists(heading)):
heading = self.__getRandomHeading()
self.__rooms[i-1].addNeighbour(r, heading)
r.addNeighbour(self.__rooms[i-1], self.__invertHeading(heading))
for i in range(random_rooms):
chosen_room = self.__rooms[random.randint(0, len(self.__rooms)-1)]
while(len(chosen_room.getEmptyNeighbours()) == 0 or chosen_room.isStart() or chosen_room.isEnd()):
chosen_room = self.__rooms[random.randint(0, len(self.__rooms)-1)]
heading = self.__getRandomHeading()
while(chosen_room.headingExists(heading)):
heading = self.__getRandomHeading()
r = Room(center,
random.randrange(self.__min_width, self.__max_width, self.__tile_size),
random.randrange(self.__min_height, self.__max_height, self.__tile_size)
)
chosen_room.addNeighbour(r, heading)
r.addNeighbour(chosen_room, self.__invertHeading(heading))
self.__rooms.append(r)
self.__addEnemies()
print("Map Generated")
def __addEnemies(self):
"""
Adds enemies to the rooms on map generated
"""
enemy_types = 3
for room in self.getRooms():
if(not room.isStart() and not room.isEnd()):
enemies = []
num_to_spawn = random.randint(1, 4)
for e in range(num_to_spawn):
e_type = random.randint(1, enemy_types)
if(e_type == 1):
enemies.append( DaggerGoblin(room.getRandomPos()) )
elif(e_type == 2):
enemies.append( Zombie(room.getRandomPos()) )
else:
enemies.append( MageGoblin(room.getRandomPos()) )
room.addEnemies(enemies)
elif(room.isEnd()):
room.addEnemies( [ Dragon( room.getRandomPos() ) ] )
def __getRandomHeading(self):
"""
Generates a random heading
"""
choice = random.randint(0, 3)
if(choice == 0):
return "N"
elif(choice == 1):
return "E"
elif(choice == 2):
return "S"
else:
return "W"
def __invertHeading(self, heading):
"""
Inverts a given heading
"""
if(heading == "N"):
return("S")
elif(heading == "E"):
return("W")
elif(heading == "S"):
return("N")
else:
return("E")
def getRooms(self):
"""
Returns a sorted list of rooms where the first item will be a `start` room and the last item will be the `end` room
"""
rooms = self.__rooms
for room in rooms:
if(room.isStart()):
rooms.remove(room)
rooms.insert(0, room)
elif(room.isEnd()):
rooms.remove(room)
rooms.insert(len(rooms), room)
return(rooms)