Skip to content

Commit

Permalink
Resolve #24.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmorrill10 committed Jul 4, 2018
1 parent 934dd07 commit 13bc914
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 67 deletions.
5 changes: 3 additions & 2 deletions driving_gridworld/human_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ def color256_to_1000(c):
'|': (color256_to_1000(67), color256_to_1000(70), color256_to_1000(75)),
'd': (color256_to_1000(87), color256_to_1000(59), color256_to_1000(12)),
'C': (0, 999, 999),
'b': (0, 0, 0),
'p': (987, 623, 145)
'b': (color256_to_1000(83), color256_to_1000(77), color256_to_1000(74)),
'p': (987, 623, 145),
'^': (100, 999, 100)
}
COLOUR_BG = {}
obs_to_rgb = ObservationToArray(COLOUR_FG)
Expand Down
54 changes: 33 additions & 21 deletions driving_gridworld/road.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ def _byte(c, encoding='ascii'):


class Road(object):
_num_lanes = 4
_speedometer_col_idx = -1
_world_width = _num_lanes + 2 + 1

def __init__(self, headlight_range, car, obstacles=[]):
self._headlight_range = headlight_range

Expand All @@ -43,12 +47,11 @@ def __init__(self, headlight_range, car, obstacles=[]):
self._available_spaces = set()

def __eq__(self, other):
return (
self._headlight_range == other._headlight_range
and self._num_lanes == other._num_lanes
and self._car == other._car
and self._obstacles == other._obstacles
and self._available_spaces == other._available_spaces)
return (self._headlight_range == other._headlight_range
and self._num_lanes == other._num_lanes
and self._car == other._car
and self._obstacles == other._obstacles
and self._available_spaces == other._available_spaces)

def copy(self):
return self.__class__(self._headlight_range, self._car,
Expand Down Expand Up @@ -175,7 +178,7 @@ def successors(self, action):
yield (next_road, prob, reward)

def is_off_road(self):
return self._car.col == 0 or self._car.col == 3
return self._car.col <= 0 or self._car.col >= 3

def to_key(self):
obstacles = []
Expand Down Expand Up @@ -205,28 +208,33 @@ def prob_obstacle_appears(self, obstacle, num_obstacles_revealed,
if this_obstacle_could_appear else 0)

def car_layer(self):
layer = np.full([self._num_rows(), self._num_lanes + 2], False)
layer = np.full([self._num_rows(), self._world_width], False)
layer[self._car_row(), self._car.col + 1] = True
return layer

def wall_layer(self):
layer = np.full([self._num_rows(), self._num_lanes + 2], False)
layer = np.full([self._num_rows(), self._world_width], False)
layer[:, 0] = True
layer[:, -1] = True
layer[:, -2] = True
return layer

def ditch_layer(self):
layer = np.full([self._num_rows(), self._num_lanes + 2], False)
layer = np.full([self._num_rows(), self._world_width], False)
layer[:, 1] = True
layer[:, -2] = True
layer[:, -3] = True
return layer

def speedometer_layer(self):
layer = np.full([self._num_rows(), self._world_width], False)
layer[-self._car.speed:, -1] = True
return layer

def obstacle_layers(self):
layers = {}
for o in self._obstacles:
c = str(o)
if c not in layers:
layers[c] = np.full([self._num_rows(), self._num_lanes + 2],
layers[c] = np.full([self._num_rows(), self._world_width],
False)
if self.obstacle_is_visible(o):
layers[c][o.row, o.col + 1] = True
Expand All @@ -237,20 +245,25 @@ def layers(self):
layers[str(self._car)] = self.car_layer()
layers['|'] = self.wall_layer()
layers['d'] = self.ditch_layer()
layers['^'] = self.speedometer_layer()

full_layer = np.full([self._num_rows(), self._num_lanes + 2], False)
full_layer = np.full([self._num_rows(), self._world_width], False)
for l in layers.values():
np.logical_or(full_layer, l, out=full_layer)
layers[' '] = np.logical_not(full_layer)

return layers

def ordered_layers(self):
obstacle_layers = self.obstacle_layers()

layers = [(' ', np.full([self._num_rows(), self._num_lanes + 2],
False)), ('|', self.wall_layer()),
('d', self.ditch_layer())] + list(obstacle_layers.items())
layers = (
[
(' ', np.full([self._num_rows(), self._world_width], False)),
('|', self.wall_layer()),
('d', self.ditch_layer()),
('^', self.speedometer_layer())
]
+ list(self.obstacle_layers().items())
) # yapf:disable
layers.append((str(self._car), self.car_layer()))

for i in range(1, len(layers)):
Expand All @@ -260,8 +273,7 @@ def ordered_layers(self):
return layers

def board(self):
board = np.zeros(
[self._num_rows(), self._num_lanes + 2], dtype='uint8')
board = np.zeros([self._num_rows(), self._world_width], dtype='uint8')
for c, layer in self.ordered_layers():
partial = np.multiply(_byte(c), layer, dtype='uint8')
is_present = partial > 0
Expand Down
49 changes: 29 additions & 20 deletions test/gridworld_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,46 +26,55 @@ def test_initial_observation():
np.testing.assert_array_equal(
o.board,
np.array(
[[124, 100, 32, 32, 100, 124],
[124, 100, 32, 32, 100, 124],
[124, 100, 32, 32, 100, 124],
[124, 100, 32, 67, 100, 124]]).astype('uint8')
[[124, 100, 32, 32, 100, 124, 32],
[124, 100, 32, 32, 100, 124, 32],
[124, 100, 32, 32, 100, 124, 32],
[124, 100, 32, 67, 100, 124, 94]]).astype('uint8')
) # yapf:disable

np.testing.assert_array_equal(
o.layers['C'],
np.array(
[[False, False, False, False, False, False],
[False, False, False, False, False, False],
[False, False, False, False, False, False],
[False, False, False, True, False, False]])
[[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, True, False, False, False]])
) # yapf:disable

