Skip to content

Commit 612bb0a

Browse files
spottedMetalspottedMetal
authored andcommitted
Defined a make_agent_program method for the Agent classes,
for more uniform initialization of Agents. Improved GUI with commands to list objects and agents. Fixed GUI speed control (delay slider), narrowed the range and increased the resolution. Added three new image files and image credits file. Better image for dirt
1 parent ac7af96 commit 612bb0a

7 files changed

Lines changed: 143 additions & 29 deletions

File tree

agents.py

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,16 @@ class Agent (Object):
7676
the performance measure of the agent in its environment."""
7777

7878
def __init__(self):
79-
def program(percept):
80-
return raw_input('Percept=%s; action? ' % percept)
81-
self.program = program
79+
self.program = self.make_agent_program()
8280
self.alive = True
8381
self.bump = False
8482

83+
def make_agent_program (self):
84+
85+
def program(percept):
86+
return raw_input('Percept=%s; action? ' % percept)
87+
return program
88+
8589
def can_grab (self, obj):
8690
"""Returns True if this agent can grab this object.
8791
Override for appropriate subclasses of Agent and Object."""
@@ -109,21 +113,29 @@ def __init__(self, table):
109113
"Supply as table a dictionary of all {percept_sequence:action} pairs."
110114
## The agent program could in principle be a function, but because
111115
## it needs to store state, we make it a callable instance of a class.
116+
self.table = table
112117
super(TableDrivenAgent, self).__init__()
118+
119+
def make_agent_program (self):
120+
table = self.table
113121
percepts = []
114122
def program(percept):
115123
percepts.append(percept)
116124
action = table.get(tuple(percepts))
117125
return action
118-
self.program = program
126+
return program
119127

120128

121129
class RandomAgent (Agent):
122130
"An agent that chooses an action at random, ignoring all percepts."
123131

124132
def __init__(self, actions):
133+
self.actions = actions
125134
super(RandomAgent, self).__init__()
126-
self.program = lambda percept: random.choice(actions)
135+
136+
def make_agent_program (self):
137+
actions = self.actions
138+
return lambda percept: random.choice(actions)
127139

128140

129141
#______________________________________________________________________________
@@ -135,11 +147,13 @@ class ReflexVacuumAgent (Agent):
135147

136148
def __init__(self):
137149
super(ReflexVacuumAgent, self).__init__()
150+
151+
def make_agent_program (self):
138152
def program((location, status)):
139153
if status == 'Dirty': return 'Suck'
140154
elif location == loc_A: return 'Right'
141155
elif location == loc_B: return 'Left'
142-
self.program = program
156+
return program
143157

144158
def get_image_file (self): return "images/vacuum.png"
145159

@@ -168,16 +182,19 @@ class ModelBasedVacuumAgent (Agent):
168182
"An agent that keeps track of what locations are clean or dirty."
169183

170184
def __init__(self):
185+
self.model = {loc_A: None, loc_B: None}
171186
super(ModelBasedVacuumAgent, self).__init__()
172-
model = {loc_A: None, loc_B: None}
187+
188+
def make_agent_program (self):
189+
model = self.model
173190
def program((location, status)):
174191
"Same as ReflexVacuumAgent, except if everything is clean, do NoOp"
175192
model[location] = status ## Update the model here
176193
if model[loc_A] == model[loc_B] == 'Clean': return 'NoOp'
177194
elif status == 'Dirty': return 'Suck'
178195
elif location == loc_A: return 'Right'
179196
elif location == loc_B: return 'Left'
180-
self.program = program
197+
return program
181198

182199
#______________________________________________________________________________
183200

@@ -388,14 +405,18 @@ class Obstacle (Object):
388405
moving into the same square it's in."""
389406
pass
390407

391-
class Wall (Obstacle): pass
408+
class Wall (Obstacle):
409+
410+
def get_image_file (self):
411+
return "images/wall-icon.jpg"
392412

393413
#______________________________________________________________________________
394414
## Vacuum environment
395415

396416
class Dirt (Object):
397417

398-
def get_image_file (self): return "images/dirt.png"
418+
def get_image_file (self):
419+
return "images/dirt05-icon.jpg" # "images/dirt.png"
399420

