-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenvironment.py
105 lines (91 loc) · 3.96 KB
/
environment.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
import math
import numpy as np
import maze_generator
import maze
class Environment:
def __init__(self, size, goal_location):
self.size = size
self.goal = goal_location
self.maze = maze.Maze(self.size, self.goal)
self.current_coordinate = (0, 0)
self.move_count = 0
self.move_history = [1] + [0] * ((self.size[0] + self.size[1]) * 2 - 5)
def coordinate_id(self):
if self.current_coordinate[1] == 0:
cid = self.current_coordinate[0]
elif self.current_coordinate[0] == self.size[1] - 1:
cid = self.current_coordinate[1] + self.size[0] -1
elif self.current_coordinate[1] == self.size[1] -1:
cid = (self.size[0] * 2 + self.size[1] - 3) - self.current_coordinate[0]
elif self.current_coordinate[0] == 0:
cid = (self.size[0] + self.size[1] -2) * 2 - self.current_coordinate[1]
return cid
def get_coordinate_from_id(self, cid):
if 0 <= cid and cid < self.size[0]:
x = cid
y = 0
elif self.size[0] <= cid and cid < self.size[0] + self.size[1] -1:
x = self.size[0] -1
y = cid - x
elif self.size[0] + self.size[1] -1 <= cid and cid < self.size[0] * 2 + self.size[1] -2:
x = self.size[0] * 2 + self.size[1] -3 - cid
y = self.size[1] -1
elif self.size[0] * 2 + self.size[1] -2 <= cid:
x = 0
y = (self.size[0] + self.size[1] -2) * 2 - cid
return (x, y)
def wall(self, cid=None):
if cid is None:
cid = self.coordinate_id()
return self.maze.wall(self.get_coordinate_from_id(cid))
def move(self, direction):
neighbor = [ \
(self.current_coordinate[0] + 1, self.current_coordinate[1] ), \
(self.current_coordinate[0] - 1, self.current_coordinate[1] ), \
(self.current_coordinate[0] , self.current_coordinate[1] + 1), \
(self.current_coordinate[0] , self.current_coordinate[1] - 1)]
if self.wall()[direction] == 0:
self.current_coordinate = neighbor[direction]
self.move_count += 1
self.move_history[self.coordinate_id()] = 1
def get_goal(self):
# if sum(self.move_history) == 32:
# which means that the agenet has passed the entire arena
# return self.maze.is_goal(self.current_coordinate)
# else:
# return 0
return self.maze.is_goal(self.current_coordinate)
def visual_targets(self):
return [ \
(self.size[0], self.size[1]), \
( -1, self.size[1]), \
( -1, -1), \
(self.size[0], -1)]
def visual_distance(self):
distance = []
for target in self.visual_targets():
distance.append(math.sqrt( \
(self.current_coordinate[0] - target[0]) ** 2 + \
(self.current_coordinate[1] - target[1]) ** 2))
return distance
def visual_image(self, cid=None):
if cid is None:
cid = self.coordinate_id()
coordinate = self.get_coordinate_from_id(cid)
DEGREE_PER_DOT = 6
image = np.zeros(360 / DEGREE_PER_DOT)
for target in self.visual_targets():
distance = math.sqrt( \
(coordinate[0] - target[0]) ** 2 + \
(coordinate[1] - target[1]) ** 2)
visual_width = math.degrees(math.atan(0.5 / distance))
angle = math.degrees(math.atan2(target[1] - coordinate[1], target[0] - coordinate[0]))
if angle < 0:
angle += 360
visual_range = [round(i / DEGREE_PER_DOT) for i in [angle - visual_width, angle + visual_width]]
image[visual_range[0]:(visual_range[1] + 1)] = 1
return image
def reset(self):
self.current_coordinate = (0, 0)
self.move_count = 0
self.move_history = [1] + [0] * ((self.size[0] + self.size[1]) * 2 - 5)