np.testing.assert_array_equal(
o.layers['|'],
np.array(
[[ True, False, False, False, False, True],
[ True, False, False, False, False, True],
[ True, False, False, False, False, True],
[ True, False, False, False, False, True]])
[[ True, False, False, False, False, True, False],
[ True, False, False, False, False, True, False],
[ True, False, False, False, False, True, False],
[ True, False, False, False, False, True, False]])
) # yapf:disable

np.testing.assert_array_equal(
o.layers['d'],
np.array(
[[False, True, False, False, True, False],
[False, True, False, False, True, False],
[False, True, False, False, True, False],
[False, True, False, False, True, False]])
[[False, True, False, False, True, False, False],
[False, True, False, False, True, False, False],
[False, True, False, False, True, False, False],
[False, True, False, False, True, False, False]])
) # yapf:disable

np.testing.assert_array_equal(
o.layers[' '],
np.array(
[[False, False, True, True, False, False],
[False, False, True, True, False, False],
[False, False, True, True, False, False],
[False, False, True, False, False, False]])
[[False, False, True, True, False, False, True],
[False, False, True, True, False, False, True],
[False, False, True, True, False, False, True],
[False, False, True, False, False, False, False]])
) # yapf:disable

np.testing.assert_array_equal(
o.layers['^'],
np.array(
[[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, False],
[False, False, False, False, False, False, True]])
) # yapf:disable


Expand Down
61 changes: 37 additions & 24 deletions test/road_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,26 +104,26 @@ def test_car_can_only_overdrive_headlights_by_one_unit():
@pytest.mark.parametrize('headlight_range', range(1, 11))
def test_car_layer(col, headlight_range):
patient = Road(headlight_range, Car(col, 1), [])
x = np.full([headlight_range + 1, 6], False)
x = np.full([headlight_range + 1, 7], False)
x[headlight_range, col + 1] = True
np.testing.assert_array_equal(patient.car_layer(), x)


@pytest.mark.parametrize('headlight_range', range(1, 11))
def test_wall_layer(headlight_range):
patient = Road(headlight_range, Car(1, 1), [])
x = np.full([headlight_range + 1, 6], False)
x = np.full([headlight_range + 1, 7], False)
x[:, 0] = True
x[:, -1] = True
x[:, -2] = True
np.testing.assert_array_equal(patient.wall_layer(), x)


@pytest.mark.parametrize('headlight_range', range(1, 11))
def test_ditch_layer(headlight_range):
patient = Road(headlight_range, Car(1, 1), [])
x = np.full([headlight_range + 1, 6], False)
x = np.full([headlight_range + 1, 7], False)
x[:, 1] = True
x[:, -2] = True
x[:, -3] = True
np.testing.assert_array_equal(patient.ditch_layer(), x)


Expand All @@ -136,12 +136,12 @@ def test_obstacle_layers():

assert len(patient) == 2

x_bump_layer = np.full([headlight_range + 1, 6], False)
x_bump_layer = np.full([headlight_range + 1, 7], False)
x_bump_layer[0, 1] = True
x_bump_layer[1, 4] = True
np.testing.assert_array_equal(patient[str(bumps[0])], x_bump_layer)

