Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6b556eb

Browse files
committed
Fixed s/object/Object/ -- oops. Converted docex to doctest. Cleanup.
1 parent d43e072 commit 6b556eb

File tree

2 files changed

+54
-66
lines changed

2 files changed

+54
-66
lines changed

agents.py

Lines changed: 47 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def display(self, canvas, x, y, width, height):
6060
"""Display an image of this Object on the canvas."""
6161
pass
6262

63-
class Agent(object):
63+
class Agent(Object):
6464
"""An Agent is a subclass of Object with one required slot,
6565
.program, which should hold a function that takes one argument, the
6666
percept, and returns an action. (What counts as a percept or action
@@ -214,11 +214,11 @@ def object_classes(self):
214214
return [] ## List of classes that can go into environment
215215

216216
def percept(self, agent):
217-
"Return the percept that the agent sees at this point. Override this."
217+
"Return the percept that the agent sees at this point. (Implement this.)"
218218
abstract
219219

220220
def execute_action(self, agent, action):
221-
"Change the world to reflect this action. Override this."
221+
"Change the world to reflect this action. (Implement this.)"
222222
abstract
223223

224224
def default_location(self, object):
@@ -260,23 +260,17 @@ def list_objects_at(self, location, oclass=Object):
260260

261261
def some_objects_at(self, location, oclass=Object):
262262
"""Return true if at least one of the objects at location
263-
is an instance of class oclass.
264-
265-
'Is an instance' in the sense of 'isinstance',
266-
which is true if the object is an instance of a subclass of oclass."""
267-
263+
is an instance of class oclass (or a subclass)."""
268264
return self.list_objects_at(location, oclass) != []
269265

270266
def add_object(self, obj, location=None):
271267
"""Add an object to the environment, setting its location. Also keep
272268
track of objects that are agents. Shouldn't need to override this."""
273-
274269
obj.location = location or self.default_location(obj)
275270
self.objects.append(obj)
276271
if isinstance(obj, Agent):
277272
obj.performance = 0
278273
self.agents.append(obj)
279-
return self
280274

281275
def delete_object(self, obj):
282276
"""Remove an object from the environment."""
@@ -286,15 +280,11 @@ def delete_object(self, obj):
286280
print e
287281
print " in Environment delete_object"
288282
print " Object to be removed: %s at %s" % (obj, obj.location)
289-
trace_list(" from list", self.objects)
283+
print " from list: %s" % [(obj, obj.location)
284+
for obj in self.objects]
290285
if obj in self.agents:
291286
self.agents.remove(obj)
292287

293-
294-
def trace_list (name, objlist):
295-
ol_list = [(obj, obj.location) for obj in objlist]
296-
print "%s: %s" % (name, ol_list)
297-
298288
class XYEnvironment(Environment):
299289
"""This class is for environments on a 2D plane, with locations
300290
labelled by (x, y) points, either discrete or continuous.
@@ -306,22 +296,21 @@ class XYEnvironment(Environment):
306296

307297
def __init__(self, width=10, height=10):
308298
super(XYEnvironment, self).__init__()
309-
self.width = width
310-
self.height = height
311-
#update(self, objects=[], agents=[], width=width, height=height)
312-
self.observers = []
299+
update(self, width=width, height=height, observers=[])
313300

314-
def objects_near(self, location, radius):
301+
def objects_near(self, location, radius=None):
315302
"Return all objects within radius of location."
303+
if radius is None: radius = self.perceptible_distance
316304
radius2 = radius * radius
317305
return [obj for obj in self.objects
318306
if distance2(location, obj.location) <= radius2]
319307

308+
perceptible_distance = 1
309+
320310
def percept(self, agent):
321-
"By default, agent perceives objects within radius r."
322-
### Error below: objects_near requires also a radius argument
311+
"By default, agent perceives objects within a default radius."
323312
return [self.object_percept(obj, agent)
324-
for obj in self.objects_near(agent)] ### <- error
313+
for obj in self.objects_near(agent.location)]
325314

326315
def execute_action(self, agent, action):
327316
agent.bump = False
@@ -349,12 +338,8 @@ def default_location(self, object):
349338

350339
def move_to(self, obj, destination):
351340
"Move an object to a new location."
352-
353-
# Bumped?
354341
obj.bump = self.some_objects_at(destination, Obstacle)
355-
356342
if not obj.bump:
357-
# Move object and report to observers
358343
obj.location = destination
359344
for o in self.observers:
360345
o.object_moved(obj)
@@ -363,8 +348,6 @@ def add_object(self, obj, location=(1, 1)):
363348
super(XYEnvironment, self).add_object(obj, location)
364349
obj.holding = []
365350
obj.held = None
366-
# self.objects.append(obj) # done in Environment!
367-
# Report to observers
368351
for obs in self.observers:
369352
obs.object_added(obj)
370353

@@ -392,11 +375,11 @@ def add_observer(self, observer):
392375
and object_added(obj, loc)."""
393376
self.observers.append(observer)
394377

395-
def turn_heading(self, heading, inc, headings=orientations):
396-
"Return the heading to the left (inc=+1) or right (inc=-1) in headings."
397-
return headings[(headings.index(heading) + inc) % len(headings)]
378+
def turn_heading(self, heading, inc):
379+
"Return the heading to the left (inc=+1) or right (inc=-1) of heading."
380+
return turn_heading(heading, inc)
398381

