Newer
Older
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# AGENT #\n",
"\n",
"An agent, as defined in 2.1 is anything that can perceive its <b>environment</b> through sensors, and act upon that environment through actuators based on its <b>agent program</b>. This can be a dog, robot, or even you. As long as you can perceive the environment and act on it, you are an agent. This notebook will explain how to implement a simple agent, create an environment, and create a program that helps the agent act on the environment based on its percepts.\n",
"\n",
"Before moving on, review the <b>Agent</b> and <b>Environment</b> classes in [<b>agents.py</b>](https://github.com/aimacode/aima-python/blob/master/agents.py).\n",
"\n",
"Let's begin by importing all the functions from the agents.py module and creating our first agent - a blind dog."
]
},
"execution_count": 1,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [],
"source": [
"from agents import *\n",
"\n",
"class BlindDog(Agent):\n",
" def eat(self, thing):\n",
" print(\"Dog: Ate food at {}.\".format(self.location))\n",
" \n",
" def drink(self, thing):\n",
" print(\"Dog: Drank water at {}.\".format( self.location))\n",
"\n",
"dog = BlindDog()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"What we have just done is create a dog who can only feel what's in his location (since he's blind), and can eat or drink. Let's see if he's alive..."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
}
],
"source": [
"print(dog.alive)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"This is our dog. How cool is he? Well, he's hungry and needs to go search for food. For him to do this, we need to give him a program. But before that, let's create a park for our dog to play in."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ENVIRONMENT #\n",
"\n",
"A park is an example of an environment because our dog can perceive and act upon it. The <b>Environment</b> class in agents.py is an abstract class, so we will have to create our own subclass from it before we can use it. The abstract class must contain the following methods:\n",
"\n",
"<li><b>percept(self, agent)</b> - returns what the agent perceives</li>\n",
"<li><b>execute_action(self, agent, action)</b> - changes the state of the environment based on what the agent does.</li>"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Food(Thing):\n",
" pass\n",
"\n",
"class Water(Thing):\n",
" pass\n",
"\n",
"class Park(Environment):\n",
" def percept(self, agent):\n",
" '''prints & return a list of things that are in our agent's location'''\n",
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
" things = self.list_things_at(agent.location)\n",
" print(things)\n",
" return things\n",
" \n",
" def execute_action(self, agent, action):\n",
" '''changes the state of the environment based on what the agent does.'''\n",
" if action == \"move down\":\n",
" agent.movedown()\n",
" elif action == \"eat\":\n",
" items = self.list_things_at(agent.location, tclass=Food)\n",
" if len(items) != 0:\n",
" if agent.eat(items[0]): #Have the dog pick eat the first item\n",
" self.delete_thing(items[0]) #Delete it from the Park after.\n",
" elif action == \"drink\":\n",
" items = self.list_things_at(agent.location, tclass=Water)\n",
" if len(items) != 0:\n",
" if agent.drink(items[0]): #Have the dog drink the first item\n",
" self.delete_thing(items[0]) #Delete it from the Park after.\n",
" \n",
" def is_done(self):\n",
" '''By default, we're done when we can't find a live agent, \n",
" but to prevent killing our cute dog, we will or it with when there is no more food or water'''\n",
" no_edibles = not any(isinstance(thing, Food) or isinstance(thing, Water) for thing in self.things)\n",
" dead_agents = not any(agent.is_alive() for agent in self.agents)\n",
" return dead_agents or no_edibles\n"
]
},
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Wumpus Environment"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"from ipythonblocks import BlockGrid\n",
"from agents import *\n",
"\n",
"color = {\"Breeze\": (225, 225, 225),\n",
" \"Pit\": (0,0,0),\n",
" \"Gold\": (253, 208, 23),\n",
" \"Glitter\": (253, 208, 23),\n",
" \"Wumpus\": (43, 27, 23),\n",
" \"Stench\": (128, 128, 128),\n",
" \"Explorer\": (0, 0, 255),\n",
" \"Wall\": (44, 53, 57)\n",
" }\n",
"\n",
"def program(percepts):\n",
" '''Returns an action based on it's percepts'''\n",
" print(percepts)\n",
" return input()\n",
"\n",
"w = WumpusEnvironment(program, 7, 7) \n",
"grid = BlockGrid(w.width, w.height, fill=(123, 234, 123))\n",
"\n",
"def draw_grid(world):\n",
" global grid\n",
" grid[:] = (123, 234, 123)\n",
" for x in range(0, len(world)):\n",
" for y in range(0, len(world[x])):\n",
" if len(world[x][y]):\n",
" grid[y, x] = color[world[x][y][-1].__class__.__name__]\n",
"\n",
"def step():\n",
" global grid, w\n",
" draw_grid(w.get_world())\n",
" grid.show()\n",
" w.step()"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"<style type=\"text/css\">table.blockgrid {border: none;} .blockgrid tr {border: none;} .blockgrid td {padding: 0px;} #blocksd29b49d9-0de7-4669-986f-6f9f11558b46 td {border: 1px solid white;}</style><table id=\"blocksd29b49d9-0de7-4669-986f-6f9f11558b46\" class=\"blockgrid\"><tbody><tr><td title=\"Index: [0, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [0, 1] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [0, 2] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [0, 3] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [0, 4] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [0, 5] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [0, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr><tr><td title=\"Index: [1, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [1, 1] Color: (0, 0, 255)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 255);\"></td><td title=\"Index: [1, 2] Color: (123, 234, 123)\" style=\"width: 20px; height: 20px;background-color: rgb(123, 234, 123);\"></td><td title=\"Index: [1, 3] Color: (128, 128, 128)\" style=\"width: 20px; height: 20px;background-color: rgb(128, 128, 128);\"></td><td title=\"Index: [1, 4] Color: (123, 234, 123)\" style=\"width: 20px; height: 20px;background-color: rgb(123, 234, 123);\"></td><td title=\"Index: [1, 5] Color: (123, 234, 123)\" style=\"width: 20px; height: 20px;background-color: rgb(123, 234, 123);\"></td><td title=\"Index: [1, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr><tr><td title=\"Index: [2, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [2, 1] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [2, 2] Color: (128, 128, 128)\" style=\"width: 20px; height: 20px;background-color: rgb(128, 128, 128);\"></td><td title=\"Index: [2, 3] Color: (43, 27, 23)\" style=\"width: 20px; height: 20px;background-color: rgb(43, 27, 23);\"></td><td title=\"Index: [2, 4] Color: (128, 128, 128)\" style=\"width: 20px; height: 20px;background-color: rgb(128, 128, 128);\"></td><td title=\"Index: [2, 5] Color: (123, 234, 123)\" style=\"width: 20px; height: 20px;background-color: rgb(123, 234, 123);\"></td><td title=\"Index: [2, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr><tr><td title=\"Index: [3, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [3, 1] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [3, 2] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [3, 3] Color: (128, 128, 128)\" style=\"width: 20px; height: 20px;background-color: rgb(128, 128, 128);\"></td><td title=\"Index: [3, 4] Color: (0, 0, 0)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 0);\"></td><td title=\"Index: [3, 5] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [3, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr><tr><td title=\"Index: [4, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [4, 1] Color: (0, 0, 0)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 0);\"></td><td title=\"Index: [4, 2] Color: (0, 0, 0)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 0);\"></td><td title=\"Index: [4, 3] Color: (0, 0, 0)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 0);\"></td><td title=\"Index: [4, 4] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [4, 5] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [4, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr><tr><td title=\"Index: [5, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [5, 1] Color: (0, 0, 0)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 0);\"></td><td title=\"Index: [5, 2] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [5, 3] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [5, 4] Color: (225, 225, 225)\" style=\"width: 20px; height: 20px;background-color: rgb(225, 225, 225);\"></td><td title=\"Index: [5, 5] Color: (0, 0, 0)\" style=\"width: 20px; height: 20px;background-color: rgb(0, 0, 0);\"></td><td title=\"Index: [5, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr><tr><td title=\"Index: [6, 0] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [6, 1] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [6, 2] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [6, 3] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [6, 4] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [6, 5] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td><td title=\"Index: [6, 6] Color: (44, 53, 57)\" style=\"width: 20px; height: 20px;background-color: rgb(44, 53, 57);\"></td></tr></tbody></table>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[<Bump>], [None], [<Bump>], [<Breeze>], [None]]\n",
"2\n"
]
}
],
"source": [
"step()"
]
},
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"# PROGRAM #\n",
"Now that we have a <b>Park</b> Class, we need to implement a <b>program</b> module for our dog. A program controls how the dog acts upon it's environment. Our program will be very simple, and is shown in the table below.\n",
"<table>\n",
" <tr>\n",
" <td><b>Percept:</b> </td>\n",
" <td>Feel Food </td>\n",
" <td>Feel Water</td>\n",
" <td>Feel Nothing</td>\n",
" </tr>\n",
" <tr>\n",
" <td><b>Action:</b> </td>\n",
" <td>eat</td>\n",
" <td>drink</td>\n",
" <td>move up</td>\n",
" </tr>\n",
" \n",
"</table>\n"
]
},
{
"cell_type": "code",
"metadata": {
"collapsed": false
},
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
"class BlindDog(Agent):\n",
" location = 1\n",
" \n",
" def movedown(self):\n",
" self.location += 1\n",
" \n",
" def eat(self, thing):\n",
" '''returns True upon success or False otherwise'''\n",
" if isinstance(thing, Food):\n",
" print(\"Dog: Ate food at {}.\".format(self.location))\n",
" return True\n",
" return False\n",
" \n",
" def drink(self, thing):\n",
" ''' returns True upon success or False otherwise'''\n",
" if isinstance(thing, Water):\n",
" print(\"Dog: Drank water at {}.\".format(self.location))\n",
" return True\n",
" return False\n",
" \n",
"def program(percepts):\n",
" '''Returns an action based on it's percepts'''\n",
" for p in percepts:\n",
" if isinstance(p, Food):\n",
" return 'eat'\n",
" elif isinstance(p, Water):\n",
" return 'drink'\n",
" return 'move down'\n",
" \n",
" "
]
},
{
"cell_type": "code",
"source": [
"park = Park()\n",
"dog = BlindDog(program)\n",
"dogfood = Food()\n",
"water = Water()\n",
"park.add_thing(dog, 0)\n",
"park.add_thing(dogfood, 5)\n",
"park.add_thing(water, 7)\n",
"\n",
"park.run(10)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"That's how easy it is to implement an agent, its program, and environment. But that was a very simple case. What if our environment was 2-Dimentional instead of 1? And what if we had multiple agents?\n",
"\n",
"To make our Park 2D, we will need to make it a subclass of <b>XYEnvironment</b> instead of Environment. Also, let's add a person to play fetch with the dog."
"metadata": {
"collapsed": true
},
"outputs": [],
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
"source": [
"class Park(XYEnvironment):\n",
" def percept(self, agent):\n",
" '''prints & return a list of things that are in our agent's location'''\n",
" things = self.list_things_at(agent.location)\n",
" print(things)\n",
" return things\n",
" \n",
" def execute_action(self, agent, action):\n",
" '''changes the state of the environment based on what the agent does.'''\n",
" if action == \"move down\":\n",
" agent.movedown()\n",
" elif action == \"eat\":\n",
" items = self.list_things_at(agent.location, tclass=Food)\n",
" if len(items) != 0:\n",
" if agent.eat(items[0]): #Have the dog pick eat the first item\n",
" self.delete_thing(items[0]) #Delete it from the Park after.\n",
" elif action == \"drink\":\n",
" items = self.list_things_at(agent.location, tclass=Water)\n",
" if len(items) != 0:\n",
" if agent.drink(items[0]): #Have the dog drink the first item\n",
" self.delete_thing(items[0]) #Delete it from the Park after.\n",
" \n",
" def is_done(self):\n",
" '''By default, we're done when we can't find a live agent, \n",
" but to prevent killing our cute dog, we will or it with when there is no more food or water'''\n",
" no_edibles = not any(isinstance(thing, Food) or isinstance(thing, Water) for thing in self.things)\n",
" dead_agents = not any(agent.is_alive() for agent in self.agents)\n",
" return dead_agents or no_edibles"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}