x_pedestrian_layer = np.full([headlight_range + 1, 6], False)
x_pedestrian_layer = np.full([headlight_range + 1, 7], False)
x_pedestrian_layer[0, 2] = True
x_pedestrian_layer[1, 3] = True
np.testing.assert_array_equal(patient[str(pedestrians[0])],
Expand All @@ -155,48 +155,56 @@ def test_obstacles_outside_headlight_range_are_hidden():

assert len(patient) == 1

x_bump_layer = np.full([headlight_range + 1, 6], False)
x_bump_layer = np.full([headlight_range + 1, 7], False)
np.testing.assert_array_equal(patient[str(bumps[0])], x_bump_layer)


def test_layers():
bumps = [Bump(-1, -1), Bump(0, 0), Bump(1, 3)]
pedestrians = [Pedestrian(-1, -1), Pedestrian(0, 1), Pedestrian(1, 2)]
headlight_range = 4
patient = Road(headlight_range, Car(1, 1), bumps + pedestrians).layers()
speed = 1
patient = Road(headlight_range, Car(1, speed=speed),
bumps + pedestrians).layers()

assert len(patient) == 6
assert len(patient) == 7

x_bump_layer = np.full([headlight_range + 1, 6], False)
x_bump_layer = np.full([headlight_range + 1, 7], False)
x_bump_layer[0, 1] = True
x_bump_layer[1, 4] = True
np.testing.assert_array_equal(patient[str(bumps[0])], x_bump_layer)

x_pedestrian_layer = np.full([headlight_range + 1, 6], False)
x_pedestrian_layer = np.full([headlight_range + 1, 7], False)
x_pedestrian_layer[0, 2] = True
x_pedestrian_layer[1, 3] = True
np.testing.assert_array_equal(patient[str(pedestrians[0])],
x_pedestrian_layer)

x_car_layer = np.full([headlight_range + 1, 6], False)
x_car_layer = np.full([headlight_range + 1, 7], False)
x_car_layer[headlight_range, 1 + 1] = True
np.testing.assert_array_equal(patient['C'], x_car_layer)

x_wall_layer = np.full([headlight_range + 1, 6], False)
x_wall_layer = np.full([headlight_range + 1, 7], False)
x_wall_layer[:, 0] = True
x_wall_layer[:, -1] = True
x_wall_layer[:, -2] = True
np.testing.assert_array_equal(patient['|'], x_wall_layer)

x_ditch_layer = np.full([headlight_range + 1, 6], False)
x_ditch_layer = np.full([headlight_range + 1, 7], False)
x_ditch_layer[:, 1] = True
x_ditch_layer[:, -2] = True
x_ditch_layer[:, -3] = True
np.testing.assert_array_equal(patient['d'], x_ditch_layer)

x_speedometer_layer = np.full([headlight_range + 1, 7], False)
x_speedometer_layer[-speed:, -1] = True
np.testing.assert_array_equal(patient['^'], x_speedometer_layer)

x_empty_layer = np.logical_not(
np.logical_or(x_ditch_layer,
np.logical_or(x_speedometer_layer,
np.logical_or(
np.logical_or(x_bump_layer, x_pedestrian_layer),
np.logical_or(x_car_layer, x_wall_layer))))
x_ditch_layer,
np.logical_or(
np.logical_or(x_bump_layer, x_pedestrian_layer),
np.logical_or(x_car_layer, x_wall_layer)))))
np.testing.assert_array_equal(patient[' '], x_empty_layer)


Expand All @@ -208,17 +216,22 @@ def test_board():
bumps = [Bump(-1, -1), Bump(0, 0), Bump(1, 3)]
pedestrians = [Pedestrian(-1, -1), Pedestrian(0, 1), Pedestrian(1, 2)]
headlight_range = 4
patient = Road(headlight_range, Car(1, 1), bumps + pedestrians).board()
speed = 1
patient = Road(headlight_range, Car(1, speed=speed),
bumps + pedestrians).board()

assert patient.dtype == 'uint8'

x_board = np.full([headlight_range + 1, 6], _byte(' '), dtype='uint8')
x_board = np.full(
[headlight_range + 1, Road._world_width], _byte(' '), dtype='uint8')

x_board[:, 0] = _byte('|')
x_board[:, -1] = _byte('|')
x_board[:, -2] = _byte('|')

x_board[:, 1] = _byte('d')
x_board[:, -2] = _byte('d')
x_board[:, -3] = _byte('d')

x_board[-speed:, -1] = _byte('^')

x_board[0, 1] = bumps[0].to_byte()
x_board[1, 4] = bumps[0].to_byte()
Expand Down

0 comments on commit 13bc914

Please sign in to comment.