-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap.py
165 lines (132 loc) · 4.88 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
from math import sqrt
from random import choice, random, randint
from constants import (
NORTH, SOUTH, EAST, WEST, DIRECTIONS,
SOUND_THRESHOLD, OPPOSITE_MOVES
)
from monster import Monster
def distance(one, other):
return sqrt(
(one[0] - other[0]) ** 2 + (one[1] - other[1] ** 2)
)
class Room(object):
doors = []
def make_description(self):
description = "You are in a room.\n"
for direction in self.doors:
description += "There is a door to the {}\n".format(direction)
return description
class Labyrinth(object):
player_location = None
monster_location = None
layout = None
width = None
height = None
monster = None
def __getitem__(self, key):
x, y = key
return self.layout[x][y]
def __init__(self, width, height):
self.width = width
self.height = height
layout = []
for _ in range(self.width):
# To start out, just do a "maze" with doors between all rooms.
row = []
for _ in range(self.height):
room = Room()
room.doors = [NORTH, SOUTH, EAST, WEST]
row.append(room)
layout.append(row)
# Remove the doors in the outer walls
for room in layout[0]:
room.doors.remove(WEST)
for inner_column in layout:
inner_column[0].doors.remove(SOUTH)
inner_column[-1].doors.remove(NORTH)
for room in layout[-1]:
room.doors.remove(EAST)
self.layout = layout
self._remove_random_doors()
self.player_location = self.get_random_location()
self.monster_location = self.get_random_location()
self.monster = Monster()
def _remove_random_doors(self):
for x, column in enumerate(self.layout):
for y, room in enumerate(column):
if randint(0,10) < 5:
# Remove a door at random
door = choice(room.doors)
room.doors.remove(door)
change_x, change_y = DIRECTIONS[door]
new_x, new_y = x+change_x, y+change_y
self.layout[new_x][new_y].doors.remove(OPPOSITE_MOVES[door])
def get_random_location(self):
return randint(0, self.width-1), randint(0, self.height-1)
def player_hears(self):
distance = distance(
self.monster_location, self.player_location
)
return distance < SOUND_THRESHOLD
def monster_hears(self):
distance = distance(
self.player_location, self.monster_location
)
return distance < SOUND_THRESHOLD * 1.5
def text_map(self):
"""
Return maze table in ASCII
For debugging purposes
"Borrowed" from http://code.activestate.com/recipes/252127-maze-generator/
"""
result = '.' + self.width*'_.'
result += '\n'
for j in range(self.height-1, -1, -1):
result += '|'
for i in range(self.width):
if SOUTH not in self.layout[i][j].doors:
result += '_'
elif (i,j) == self.player_location:
result += 'p'
elif (i,j) == self.monster_location:
result += 'm'
else:
result += ' '
if EAST not in self.layout[i][j].doors:
result += '|'
else:
result += '.'
result += '\n'
return result
def get_current_player_room(self):
x, y = self.player_location
return self.layout[x][y]
def get_current_monster_room(self):
x, y = self.monster_location
return self.layout[x][y]
def _move_player(self, direction):
current_room = self.get_current_player_room()
print current_room.make_description()
if direction not in current_room.doors:
print "You cannot move in this direction"
else:
current_x, current_y = self.player_location
change_x, change_y = DIRECTIONS[direction]
self.player_location = current_x + change_x, current_y + change_y
print "You moved {}.".format(direction)
def _move_monster(self):
direction = self.monster.get_move()
current_room = self.get_current_monster_room()
if direction in current_room.doors:
current_x, current_y = self.monster_location
change_x, change_y = DIRECTIONS[direction]
self.monster_location = current_x + change_x, current_y + change_y
def _check_condition(self):
if self.player_location == self.monster_location:
print "You have been eaten by a grue."
raise Exception("Grue")
def move_player(self, direction):
self._move_player(direction)
self._move_monster()
self._check_condition()
return self.get_current_player_room()