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_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>
'''
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_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)
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))