Skip to content

Commit 04b3326

Browse files
tirthasheshpatelantmarakis
authored andcommitted
[MRG] ENH: Small improvements for agents.py (aimacode#1139)
* ENH: Small improvements for agents.py * FIXUP: fix `add_thing` to pass the tests * [MRG] ENH: Add small chnages to agents.py * [MRG] FIX: `default_location` now returns a valid location * FIXUP: fix `default_location` in agents4e.py and modify tests
1 parent c587f2c commit 04b3326

File tree

4 files changed

+63
-33
lines changed

4 files changed

+63
-33
lines changed

agents.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from utils import distance_squared, turn_heading
3838
from statistics import mean
3939
from ipythonblocks import BlockGrid
40-
from IPython.display import HTML, display
40+
from IPython.display import HTML, display, clear_output
4141
from time import sleep
4242

4343
import random
@@ -89,7 +89,7 @@ def __init__(self, program=None):
8989
self.bump = False
9090
self.holding = []
9191
self.performance = 0
92-
if program is None or not isinstance(program, collections.Callable):
92+
if program is None or not isinstance(program, collections.abc.Callable):
9393
print("Can't find a valid program for {}, falling back to default.".format(self.__class__.__name__))
9494

9595
def program(percept):
@@ -455,15 +455,17 @@ def move_forward(self, from_location):
455455
>>> l1
456456
(1, 0)
457457
"""
458+
# get the iterable class to return
459+
iclass = from_location.__class__
458460
x, y = from_location
459461
if self.direction == self.R:
460-
return x + 1, y
462+
return iclass((x + 1, y))
461463
elif self.direction == self.L:
462-
return x - 1, y
464+
return iclass((x - 1, y))
463465
elif self.direction == self.U:
464-
return x, y - 1
466+
return iclass((x, y - 1))
465467
elif self.direction == self.D:
466-
return x, y + 1
468+
return iclass((x, y + 1))
467469

468470

469471
class XYEnvironment(Environment):
@@ -518,7 +520,11 @@ def execute_action(self, agent, action):
518520
agent.holding.pop()
519521

520522
def default_location(self, thing):
521-
return random.choice(self.width), random.choice(self.height)
523+
location = self.random_location_inbounds()
524+
while self.some_things_at(location, Obstacle):
525+
# we will find a random location with no obstacles
526+
location = self.random_location_inbounds()
527+
return location
522528

523529
def move_to(self, thing, destination):
524530
"""Move a thing to a new location. Returns True on success or False if there is an Obstacle.
@@ -534,10 +540,12 @@ def move_to(self, thing, destination):
534540
t.location = destination
535541
return thing.bump
536542

537-
def add_thing(self, thing, location=(1, 1), exclude_duplicate_class_items=False):
543+
def add_thing(self, thing, location=None, exclude_duplicate_class_items=False):
538544
"""Add things to the world. If (exclude_duplicate_class_items) then the item won't be
539545
added if the location has at least one item of the same class."""
540-
if self.is_inbounds(location):
546+
if location is None:
547+
super().add_thing(thing)
548+
elif self.is_inbounds(location):
541549
if (exclude_duplicate_class_items and
542550
any(isinstance(t, thing.__class__) for t in self.list_things_at(location))):
543551
return
@@ -666,16 +674,16 @@ def run(self, steps=1000, delay=1):
666674

667675
def update(self, delay=1):
668676
sleep(delay)
669-
if self.visible:
670-
self.conceal()
671-
self.reveal()
672-
else:
673-
self.reveal()
677+
self.reveal()
674678

675679
def reveal(self):
676680
"""Display the BlockGrid for this world - the last thing to be added
677681
at a location defines the location color."""
678682
self.draw_world()
683+
# wait for the world to update and
684+
# apply changes to the same grid instead
685+
# of making a new one.
686+
clear_output(1)
679687
self.grid.show()
680688
self.visible = True
681689

agents4e.py

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from utils4e import distance_squared, turn_heading
3838
from statistics import mean
3939
from ipythonblocks import BlockGrid
40-
from IPython.display import HTML, display
40+
from IPython.display import HTML, display, clear_output
4141
from time import sleep
4242

4343
import random
@@ -89,7 +89,7 @@ def __init__(self, program=None):
8989
self.bump = False
9090
self.holding = []
9191
self.performance = 0
92-
if program is None or not isinstance(program, collections.Callable):
92+
if program is None or not isinstance(program, collections.abc.Callable):
9393
print("Can't find a valid program for {}, falling back to default.".format(self.__class__.__name__))
9494

9595
def program(percept):
@@ -455,15 +455,17 @@ def move_forward(self, from_location):
455455
>>> l1
456456
(1, 0)
457457
"""
458+
# get the iterable class to return
459+
iclass = from_location.__class__
458460
x, y = from_location
459461
if self.direction == self.R:
460-
return x + 1, y
462+
return iclass((x + 1, y))
461463
elif self.direction == self.L:
462-
return x - 1, y
464+
return iclass((x - 1, y))
463465
elif self.direction == self.U:
464-
return x, y - 1
466+
return iclass((x, y - 1))
465467
elif self.direction == self.D:
466-
return x, y + 1
468+
return iclass((x, y + 1))
467469

468470

469471
class XYEnvironment(Environment):
@@ -518,7 +520,11 @@ def execute_action(self, agent, action):
518520
agent.holding.pop()
519521

520522
def default_location(self, thing):
521-
return random.choice(self.width), random.choice(self.height)
523+
location = self.random_location_inbounds()
524+
while self.some_things_at(location, Obstacle):
525+
# we will find a random location with no obstacles
526+
location = self.random_location_inbounds()
527+
return location
522528

523529
def move_to(self, thing, destination):
524530
"""Move a thing to a new location. Returns True on success or False if there is an Obstacle.
@@ -534,10 +540,12 @@ def move_to(self, thing, destination):
534540
t.location = destination
535541
return thing.bump
536542

537-
def add_thing(self, thing, location=(1, 1), exclude_duplicate_class_items=False):
543+
def add_thing(self, thing, location=None, exclude_duplicate_class_items=False):
538544
"""Add things to the world. If (exclude_duplicate_class_items) then the item won't be
539545
added if the location has at least one item of the same class."""
540-
if self.is_inbounds(location):
546+
if location is None:
547+
super().add_thing(thing)
548+
elif self.is_inbounds(location):
541549
if (exclude_duplicate_class_items and
542550
any(isinstance(t, thing.__class__) for t in self.list_things_at(location))):
543551
return
@@ -666,16 +674,16 @@ def run(self, steps=1000, delay=1):
666674

667675
def update(self, delay=1):
668676
sleep(delay)
669-
if self.visible:
670-
self.conceal()
671-
self.reveal()
672-
else:
673-
self.reveal()
677+
self.reveal()
674678

675679
def reveal(self):
676680
"""Display the BlockGrid for this world - the last thing to be added
677681
at a location defines the location color."""
678682
self.draw_world()
683+
# wait for the world to update and
684+
# apply changes to the same grid instead
685+
# of making a new one.
686+
clear_output(1)
679687
self.grid.show()
680688
self.visible = True
681689

tests/test_agents.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
SimpleReflexAgentProgram, ModelBasedReflexAgentProgram, Wall, Gold, Explorer, Thing, Bump, Glitter,
88
WumpusEnvironment, Pit, VacuumEnvironment, Dirt, Direction, Agent)
99

