-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrover.py
222 lines (204 loc) · 6.82 KB
/
rover.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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
class Rover:
"""
This is the core class which contains a lot of useful
fuctions. In game menu, all fuctions can be found here.
"""
def __init__(self, x, y , planet):
"""
Initialises the rover.
A rover has a coordinate x, y.
And I give a rover a planet object, which can be used
as the 'map' of the planet.
"""
self.x = x
self.y = y
self.planet = planet
self.battery = 100
def spherical(self, x, y):
"""
To make the planet be a spherical planet, I use this
fuction to make each coordinate can be an exact point
on the initial map.
"""
while x >= self.planet.width or x < 0 or y >= self.planet.height or y < 0:
#change x if x is out of boundary
if x >= self.planet.width:
x -= (self.planet.width)
elif x < 0:
x += (self.planet.width)
#change y if y is out of boundary
if y >= self.planet.height:
y -= (self.planet.height)
elif y < 0:
y += (self.planet.height)
return x, y
def can_move(self, next_x, next_y):
"""
Check whether the rover can move to next tile.
Use a very easy way to check:
If next tile's elevation is "+" or "-", then the rover
can not get there.
Other wise, the rover can get there, no matter the elevation
is " " or "/" or "\".
"""
if self.battery == 0:
if self.planet.tiles[next_y][next_x].is_shaded():
return False
if self.planet.tiles[next_y][next_x].elevation(self) == "+":
return False
if self.planet.tiles[next_y][next_x].elevation(self) == "-":
return False
return True
def move(self, direction, cycles):
"""
Move the rover on the planet.
Get the unit vector which point to the direction
of your way. Use a loop to move step by step. Before
move, check whether the rover can get there, if it can
get there, change the coordinate of the rover.
Example: if you want to move "E" direction, then
'(1,0)' is your unit vector. You can add the rover's
coordinate by this vector, which can only change your
x number and keep the initial y number. And move the rover
step by step.
"""
self.planet.tiles[self.y][self.x].set_occupant() # set occupant to the initial tile
if direction == "N": # unit vector (0, -1)
y_symbol = -1
x_symbol = 0
if direction == "S": # unit vector (0, 1)
y_symbol = 1
x_symbol = 0
if direction == "W": # unit vector (-1, 0)
x_symbol = -1
y_symbol = 0
if direction == "E": # unit vector (1, 0)
x_symbol = 1
y_symbol = 0
i = 0
while i < int(cycles):
next_x = self.x + x_symbol # change x coordinate
next_y = self.y + y_symbol # change y coordinate
next_x, next_y = self.spherical(next_x, next_y) # get the next tile's coordinate
if self.can_move(next_x, next_y): # check whether rover can move
#reduce battery
if self.planet.tiles[next_y][next_x].is_shaded():
self.battery -= 1
self.x = next_x
self.y = next_y
tile = self.planet.tiles[next_y][next_x]
tile.set_occupant()
i += 1
else:
break
def scan(self, type):
"""
Name each tile like this:
|t00|t01|t02|t03|t04|
|t10|t11|t12|t13|t14|
|t20|t21| H |t23|t24|
|t30|t31|t32|t33|t34|
|t40|t41|t42|t43|t44|
"""
self.planet.tiles[self.y][self.x].set_occupant() # set occupant to the initial tile
t = {} # create a dictionary which contains all tiles around the rover
for i in range(5):
t[i] = []
for j in range(5):
tile = self.planet.tiles\
[self.spherical(self.x - 2 + j,self.y - 2 + i)[1]]\
[self.spherical(self.x - 2 + j,self.y - 2 + i)[0]]
t[i].append(tile)
tile.set_occupant()
if type == "shade": # print each tile's shade type
print("|{}|{}|{}|{}|{}|".format(t[0][0].terrain,
t[0][1].terrain,
t[0][2].terrain,
t[0][3].terrain,
t[0][4].terrain))
print("|{}|{}|{}|{}|{}|".format(t[1][0].terrain,
t[1][1].terrain,
t[1][2].terrain,
t[1][3].terrain,
t[1][4].terrain))
print("|{}|{}|H|{}|{}|".format(t[2][0].terrain,
t[2][1].terrain,
t[2][3].terrain,
t[2][4].terrain))
print("|{}|{}|{}|{}|{}|".format(t[3][0].terrain,
t[3][1].terrain,
t[3][2].terrain,
t[3][3].terrain,
t[3][4].terrain))
print("|{}|{}|{}|{}|{}|".format(t[4][0].terrain,
t[4][1].terrain,
t[4][2].terrain,
t[4][3].terrain,
t[4][4].terrain))
if type == "elevation": # print each tile;s elevation's type
print("|{}|{}|{}|{}|{}|".format(t[0][0].elevation(self),
t[0][1].elevation(self),
t[0][2].elevation(self),
t[0][3].elevation(self),
t[0][4].elevation(self)))
print("|{}|{}|{}|{}|{}|".format(t[1][0].elevation(self),
t[1][1].elevation(self),
t[1][2].elevation(self),
t[1][3].elevation(self),
t[1][4].elevation(self)))
print("|{}|{}|H|{}|{}|".format(t[2][0].elevation(self),
t[2][1].elevation(self),
t[2][3].elevation(self),
t[2][4].elevation(self)))
print("|{}|{}|{}|{}|{}|".format(t[3][0].elevation(self),
t[3][1].elevation(self),
t[3][2].elevation(self),
t[3][3].elevation(self),
t[3][4].elevation(self)))
print("|{}|{}|{}|{}|{}|".format(t[4][0].elevation(self),
t[4][1].elevation(self),
t[4][2].elevation(self),
t[4][3].elevation(self),
t[4][4].elevation(self)))
def statistic(self):
"""
Print the percentage of the planet that the rover has explored,
and print the batery of the rover.
"""
self.planet.tiles[self.y][self.x].set_occupant() # set occupant to the initial tile
num_tile = self.planet.width * self.planet.height
sum = 0
for y in range(self.planet.height):
for x in range(self.planet.width):
tile = self.planet.tiles[y][x]
if tile.occupant == 1:
sum += 1
percent = int((sum/num_tile)*100)
print("Explored: {}%".format(percent))
print("Battery: {}/100".format(self.battery))
def finish(self):
"""
Print the percentage of the planet that the rover has explored,
and exit the program.
"""
self.planet.tiles[self.y][self.x].set_occupant() # set occupant to the initial tile
num_tile = self.planet.width * self.planet.height
sum = 0
for y in range(self.planet.height): # get the number of the tiles which have been explored
for x in range(self.planet.width):
tile = self.planet.tiles[y][x]
if tile.occupant == 1:
sum += 1
percent = int((sum/num_tile)*100)
print("You explored {}% of {}".format(percent, self.planet.name))
def wait(self, cycles):
"""
The rover will wait for the specified cycles
"""
self.planet.tiles[self.y][self.x].set_occupant() # set occupant to the initial tile
if self.planet.tiles[self.y][self.x].is_shaded: # in 'plain' the rover will recharge itself
i = 0
while i < int(cycles):
if self.battery < 100:
self.battery += 1
i += 1