;ò iìÈ?c@s~dZdkTdkZdkZdfd„ƒYZdefd„ƒYZd„Zdefd „ƒYZd efd „ƒYZd d fd d ff\Z Z defd„ƒYZ d„Z d„Z defd„ƒYZdfd„ƒYZdefd„ƒYZd d fd d fdd fd dfgd„Zdefd„ƒYZdefd„ƒYZdefd„ƒYZd efd!„ƒYZd"efd#„ƒYZd$efd%„ƒYZd&efd'„ƒYZd(efd)„ƒYZd*efd+„ƒYZd,efd-„ƒYZd.efd/„ƒYZd0efd1„ƒYZd2d3d4„Zd5„Zd6Z dk!Z"d7e"i#fd8„ƒYZ$dS(9sÉImplement Agents and Environments (Chapters 1-2). The class hierarchies are as follows: Object ## A physical object that can exist in an environment Agent Wumpus RandomAgent ReflexVacuumAgent ... Dirt Wall ... Environment ## An environment holds objects, runs simulations XYEnvironment VacuumEnvironment WumpusEnvironment EnvFrame ## A graphical representation of the Environment (s*NsObjectcBs)tZdZd„Zd„Zd„ZRS(s¿This represents any physical object that can appear in an Environment. You subclass Object to get the objects you want. Each object can have a .__name__ slot (used for output only).cCsdt|d|iiƒSdS(Ns<%s>s__name__(sgetattrsselfs __class__s__name__(sself((s agents.pys__repr__!scCst|dƒo|iSdS(s,Objects that are 'alive' should return true.saliveN(shasattrsselfsalive(sself((s agents.pysis_alive$scCsdS(s.Display an image of this Object on the canvas.N((sselfscanvassxsyswidthsheight((s agents.pysdisplay(s(s__name__s __module__s__doc__s__repr__sis_alivesdisplay(((s agents.pysObjects   sAgentcBstZdZd„ZRS(sñAn Agent is a subclass of Object with one required slot, .program, which should hold a function that takes one argument, the percept, and returns an action. (What counts as a percept or action will depend on the specific environment in which the agent exists.) Note that 'program' is a slot, not a method. If it were a method, then the program could 'cheat' and look at aspects of the agent. It's not supposed to do that: the program can only look at the percepts. An agent program that needs a model of the world (and of the agent itself) will have to build and maintain its own model. There is an optional slots, .performance, which is a number giving the performance measure of the agent in its environment.cCsd„}||_t|_dS(NcCstd|ƒSdS(NsPercept=%s; action? (s raw_inputspercept(spercept((s agents.pysprogram:s(sprogramsselfsTruesalive(sselfsprogram((s agents.pys__init__9s  (s__name__s __module__s__doc__s__init__(((s agents.pysAgent,s cs)ˆi‰‡‡d†}|ˆ_ˆSdS(s}Wrap the agent's program to print its input and output. This will let you see what the agent is doing in the environment.cs&ˆ|ƒ}dˆ||fGH|SdS(Ns%s perceives %s and does %s(s old_programsperceptsactionsagent(sperceptsaction(s old_programsagent(s agents.pys new_programCs N(sagentsprograms old_programs new_program(sagents old_programs new_program((sagents old_programs agents.pys TraceAgent?s   sTableDrivenAgentcBstZdZd„ZRS(s­This agent selects an action based on the percept sequence. It is practical only for tiny domains. To customize it you provide a table to the constructor. [Fig. 2.7]cs/ti|ƒg‰‡‡d†}||_dS(sDSupply as table a dictionary of all {percept_sequence:action} pairs.cs*ˆi|ƒˆitˆƒƒ}|SdS(N(sperceptssappendsperceptstablesgetstuplesaction(sperceptsaction(stablespercepts(s agents.pysprogramWs N(sAgents__init__sselfsperceptssprogram(sselfstablesprogramspercepts((stablesperceptss agents.pys__init__Qs  (s__name__s __module__s__doc__s__init__(((s agents.pysTableDrivenAgentLs s RandomAgentcBstZdZd„ZRS(sAAn agent that chooses an action at random, ignoring all percepts.cs ti|ƒ‡d†|_dS(Ncs tiˆƒS(N(srandomschoicesactions(spercept(sactions(s agents.pysbs(sAgents__init__sselfsprogram(sselfsactions((sactionss agents.pys__init__`s (s__name__s __module__s__doc__s__init__(((s agents.pys RandomAgent^s iisReflexVacuumAgentcBstZdZd„ZRS(s?A reflex agent for the two-state vacuum environment. [Fig. 2.8]cCs#ti|ƒd„}||_dS(NcCsO|\}}|djodSn+|tjodSn|tjodSndS(NsDirtysSucksRightsLeft(slocationsstatussloc_Asloc_B(s.0slocationsstatus((s agents.pysprogramns    (sAgents__init__sselfsprogram(sselfsprogram((s agents.pys__init__ls  (s__name__s __module__s__doc__s__init__(((s agents.pysReflexVacuumAgentis cCstddddgƒSdS(s?Randomly choose one of the actions from the vaccum environment.sRightsLeftsSucksNoOpN(s RandomAgent(((s agents.pysRandomVacuumAgentuscCsÚhtdffd<tdffd<tdffd<tdffd<tdftdffd<tdftdffd<tdftdftdffd<tdftdftdffd<}t|ƒSdS(s [Fig. 2.3]sCleansRightsDirtysSucksLeftN(sloc_Asloc_BstablesTableDrivenAgent(stable((s agents.pysTableDrivenVacuumAgentzsÌ sModelBasedVacuumAgentcBstZdZd„ZRS(s?An agent that keeps track of what locations are clean or dirty.cs>ti|ƒhtt<tt<‰‡d†}||_dS(Ncs‡|\}}|ˆ|<ˆtˆtjo djnodSn@|djodSn+|tjodSn|tjodSndS(sASame as ReflexVacuumAgent, except if everything is clean, do NoOpsCleansNoOpsDirtysSucksRightsLeftN(slocationsstatussmodelsloc_Asloc_B(s.0slocationsstatus(smodel(s agents.pysprograms  &   (sAgents__init__sselfsloc_AsNonesloc_Bsmodelsprogram(sselfsprogramsmodel((smodels agents.pys__init__Œs  (s__name__s __module__s__doc__s__init__(((s agents.pysModelBasedVacuumAgentŠs s EnvironmentcBsktZdZd„ZgZd„Zd„Zd„Zd„Zd„Z d„Z dd „Z e d „Z RS( sKAbstract class representing an Environment. 'Real' Environment classes inherit from this. Your Environment will typically need to implement: percept: Define the percept that an agent sees. execute_action: Define the effects of executing an action. Also update the agent.performance slot. The environment keeps a list of .objects and .agents (which is a subset of .objects). Each agent has a .performance slot, initialized to 0. Each object has a .location slot, even though some environments may not need this.cCsg|_g|_dS(N(sselfsobjectssagents(sself((s agents.pys__init__¥scCs tƒdS(sDReturn the percept that the agent sees at this point. Override this.N(sabstract(sselfsagent((s agents.pysperceptªscCs tƒdS(s7Change the world to reflect this action. Override this.N(sabstract(sselfsagentsaction((s agents.pysexecute_action®scCstSdS(sADefault location to place a new object with unspecified location.N(sNone(sselfsobject((s agents.pysdefault_location²scCsdS(s;If there is spontaneous change in the world, override this.N((sself((s agents.pysexogenous_change¶scCs1x&|iD]}|iƒotSq q WtSdS(s7By default, we're done when we can't find a live agent.N(sselfsagentssagentsis_alivesFalsesTrue(sselfsagent((s agents.pysis_doneºs   cCs|iƒ o}gi}|iD]"}||i|i|ƒƒƒq~}x0t |i|ƒD]\}}|i ||ƒq]W|i ƒndS(sÂRun the environment for one time step. If the actions and exogenous changes are independent, this method will do. If there are interactions between them, you'll need to override this method.N( sselfsis_donesappends_[1]sagentssagentsprogramsperceptsactionsszipsactionsexecute_actionsexogenous_change(sselfsagents_[1]sactionssaction((s agents.pysstepÀs< iècCs:x3t|ƒD]%}|iƒodSn|iƒq WdS(s3Run the Environment for given number of time steps.N(srangesstepssstepsselfsis_done(sselfsstepssstep((s agents.pysrunÌs   cCs^|p |i|ƒ|_|ii|ƒt|tƒod|_|i i|ƒn|SdS(s†Add an object to the environment, setting its location. Also keep track of objects that are agents. Shouldn't need to override this.iN( slocationsselfsdefault_locationsobjectsobjectssappends isinstancesAgents performancesagents(sselfsobjectslocation((s agents.pys add_objectÒs (s__name__s __module__s__doc__s__init__sobject_classessperceptsexecute_actionsdefault_locationsexogenous_changesis_donesstepsrunsNones add_object(((s agents.pys Environmentšs        s XYEnvironmentcBswtZdZddd„Zd„Zd„Zd„Zd„Zd„Zd„Z d „Z d d fd „Z d „Z RS( sYThis class is for environments on a 2D plane, with locations labelled by (x, y) points, either discrete or continuous. Agents perceive objects within a radius. Each agent in the environment has a .location slot which should be a location such as (0, 1), and a .holding slot, which should be a list of objects that are held i c Cs&t|dgdgd|d|ƒdS(Nsobjectssagentsswidthsheight(supdatesselfswidthsheight(sselfswidthsheight((s agents.pys__init__åscCs@gi}|iD]$}|i|jo||ƒqq~SdS(s/Return all objects exactly at a given location.N(sappends_[1]sselfsobjectssobjslocation(sselfslocations_[1]sobj((s agents.pys objects_atèscCsS||}gi}|iD]-}t||iƒ|jo||ƒqq~SdS(s-Return all objects within radius of location.N( sradiussradius2sappends_[1]sselfsobjectssobjs distance2slocation(sselfslocationsradiussradius2sobjs_[1]((s agents.pys objects_nearìs cCs>gi}|i|ƒD]}||i||ƒƒq~SdS(s4By default, agent perceives objects within radius r.N(sappends_[1]sselfs objects_nearsagentsobjsobject_percept(sselfsagents_[1]sobj((s agents.pysperceptòscCs,|djot|idƒ|_nú|djot|idƒ|_nÔ|djo#|i|t|i|iƒƒn¤|djojgi}|i |iƒD]$}|i |ƒo||ƒq£q£~}|o|ii|dƒqn-|djo|io|iiƒqnt|_dS( Ns TurnRightiÿÿÿÿsTurnLeftisForwardsGrabisRelease(sactions turn_headingsagentsheadingsselfsmove_tos vector_addslocationsappends_[1]s objects_atsobjs is_grabablesobjssholdingspopsFalsesbump(sselfsagentsactionsobjssobjs_[1]((s agents.pysexecute_action÷s   # G  cCs|iiSdS(s#Return the percept for this object.N(sobjs __class__s__name__(sselfsobjsagent((s agents.pysobject_perceptscCs&ti|iƒti|iƒfSdS(N(srandomschoicesselfswidthsheight(sselfsobject((s agents.pysdefault_location scCsdS(s!Move an object to a new location.N((sobjects destination((s agents.pysmove_tosicCs9ti|||ƒg|_t|_|ii |ƒdS(N( s Environments add_objectsselfsobjectslocationsholdingsNonesheldsobjectssappend(sselfsobjectslocation((s agents.pys add_objects  cCsªxPt|iƒD]?}|itƒ|dfƒ|itƒ||idfƒqWxPt|iƒD]?}|itƒd|fƒ|itƒ|id|fƒqcWdS(s2Put walls around the entire perimeter of the grid.iiN(srangesselfswidthsxs add_objectsWallsheightsy(sselfsxsy((s agents.pys add_wallss$( s__name__s __module__s__doc__s__init__s objects_ats objects_nearsperceptsexecute_actionsobject_perceptsdefault_locationsmove_tos add_objects add_walls(((s agents.pys XYEnvironmentÝs        iÿÿÿÿcCs#||i|ƒ|t|ƒSdS(sFReturn the heading to the left (inc=+1) or right (inc=-1) in headings.N(sheadingssindexsheadingsincslen(sselfsheadingsincsheadings((s agents.pys turn_heading!ssTrivialVacuumEnvironmentcBs2tZdZd„Zd„Zd„Zd„ZRS(sÐThis environment has two locations, A and B. Each can be Dirty or Clean. The agent perceives its location and the location's status. This serves as an example of how to implement a simple Environment.cCsJti|ƒhttiddgƒ<ttiddgƒ<|_dS(NsCleansDirty(s Environments__init__sselfsloc_Asrandomschoicesloc_Bsstatus(sself((s agents.pys__init__.s cCs|i|i|ifSdS(sDReturns the agent's location, and the location status (Dirty/Clean).N(sagentslocationsselfsstatus(sselfsagent((s agents.pyspercept3scCs¡|djot|_|id8_nu|djot|_|id8_nL|djo>|i|idjo|id7_nd|i|i~SdS(s*See how well each of several agents do in n instances of an environment. Pass in a factory (constructor) for environments, and several for agents. Create n instances of the environment, and run each agent in copies of each one for steps. Return a list of (agent, average-score) tuples.N( sappends_[1]srangesnsis EnvFactorysenvssAgentFactoriessAs test_agentsstepsscopysdeepcopy(s EnvFactorysAgentFactoriessnsstepssAsenvss_[1]si((s agents.pyscompare_agents”s0cCs_d}x>|D]6}|ƒ}|i|ƒ|i|ƒ||i7}q Wt |ƒt |ƒSdS(sHReturn the mean score of running an agent in each of the envs, for stepsiN( stotalsenvssenvs AgentFactorysagents add_objectsrunsstepss performancesfloatslen(s AgentFactorysstepssenvssagentsenvstotal((s agents.pys test_agents   s  a = ReflexVacuumAgent() a.program a.program((loc_A, 'Clean')) ==> 'Right' a.program((loc_B, 'Clean')) ==> 'Left' a.program((loc_A, 'Dirty')) ==> 'Suck' a.program((loc_A, 'Dirty')) ==> 'Suck' e = TrivialVacuumEnvironment() e.add_object(TraceAgent(ModelBasedVacuumAgent())) e.run(5) ## Environments, and some agents, are randomized, so the best we can ## give is a range of expected scores. If this test fails, it does ## not necessarily mean something is wrong. envs = [TrivialVacuumEnvironment() for i in range(100)] def testv(A): return test_agent(A, 4, copy.deepcopy(envs)) testv(ModelBasedVacuumAgent) (7 < _ < 11) ==> True testv(ReflexVacuumAgent) (5 < _ < 9) ==> True testv(TableDrivenVacuumAgent) (2 < _ < 6) ==> True testv(RandomVacuumAgent) (0.5 < _ < 3) ==> True sEnvFramecBsPtZdddd„Zd„Zd„Zd„Zd„Zd „Zd „ZRS( NsAIMA GUIi2i c s…tˆd|dtddƒ|ˆ_dˆ_dˆ_|ˆ_ti i ˆt d|d|d|d|ƒti ˆd d d dƒ} | i d d ddƒx`dˆiifdˆifdˆifgD]1\} }ti| d| d|ƒi d dƒqÎWti| ddƒi d dƒti| ddddddddd‡d†ƒ}|iˆiƒ|i d dƒtiˆd|d |d|d |d!d"ƒˆ_ˆiid#ˆiƒˆiid$ˆiƒˆiid%ˆiƒ|o…ˆi}xytd |d ƒD]`}|i!d||||||ƒ|i!||d||||ƒ|i d&d dd'ƒqWnˆi ƒdS((Ns cellwidthsrunningsdelayf1.0iswidthisheightsreliefsraisedsbdssidestopsfillsxsStep >sRun >>sStop [ ]stextscommandsleftsDelaysorientshsfrom_f0.0stoi s resolutionf0.5cstˆd|ƒS(Nsdelay(ssetattrsselfsd(sd(sself(s agents.pysÝsis backgroundswhites s s sexpandsboth("supdatesselfs cellwidthsFalsesnsrunningsdelaysenvstksFrames__init__sNonestoolbarspacksstepsrunsstopstxtscmdsButtonsLabelsScalesscalessetsCanvasscanvassbindslefts edit_objectss add_objectscsrangesis create_line( sselfsenvstitles cellwidthsnsscalesiscscmdstxtstoolbar((sselfs agents.pys__init__Ís:    /. )! ""cCsT|ioF|iiƒtdtt|iƒdƒƒ}|i ||i ƒndS(Nièf0.5( sselfsrunningsenvsstepsintsmaxsfloatsdelaysmssaftersbackground_run(sselfsms((s agents.pysbackground_runïs  "cCsdGHd|_|iƒdS(Nsruni(sselfsrunningsbackground_run(sself((s agents.pysrunõs cCsdGHd|_dS(Nsstopi(sselfsrunning(sself((s agents.pysstopúscCsdG|idG|idGHdS(Nsleft at i2(seventsxsy(sselfsevent((s agents.pysleftþscCsdS(s3Choose an object within radius and edit its fields.N((sselfsevent((s agents.pys edit_objectsscCs ti|dd|id|idfƒ}xBd|ifd|ifgD]"\}}|i d|d|ƒqLW|i |i|i ƒ|i|i ƒƒdS(Nstitles Edit (%d, %d)i2sWumpussPitslabelscommand(stksMenusselfseventsxsysmenusrunstxtscmds add_commandstk_popups winfo_rootxs winfo_rooty(sselfseventsmenuscmdstxt((s agents.pys add_objects - ( s__name__s __module__s__init__sbackground_runsrunsstopslefts edit_objectss add_object(((s agents.pysEnvFrameÌs"     (%s__doc__sutilssrandomscopysObjectsAgents TraceAgentsTableDrivenAgents RandomAgentsloc_Asloc_BsReflexVacuumAgentsRandomVacuumAgentsTableDrivenVacuumAgentsModelBasedVacuumAgents Environments XYEnvironments turn_headingsTrivialVacuumEnvironmentsDirtsWallsVacuumEnvironmentsSimpleReflexAgentsReflexAgentWithStatesGoldsPitsArrowsWumpussExplorersWumpusEnvironmentscompare_agentss test_agents_docexsTkinterstksFramesEnvFrame(!sTableDrivenVacuumAgents TraceAgentsrandoms EnvironmentsTableDrivenAgentsModelBasedVacuumAgentsExplorersDirtsObjectsloc_Bsloc_Astks turn_headingsReflexAgentWithStates XYEnvironments RandomAgentsTrivialVacuumEnvironments test_agentsVacuumEnvironments_docexsRandomVacuumAgentsEnvFramesWumpussArrowsSimpleReflexAgentscopysGoldsWallscompare_agentssAgentsWumpusEnvironmentsPitsReflexVacuumAgent((s agents.pys?s@    CD0    !