10-
random.seed("aima-python")
11-
10+
# random seed may affect the placement
11+
# of things in the environment which may
12+
# lead to failure of tests. Please change
13+
# the seed if the tests are failing with
14+
# current changes in any stochastic method
15+
# function or variable.
16+
random.seed(9)
1217

1318
def test_move_forward():
1419
d = Direction("up")
@@ -88,6 +93,7 @@ def test_RandomVacuumAgent():
8893

8994

9095
def test_TableDrivenAgent():
96+
random.seed(10)
9197
loc_A, loc_B = (0, 0), (1, 0)
9298
# table defining all the possible states of the agent
9399
table = {((loc_A, 'Clean'),): 'Right',
@@ -346,6 +352,7 @@ def constant_prog(percept):
346352

347353

348354
def test_WumpusEnvironmentActions():
355+
random.seed(9)
349356
def constant_prog(percept):
350357
return percept
351358

tests/test_agents4e.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@
77
SimpleReflexAgentProgram, ModelBasedReflexAgentProgram, Wall, Gold, Explorer, Thing, Bump,
88
Glitter, WumpusEnvironment, Pit, VacuumEnvironment, Dirt, Direction, Agent)
99

10-
random.seed("aima-python")
11-
10+
# random seed may affect the placement
11+
# of things in the environment which may
12+
# lead to failure of tests. Please change
13+
# the seed if the tests are failing with
14+
# current changes in any stochastic method
15+
# function or variable.
16+
random.seed(9)
1217

1318
def test_move_forward():
1419
d = Direction("up")
@@ -88,6 +93,7 @@ def test_RandomVacuumAgent():
8893

8994

9095
def test_TableDrivenAgent():
96+
random.seed(10)
9197
loc_A, loc_B = (0, 0), (1, 0)
9298
# table defining all the possible states of the agent
9399
table = {((loc_A, 'Clean'),): 'Right',
@@ -271,7 +277,7 @@ def test_VacuumEnvironment():
271277
# get an agent
272278
agent = ModelBasedVacuumAgent()
273279
agent.direction = Direction(Direction.R)
274-
v.add_thing(agent)
280+
v.add_thing(agent, location=(1, 1))
275281
v.add_thing(Dirt(), location=(2, 1))
276282

277283
# check if things are added properly
@@ -345,6 +351,7 @@ def constant_prog(percept):
345351

346352

347353
def test_WumpusEnvironmentActions():
354+
random.seed(9)
348355
def constant_prog(percept):
349356
return percept
350357

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy