-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
ipyviews.py
157 lines (128 loc) · 5.44 KB
/
ipyviews.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
from IPython.display import HTML, display, clear_output
from collections import defaultdict
from agents import PolygonObstacle
import time
import json
import copy
import __main__
# ______________________________________________________________________________
# Continuous environment
_CONTINUOUS_WORLD_HTML = '''
<div>
<canvas class="main-robo-world" width="{0}" height="{1}" style="background:rgba(158, 167, 184, 0.2);" data-world_name="{2}" onclick="getPosition(this,event)"/>
</div>
<script type="text/javascript">
var all_polygons = {3};
{4}
</script>
''' # noqa
with open('js/continuousworld.js', 'r') as js_file:
_JS_CONTINUOUS_WORLD = js_file.read()
class ContinuousWorldView:
""" View for continuousworld Implementation in agents.py """
def __init__(self, world, fill="#AAA"):
self.time = time.time()
self.world = world
self.width = world.width
self.height = world.height
def object_name(self):
globals_in_main = {x: getattr(__main__, x) for x in dir(__main__)}
for x in globals_in_main:
if isinstance(globals_in_main[x], type(self)):
if globals_in_main[x].time == self.time:
return x
def handle_add_obstacle(self, vertices):
""" Vertices must be a nestedtuple. This method
is called from kernel.execute on completion of
a polygon. """
self.world.add_obstacle(vertices)
self.show()
def handle_remove_obstacle(self):
return NotImplementedError
def get_polygon_obstacles_coordinates(self):
obstacle_coordiantes = []
for thing in self.world.things:
if isinstance(thing, PolygonObstacle):
obstacle_coordiantes.append(thing.coordinates)
return obstacle_coordiantes
def show(self):
clear_output()
total_html = _CONTINUOUS_WORLD_HTML.format(self.width, self.height, self.object_name(),
str(self.get_polygon_obstacles_coordinates()),
_JS_CONTINUOUS_WORLD)
display(HTML(total_html))
# ______________________________________________________________________________
# Grid environment
_GRID_WORLD_HTML = '''
<div class="map-grid-world" >
<canvas data-world_name="{0}"></canvas>
<div style="min-height:20px;">
<span></span>
</div>
</div>
<script type="text/javascript">
var gridArray = {1} , size = {2} , elements = {3};
{4}
</script>
'''
with open('js/gridworld.js', 'r') as js_file:
_JS_GRID_WORLD = js_file.read()
class GridWorldView:
""" View for grid world. Uses XYEnviornment in agents.py as model.
world: an instance of XYEnviornment.
block_size: size of individual blocks in pixes.
default_fill: color of blocks. A hex value or name should be passed.
"""
def __init__(self, world, block_size=30, default_fill="white"):
self.time = time.time()
self.world = world
self.labels = defaultdict(str) # locations as keys
self.representation = {"default": {"type": "color", "source": default_fill}}
self.block_size = block_size
def object_name(self):
globals_in_main = {x: getattr(__main__, x) for x in dir(__main__)}
for x in globals_in_main:
if isinstance(globals_in_main[x], type(self)):
if globals_in_main[x].time == self.time:
return x
def set_label(self, coordinates, label):
""" Add lables to a particular block of grid.
coordinates: a tuple of (row, column).
rows and columns are 0 indexed.
"""
self.labels[coordinates] = label
def set_representation(self, thing, repr_type, source):
""" Set the representation of different things in the
environment.
thing: a thing object.
repr_type : type of representation can be either "color" or "img"
source: Hex value in case of color. Image path in case of image.
"""
thing_class_name = thing.__class__.__name__
if repr_type not in ("img", "color"):
raise ValueError('Invalid repr_type passed. Possible types are img/color')
self.representation[thing_class_name] = {"type": repr_type, "source": source}
def handle_click(self, coordinates):
""" This method needs to be overidden. Make sure to include a
self.show() call at the end. """
self.show()
def map_to_render(self):
default_representation = {"val": "default", "tooltip": ""}
world_map = [[copy.deepcopy(default_representation) for _ in range(self.world.width)]
for _ in range(self.world.height)]
for thing in self.world.things:
row, column = thing.location
thing_class_name = thing.__class__.__name__
if thing_class_name not in self.representation:
raise KeyError('Representation not found for {}'.format(thing_class_name))
world_map[row][column]["val"] = thing.__class__.__name__
for location, label in self.labels.items():
row, column = location
world_map[row][column]["tooltip"] = label
return json.dumps(world_map)
def show(self):
clear_output()
total_html = _GRID_WORLD_HTML.format(
self.object_name(), self.map_to_render(),
self.block_size, json.dumps(self.representation), _JS_GRID_WORLD)
display(HTML(total_html))