@@ -113,9 +113,11 @@ def new_program(percept):
113113 action = old_program (percept )
114114 print ('{} perceives {} and does {}' .format (agent , percept , action ))
115115 return action
116+
116117 agent .program = new_program
117118 return agent
118119
120+
119121# ______________________________________________________________________________
120122
121123
@@ -130,6 +132,7 @@ def program(percept):
130132 percepts .append (percept )
131133 action = table .get (tuple (percepts ))
132134 return action
135+
133136 return program
134137
135138
@@ -146,26 +149,31 @@ def RandomAgentProgram(actions):
146149 """
147150 return lambda percept : random .choice (actions )
148151
152+
149153# ______________________________________________________________________________
150154
151155
152156def SimpleReflexAgentProgram (rules , interpret_input ):
153157 """This agent takes action based solely on the percept. [Figure 2.10]"""
158+
154159 def program (percept ):
155160 state = interpret_input (percept )
156161 rule = rule_match (state , rules )
157162 action = rule .action
158163 return action
164+
159165 return program
160166
161167
162168def ModelBasedReflexAgentProgram (rules , update_state , trainsition_model , sensor_model ):
163169 """This agent takes action based on the percept and state. [Figure 2.12]"""
170+
164171 def program (percept ):
165172 program .state = update_state (program .state , program .action , percept , trainsition_model , sensor_model )
166173 rule = rule_match (program .state , rules )
167174 action = rule .action
168175 return action
176+
169177 program .state = program .action = None
170178 return program
171179
@@ -176,6 +184,7 @@ def rule_match(state, rules):
176184 if rule .matches (state ):
177185 return rule
178186
187+
179188# ______________________________________________________________________________
180189
181190
@@ -219,6 +228,7 @@ def ReflexVacuumAgent():
219228 >>> environment.status == {(1,0):'Clean' , (0,0) : 'Clean'}
220229 True
221230 """
231+
222232 def program (percept ):
223233 location , status = percept
224234 if status == 'Dirty' :
@@ -227,6 +237,7 @@ def program(percept):
227237 return 'Right'
228238 elif location == loc_B :
229239 return 'Left'
240+
230241 return Agent (program )
231242
232243
@@ -253,8 +264,10 @@ def program(percept):
253264 return 'Right'
254265 elif location == loc_B :
255266 return 'Left'
267+
256268 return Agent (program )
257269
270+
258271# ______________________________________________________________________________
259272
260273
@@ -392,22 +405,22 @@ def __add__(self, heading):
392405 True
393406 """
394407 if self .direction == self .R :
395- return {
408+ return {
396409 self .R : Direction (self .D ),
397410 self .L : Direction (self .U ),
398411 }.get (heading , None )
399412 elif self .direction == self .L :
400- return {
413+ return {
401414 self .R : Direction (self .U ),
402415 self .L : Direction (self .D ),
403416 }.get (heading , None )
404417 elif self .direction == self .U :
405- return {
418+ return {
406419 self .R : Direction (self .R ),
407420 self .L : Direction (self .L ),
408421 }.get (heading , None )
409422 elif self .direction == self .D :
410- return {
423+ return {
411424 self .R : Direction (self .L ),
412425 self .L : Direction (self .R ),
413426 }.get (heading , None )
@@ -425,13 +438,13 @@ def move_forward(self, from_location):
425438 """
426439 x , y = from_location
427440 if self .direction == self .R :
428- return ( x + 1 , y )
441+ return x + 1 , y
429442 elif self .direction == self .L :
430- return ( x - 1 , y )
443+ return x - 1 , y
431444 elif self .direction == self .U :
432- return ( x , y - 1 )
445+ return x , y - 1
433446 elif self .direction == self .D :
434- return ( x , y + 1 )
447+ return x , y + 1
435448
436449
437450class XYEnvironment (Environment ):
@@ -462,7 +475,7 @@ def things_near(self, location, radius=None):
462475 radius2 = radius * radius
463476 return [(thing , radius2 - distance_squared (location , thing .location ))
464477 for thing in self .things if distance_squared (
465- location , thing .location ) <= radius2 ]
478+ location , thing .location ) <= radius2 ]
466479
467480 def percept (self , agent ):
468481 """By default, agent perceives things within a default radius."""
@@ -476,17 +489,17 @@ def execute_action(self, agent, action):
476489 agent .direction += Direction .L
477490 elif action == 'Forward' :
478491 agent .bump = self .move_to (agent , agent .direction .move_forward (agent .location ))
479- # elif action == 'Grab':
480- # things = [thing for thing in self.list_things_at(agent.location)
481- # if agent.can_grab(thing)]
482- # if things:
483- # agent.holding.append(things[0])
492+ # elif action == 'Grab':
493+ # things = [thing for thing in self.list_things_at(agent.location)
494+ # if agent.can_grab(thing)]
495+ # if things:
496+ # agent.holding.append(things[0])
484497 elif action == 'Release' :
485498 if agent .holding :
486499 agent .holding .pop ()
487500
488501 def default_location (self , thing ):
489- return ( random .choice (self .width ), random .choice (self .height ) )
502+ return random .choice (self .width ), random .choice (self .height )
490503
491504 def move_to (self , thing , destination ):
492505 """Move a thing to a new location. Returns True on success or False if there is an Obstacle.
@@ -505,7 +518,7 @@ def move_to(self, thing, destination):
505518 def add_thing (self , thing , location = (1 , 1 ), exclude_duplicate_class_items = False ):
506519 """Add things to the world. If (exclude_duplicate_class_items) then the item won't be
507520 added if the location has at least one item of the same class."""
508- if ( self .is_inbounds (location ) ):
521+ if self .is_inbounds (location ):
509522 if (exclude_duplicate_class_items and
510523 any (isinstance (t , thing .__class__ ) for t in self .list_things_at (location ))):
511524 return
@@ -514,14 +527,14 @@ def add_thing(self, thing, location=(1, 1), exclude_duplicate_class_items=False)
514527 def is_inbounds (self , location ):
515528 """Checks to make sure that the location is inbounds (within walls if we have walls)"""
516529 x , y = location
517- return not (x < self .x_start or x >= self .x_end or y < self .y_start or y >= self .y_end )
530+ return not (x < self .x_start or x > self .x_end or y < self .y_start or y > self .y_end )
518531
519532 def random_location_inbounds (self , exclude = None ):
520533 """Returns a random location that is inbounds (within walls if we have walls)"""
521534 location = (random .randint (self .x_start , self .x_end ),
522535 random .randint (self .y_start , self .y_end ))
523536 if exclude is not None :
524- while ( location == exclude ) :
537+ while location == exclude :
525538 location = (random .randint (self .x_start , self .x_end ),
526539 random .randint (self .y_start , self .y_end ))
527540 return location
@@ -543,7 +556,7 @@ def add_walls(self):
543556 for x in range (self .width ):
544557 self .add_thing (Wall (), (x , 0 ))
545558 self .add_thing (Wall (), (x , self .height - 1 ))
546- for y in range (1 , self .height - 1 ):
559+ for y in range (1 , self .height - 1 ):
547560 self .add_thing (Wall (), (0 , y ))
548561 self .add_thing (Wall (), (self .width - 1 , y ))
549562
@@ -574,6 +587,7 @@ class Obstacle(Thing):
574587class Wall (Obstacle ):
575588 pass
576589
590+
577591# ______________________________________________________________________________
578592
579593
@@ -682,6 +696,7 @@ def __init__(self, coordinates):
682696 super ().__init__ ()
683697 self .coordinates = coordinates
684698
699+
685700# ______________________________________________________________________________
686701# Vacuum environment
687702
@@ -691,7 +706,6 @@ class Dirt(Thing):
691706
692707
693708class VacuumEnvironment (XYEnvironment ):
694-
695709 """The environment of [Ex. 2.12]. Agent perceives dirty or clean,
696710 and bump (into obstacle) or not; 2D discrete world of unknown size;
697711 performance measure is 100 for each dirt cleaned, and -1 for
@@ -710,7 +724,7 @@ def percept(self, agent):
710724 Unlike the TrivialVacuumEnvironment, location is NOT perceived."""
711725 status = ('Dirty' if self .some_things_at (
712726 agent .location , Dirt ) else 'Clean' )
713- bump = ('Bump' if agent .bump else 'None' )
727+ bump = ('Bump' if agent .bump else 'None' )
714728 return (status , bump )
715729
716730 def execute_action (self , agent , action ):
@@ -729,7 +743,6 @@ def execute_action(self, agent, action):
729743
730744
731745class TrivialVacuumEnvironment (Environment ):
732-
733746 """This environment has two locations, A and B. Each can be Dirty
734747 or Clean. The agent perceives its location and the location's
735748 status. This serves as an example of how to implement a simple
@@ -766,6 +779,7 @@ def default_location(self, thing):
766779 """Agents start in either location at random."""
767780 return random .choice ([loc_A , loc_B ])
768781
782+
769783# ______________________________________________________________________________
770784# The Wumpus World
771785
@@ -775,6 +789,7 @@ class Gold(Thing):
775789 def __eq__ (self , rhs ):
776790 """All Gold are equal"""
777791 return rhs .__class__ == Gold
792+
778793 pass
779794
780795
@@ -824,6 +839,7 @@ def can_grab(self, thing):
824839
825840class WumpusEnvironment (XYEnvironment ):
826841 pit_probability = 0.2 # Probability to spawn a pit in a location. (From Chapter 7.2)
842+
827843 # Room should be 4x4 grid of rooms. The extra 2 for walls
828844
829845 def __init__ (self , agent_program , width = 6 , height = 6 ):
@@ -901,12 +917,9 @@ def percept(self, agent):
901917 """Return things in adjacent (not diagonal) cells of the agent.
902918 Result format: [Left, Right, Up, Down, Center / Current location]"""
903919 x , y = agent .location
904- result = []
905- result .append (self .percepts_from (agent , (x - 1 , y )))
906- result .append (self .percepts_from (agent , (x + 1 , y )))
907- result .append (self .percepts_from (agent , (x , y - 1 )))
908- result .append (self .percepts_from (agent , (x , y + 1 )))
909- result .append (self .percepts_from (agent , (x , y )))
920+ result = [self .percepts_from (agent , (x - 1 , y )), self .percepts_from (agent , (x + 1 , y )),
921+ self .percepts_from (agent , (x , y - 1 )), self .percepts_from (agent , (x , y + 1 )),
922+ self .percepts_from (agent , (x , y ))]
910923
911924 """The wumpus gives out a loud scream once it's killed."""
912925 wumpus = [thing for thing in self .things if isinstance (thing , Wumpus )]
@@ -949,7 +962,7 @@ def execute_action(self, agent, action):
949962 """The arrow travels straight down the path the agent is facing"""
950963 if agent .has_arrow :
951964 arrow_travel = agent .direction .move_forward (agent .location )
952- while ( self .is_inbounds (arrow_travel ) ):
965+ while self .is_inbounds (arrow_travel ):
953966 wumpus = [thing for thing in self .list_things_at (arrow_travel )
954967 if isinstance (thing , Wumpus )]
955968 if len (wumpus ):
@@ -979,12 +992,13 @@ def is_done(self):
979992 print ("Death by {} [-1000]." .format (explorer [0 ].killed_by ))
980993 else :
981994 print ("Explorer climbed out {}."
982- .format (
983- "with Gold [+1000]!" if Gold () not in self .things else "without Gold [+0]" ))
995+ .format (
996+ "with Gold [+1000]!" if Gold () not in self .things else "without Gold [+0]" ))
984997 return True
985998
986-
987999 # TODO: Arrow needs to be implemented
1000+
1001+
9881002# ______________________________________________________________________________
9891003
9901004
@@ -1016,13 +1030,16 @@ def test_agent(AgentFactory, steps, envs):
10161030 >>> result == 5
10171031 True
10181032 """
1033+
10191034 def score (env ):
10201035 agent = AgentFactory ()
10211036 env .add_thing (agent )
10221037 env .run (steps )
10231038 return agent .performance
1039+
10241040 return mean (map (score , envs ))
10251041
1042+
10261043# _________________________________________________________________________
10271044
10281045
0 commit comments