400421
class VacuumEnvironment (XYEnvironment):
401422
"""The environment of [Ex. 2.12]. Agent perceives dirty or clean,
@@ -476,26 +497,39 @@ class SimpleReflexAgent (Agent):
476497
"""This agent takes action based solely on the percept. [Fig. 2.13]"""
477498

478499
def __init__(self, rules, interpret_input):
500+
self.rules = rules
501+
self.interpret_input = interpret_input
479502
super(SimpleReflexAgent, self).__init__()
503+
504+
def make_agent_program (self):
505+
rules = self.rules
506+
interpret_input = self.interpret_input
480507
def program(percept):
481508
state = interpret_input(percept)
482509
rule = rule_match(state, rules)
483510
action = rule.action
484511
return action
485-
self.program = program
512+
return program
486513

487514
class ReflexAgentWithState (Agent):
488515
"""This agent takes action based on the percept and state. [Fig. 2.16]"""
489516

490517
def __init__(self, rules, udpate_state):
518+
self.rules = rules
519+
self.update_state = update_state
491520
super(ReflexAgentWithState, self).__init__()
492-
state, action = None, None
521+
522+
def make_agent_program (self):
523+
rules = self.rules
524+
update_state = self.update_state
525+
state = None
526+
action = None
493527
def program(percept):
494528
state = update_state(state, action, percept)
495529
rule = rule_match(state, rules)
496530
action = rule.action
497531
return action
498-
self.program = program
532+
return program
499533

500534
#______________________________________________________________________________
501535
## The Wumpus World
@@ -608,11 +642,14 @@ def __init__ (self, parent, env, canvas):
608642
# Create buttons and other controls
609643

610644
for txt, cmd in [('Step >', self.env.step), ('Run >>', self.run),
611-
('Stop [ ]', self.stop)]:
645+
('Stop [ ]', self.stop),
646+
('List objects', self.list_objects),
647+
('List agents', self.list_agents)]:
612648
tk.Button(self, text=txt, command=cmd).pack(side='left')
613649
tk.Label(self, text='Delay').pack(side='left')
614-
scale = tk.Scale(self, orient='h', from_=0.0, to=10, resolution=0.5,
615-
command=lambda d: setattr(parent, 'delay', d))
650+
res = 0.1
651+
scale = tk.Scale(self, orient='h', from_=(0.0 + res), to=5, resolution=res,
652+
command=self.set_delay)
616653
scale.set(self.delay)
617654
scale.pack(side='left')
618655

@@ -628,10 +665,23 @@ def stop(self):
628665
def background_run(self):
629666
if self.running:
630667
self.env.step()
631-
ms = int(1000 * max(float(self.delay), 0.5))
668+
# ms = int(1000 * max(float(self.delay), 0.5))
669+
ms = max(int(1000 * float(self.delay)), 1)
632670
self.after(ms, self.background_run)
633671

634-
672+
def list_objects (self):
673+
print "Objects in the environment:"
674+
for obj in self.env.objects:
675+
print "%s at %s" % (obj, obj.location)
676+
677+
def list_agents (self):
678+
print "Agents in the environment:"
679+
for agt in self.env.agents:
680+
print "%s at %s" % (agt, agt.location)
681+
682+
def set_delay (self, delay):
683+
self.delay = delay
684+
635685
class EnvCanvas (tk.Canvas, object):
636686

637687
def __init__ (self, parent, env, cellwidth, n):

images/IMAGE-CREDITS

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
PHOTO CREDITS
2+
3+
Image After http://www.imageafter.com/
4+
5+
b15woods003.jpg
6+
(Cropped to 764x764 and scaled to 50x50 to make wall-icon.jpg
7+
by Gregory Weber)
8+
9+
Noctua Graphics, http://www.noctua-graphics.de/english/fraset_e.htm
10+
11+
dirt05.jpg 512x512
12+
(Scaled to 50x50 to make dirt05-icon.jpg by Gregory Weber)
13+
14+
Gregory Weber
15+
16+
dirt.svg, dirt.png
17+
vacuum.svg, vacuum.png

images/dirt05-icon.jpg

1.73 KB
Loading

images/makefile

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ Sources = dirt.svg vacuum.svg
44

55
Targets = $(Sources:.svg=.png)
66

7-
%.png: %.svg
8-
convert $< $@
7+
ImageScale = 50x50
8+
9+
Temporary = tmp.jpg
910

1011
.PHONY: all
1112

@@ -14,4 +15,20 @@ all: $(Targets)
1415
.PHONY: clean
1516

1617
clean:
17-
rm -f $(Targets)
18+
rm -f $(Targets) $(Temporary)
19+
20+
%.png: %.svg
21+
convert -scale $(ImageScale) $< $@
22+
23+
%-icon.jpg: %.svg
24+
convert -scale $(ImageScale) $< $@
25+
26+
%-icon.jpg: %.jpg
27+
convert -scale $(ImageScale) $< $@
28+
29+
wall-icon.jpg: b15woods003.jpg
30+
convert -crop 764x764+0+0 $< tmp.jpg
31+
convert -resize 50x50+0+0 tmp.jpg $@
32+
33+
vacuum-icon.jpg: vacuum.svg
34+
convert -scale $(ImageScale) -transparent white $< $@

images/vacuum-icon.jpg

1.39 KB
Loading

images/vacuum.svg

Lines changed: 38 additions & 8 deletions
Loading

images/wall-icon.jpg

35.1 KB
Loading

0 commit comments

Comments
 (0)