399-
class Obstacle(object):
382+
class Obstacle(Object):
400383
"""Something that can cause a bump, preventing an agent from
401384
moving into the same square it's in."""
402385
pass
@@ -407,7 +390,7 @@ class Wall(Obstacle):
407390
#______________________________________________________________________________
408391
## Vacuum environment
409392

410-
class Dirt(object):
393+
class Dirt(Object):
411394
pass
412395

413396
class VacuumEnvironment(XYEnvironment):
@@ -446,16 +429,15 @@ def execute_action(self, agent, action):
446429
agent.performance -= 1
447430

448431
class TrivialVacuumEnvironment(Environment):
449-
450432
"""This environment has two locations, A and B. Each can be Dirty
451433
or Clean. The agent perceives its location and the location's
452434
status. This serves as an example of how to implement a simple
453435
Environment."""
454436

455437
def __init__(self):
456438
super(TrivialVacuumEnvironment, self).__init__()
457-
self.status = {loc_A:random.choice(['Clean', 'Dirty']),
458-
loc_B:random.choice(['Clean', 'Dirty'])}
439+
self.status = {loc_A: random.choice(['Clean', 'Dirty']),
440+
loc_B: random.choice(['Clean', 'Dirty'])}
459441

460442
def object_classes(self):
461443
return [Wall, Dirt, ReflexVacuumAgent, RandomVacuumAgent,
@@ -532,9 +514,9 @@ def rule_match(state, rules):
532514
#______________________________________________________________________________
533515
## The Wumpus World
534516

535-
class Gold(object): pass
536-
class Pit(object): pass
537-
class Arrow(object): pass
517+
class Gold(Object): pass
518+
class Pit(Object): pass
519+
class Arrow(Object): pass
538520
class Wumpus(Agent): pass
539521
class Explorer(Agent): pass
540522

@@ -573,31 +555,34 @@ def test_agent(AgentFactory, steps, envs):
573555

574556
#_________________________________________________________________________
575557

576-
_docex = """
577-
a = ReflexVacuumAgent()
578-
a.program
579-
a.program((loc_A, 'Clean')) ==> 'Right'
580-
a.program((loc_B, 'Clean')) ==> 'Left'
581-
a.program((loc_A, 'Dirty')) ==> 'Suck'
582-
a.program((loc_A, 'Dirty')) ==> 'Suck'
583-
584-
e = TrivialVacuumEnvironment()
585-
e.add_object(TraceAgent(ModelBasedVacuumAgent()))
586-
e.run(5)
558+
__doc__ += """
559+
>>> a = ReflexVacuumAgent()
560+
>>> a.program((loc_A, 'Clean'))
561+
'Right'
562+
>>> a.program((loc_B, 'Clean'))
563+
'Left'
564+
>>> a.program((loc_A, 'Dirty'))
565+
'Suck'
566+
>>> a.program((loc_A, 'Dirty'))
567+
'Suck'
568+
569+
>>> e = TrivialVacuumEnvironment()
570+
>>> e.add_object(ModelBasedVacuumAgent()); None
571+
>>> e.run(5)
587572
588573
## Environments, and some agents, are randomized, so the best we can
589574
## give is a range of expected scores. If this test fails, it does
590575
## not necessarily mean something is wrong.
591-
envs = [TrivialVacuumEnvironment() for i in range(100)]
592-
def testv(A): return test_agent(A, 4, copy.deepcopy(envs))
593-
testv(ModelBasedVacuumAgent)
594-
(7 < _ < 11) ==> True
595-
testv(ReflexVacuumAgent)
596-
(5 < _ < 9) ==> True
597-
testv(TableDrivenVacuumAgent)
598-
(2 < _ < 6) ==> True
599-
testv(RandomVacuumAgent)
600-
(0.5 < _ < 3) ==> True
576+
>>> envs = [TrivialVacuumEnvironment() for i in range(100)]
577+
>>> def testv(A): return test_agent(A, 4, copy.deepcopy(envs))
578+
>>> 7 < testv(ModelBasedVacuumAgent) < 11
579+
True
580+
>>> 5 < testv(ReflexVacuumAgent) < 9
581+
True
582+
>>> 2 < testv(TableDrivenVacuumAgent) < 6
583+
True
584+
>>> 0.5 < testv(RandomVacuumAgent) < 3
585+
True
601586
"""
602587

603588
#______________________________________________________________________________

utils.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -525,11 +525,14 @@ def normalize(numbers, total=1.0):
525525

526526
orientations = [(1, 0), (0, 1), (-1, 0), (0, -1)]
527527

528-
def turn_right(orientation):
529-
return orientations[orientations.index(orientation)-1]
528+
def turn_heading(heading, inc, headings=orientations):
529+
return headings[(headings.index(heading) + inc) % len(headings)]
530530

531-
def turn_left(orientation):
532-
return orientations[(orientations.index(orientation)+1) % len(orientations)]
531+
def turn_right(heading):
532+
return turn_heading(heading, -1)
533+
534+
def turn_left(heading):
535+
return turn_heading(heading, +1)
533536

534537
def distance((ax, ay), (bx, by)):
535538
"The distance between two (x, y) points."

0 commit comments

Comments
 (0)