Assignment 4: Artificial Agents
Contents
Assignment 4: Artificial Agents¶
This is a demo assignment that is available as part of the Introductory Python open materials.
Overview¶
This assignment covers Classes & Objects, and builds up to the application of Artificial Agents.
This assignment is out of 8 points, worth 8% of your grade.
Make sure your completed assignment passes all the asserts. This assignment also has some hidden tests - which means that passing all the asserts you see does not guarantee that you have the correct answer! Make sure to double check and re-run your code to make sure it does what you expect.
Setup¶
Code Imports¶
You must run the following cell before proceeding with the assignment.
# Setup - run this cell before doing the next part of the assignment
# This cell imports some extra code, making it available for us to use later
import random
import string
from time import sleep
from IPython.display import clear_output
Part 1: Functions & Methods (re-visited)¶
In this part, we will revisit and extend some work on using functions and methods.
We will also write some functions that we will use later in the assignment for the ‘bots’ application.
Q1 - String Methods (1 point)¶
First, we will explore some of methods from the str
class.
a) join
¶
During the last assignment you made a function that echoed a string several times with a seperator between each repetition.
Here we will achieve a similar goal through the use of the join()
method of the str
class.
When join()
is called on a str
object (let’s call it seperator
) with a list
as its argument, it joins the elements of the list
, seperating each one by seperator
.
Below we define a a list my_list
. Use the join()
method on the string you define as seperator = '~'
to join the elements in my_list
seperated by the '~'
character.
Save the output to a new variable called joined_string
. The output should look as follows:
'Python~is~so~much~fun'
# This variable provided for you
my_list = ['Python', 'is', 'so', 'much', 'fun']
# YOUR CODE HERE
raise NotImplementedError()
assert isinstance(joined_string, str)
assert joined_string == 'Python~is~so~much~fun'
b) replace
¶
Now try to use the replace
method to update the string statement
such that it replaces UCLA
to UCSD
.
If you are unsure how use replace
you can run str.replace?
to look at documentation.
Note that using replace
returns a new string that you need to assign to a variable if you want to keep a reference to it (replace
is not ‘inplace’).
For this question, overwrite statement
as the assignment to the output of the replace
call.
# This code provided for you
statement = 'UCLA is the best UC in Southern California.'
# YOUR CODE HERE
raise NotImplementedError()
assert isinstance(statement, str)
assert statement == 'UCSD is the best UC in Southern California.'
c) replace
for dropping characters¶
Use the replace
method to remove all the exclamation points in the string excessive
.
Assign the output of doing this to a variable called fixed
.
Hint: you can drop characters with replace
by ‘replacing’ them with an empty string.
# This variable provided for you
excessive = 'using!!! excessive!!! exclamation points!! is the best!!!!!!'
# YOUR CODE HERE
raise NotImplementedError()
assert isinstance(fixed, str)
assert fixed == 'using excessive exclamation points is the best'
d) Clearing all punctuation with replace
¶
Now we want to generalize what we did in ‘c)’ to remove all punctuation using the replace()
method.
Write a for
loop to loop over every character in string.punctuation
. Inside the loop, call replace
on too_much
with the current punctuation character to remove it, like we did in ‘c)’.
To do this, inside the loop, re-assign too_much
to be the ouput of calling replace
on too_much
, so that you are replacing too_much
with it’s updated version every time.
# This variable provided for you
too_much = 'I, think th@at!! punctuation... may?>> be the bes$$$t th!ing thats: ever! been! invented!!!!!!'
# YOUR CODE HERE
raise NotImplementedError()
assert isinstance(too_much, str)
assert too_much == 'I think that punctuation may be the best thing thats ever been invented'
Example: Functions with Default Values¶
Note that functions can also have inputs with default values.
This means you don’t necessarily need to provide an input with a specific value, since if you don’t provide it explicitly, it will take on the default value.
The following is an example of a function with a default value, provided to you, so you can see what it looks like.
You don’t need to do anything with this function.
def default_function(input_number, n_value=2):
"""Multiplies an input number n times. Default value for n=2
Parameters
----------
input_number : float
Number to be multiplied.
n_value : int, optional
Number of times to multiply input.
Returns
-------
output : float
Result of the multiplication.
"""
# Multiple the input n times
output = input_number * n_value
return output
# Test using `default_function`
print(default_function(2))
print(default_function(2, 10))
# Function values can be also be defined by name
print(default_function(n_value=-1, input_number=2))
print(default_function(input_number=10, n_value=10, ))
Q2 - Default Value Functions (0.5 points)¶
a) Sort Keys¶
Write a function called sort_keys
, which will return a sorted version of the keys from an input dictionary.
Input(s):
dictionary
: dictionaryreverse
: boolean, default: False
Output(s):
sorted_keys
: list
Procedure(s):
Get the keys from the input
dictionary
using thekeys()
method (this will return a list of keys)Use the
sorted
function to sort the list of keys. Pass inreverse
tosorted
to set whether to reverse the sort orderReturn the sorted list of dictionary keys
# YOUR CODE HERE
raise NotImplementedError()
assert callable(sort_keys)
assert isinstance(sort_keys({'B': 2, 'A': 1}), list)
assert sort_keys({'B': 2, 'A': 1}) == ['A', 'B']
assert sort_keys({2: 'B', 1: 'A'}, reverse=True) == [2, 1]
assert callable(sort_keys)
b) List Powers¶
Write a function called list_powers
.
This function will take a list, and return a new list where each element is exponentiated to a specified power.
Input(s):
collection
- collection of numberspower
- int, default value: 2
Output(s):
power_list
- list of numbers
Procedure(s):
Initialize an empty list to be filled and returned
Loop through each element in the input
collection
Take the value to the power specified in
power
Append the result to the output list
Return the list of powers
# YOUR CODE HERE
raise NotImplementedError()
assert callable(list_powers)
assert isinstance(list_powers([1, 2]), list)
assert list_powers((2, 4)) == [4, 16]
assert list_powers([2, 4], 3) == [8, 64]
assert callable(list_powers)
Example: Zip¶
A reasonably common task in Python is to want to iterate across multiple collections items together.
To do so, we have the function zip
, which takes in collection types, and let’s you step across them together.
This allows you to get, for example, the 0th item of each collection, and then the 1st item of each collection, etc.
Below is an example of using zip
.
# Define some collection objects
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
# Use zip, in a loop, to loop across both collections at the same time
for it1, it2 in zip(list1, list2):
print(it1, it2)
Q3 - Functions for Later (1 point)¶
In this section we will write a set of functions that will be useful for us to use later, with our artificial agents.
a) Add Lists¶
Write a function called add_lists
.
Input(s):
list1
- list of numberslist2
- list of numbers
Output(s):
ouput
- list of numbers
Procedure(s):
Initialize a new list
output
Using
zip
, loop through elements of bothlist1
andlist2
In each iteration, append the sum of the elements to
output
Return
output
# YOUR CODE HERE
raise NotImplementedError()
assert callable(add_lists)
assert [1, 1] == add_lists([0, 0], [1, 1])
assert callable(add_lists)
b) Check Bounds¶
Write a function called check_bounds
.
We will be using this function later in our bots. It checks whether a position, given as, for example [2, 3] is within the bounds of a grid of a particular size (say, a 4 x 4 square grid).
Input(s):
position
- list of intsize
- int
Output(s):
boolean
Procedure(s):
Loop across each element in
position
.Check if the element is less than 0, or greater than or equal to
size
If so, return
False
Outside and after the loop, return
True
Note that this means the function will return False
if any element is outside the specified bounds.
After checking all elements, if it hasn’t returned yet, it returns True
to indicate all elements are indeed within the bounds.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(check_bounds)
assert check_bounds([0, 0], 5)
assert not check_bounds([0, -1], 5)
assert not check_bounds([0, 5], 5)
assert callable(check_bounds)
Part 2: Classes¶
In this section we will be working with classes - building several classes to solve a variety of problems.
Q4 - Creating a Class¶
We can start with a class object to make a ‘schedule book’ for our course Office Hours.
Create a class called OfficeHours
Class Attributes:
course
, which has the value “COGS18”
Instance Attibutes:
name
: stringday
: stringtime
: stringplace
: stringNote: all these attributes should be passed into the
__init__
, and attached to the object in there.
Method
check()
This method should print out information, to look something like:
Tom's office hours are on Tuesday at 12:30 in CSB115.
Note that this should use the instance attributes to print out
name
,day
,time
&place
of the particular instance.
# YOUR CODE HERE
raise NotImplementedError()
assert OfficeHours
assert OfficeHours('name', 'day', 'time', 'room')
name = "Instructor"
day = "Tuesday"
time = "12:30"
place = "CSB115"
test_oh = OfficeHours(name, day, time, place)
assert isinstance(test_oh, OfficeHours)
assert test_oh.course == "COGS18"
assert test_oh.name == name
assert test_oh.day == day
assert test_oh.time == time
assert test_oh.place == place
Here is a list of some office hours:
Tom - Monday @ 12:30 in SDSC 212e
Rob - Wednesday @ 2:00 in CSB 114
Daril - Tuesday @ 10:00 in CSB 115
Paolo - Friday @ 1:00 in CSB 106
Create a new instance of the OfficeHours class for each of the office hours listed above.
Then store each of these instances together in a list called all_office_hours
.
# YOUR CODE HERE
raise NotImplementedError()
assert isinstance(all_office_hours, list)
assert len(all_office_hours) == 4
for item in all_office_hours:
assert isinstance(item, OfficeHours)
assert item.name in ['Tom', 'Rob', 'Daril', 'Paolo']
Now write a function called check_all
that will take in a list of OfficeHour objects, and will call the check
method on each one, using a loop to loop across each element in the input list.
Call this function on your all_office_hours
list to make sure that it works as expected.
You should see that running this function prints out a string of information for each object, that looks like:
Tom's office hours are on Monday at 12:30 in SDSC 212e.
Rob's office hours are on Wednesday at 2:00 in CSB 114.
Daril's office hours are on Tuesday at 10:00 in CSB 115.
Paolo's office hours are on Friday at 1:00 in CSB 106.
# YOUR CODE HERE
raise NotImplementedError()
assert callable(check_all)
Q5 - Car Inventory¶
For this question you will create an object to store information on an inventory of cars.
Create a class called CarInventory
Instance Attibutes:
n_cars
: intcars
: list
Methods
add_car()
compare()
Details:
The constructor (
__init__
) should take no inputs, but setn_cars
to 0, andcars
to be[]
(an empty list).
Method: add_car
¶
Input(s):
manufacturer
: stringmodel
: stringyear
: intmpg
: float
Procedure(s):
Create a dictionary from the values passed with the corresponding keys ‘manufacturer’, ‘model’, ‘year’ and ‘mpg’
Append this dictionary to the
cars
attributeIncrement the
n_cars
attribute by 1
Method: compare
¶
This method will compare all the cars on a specified attribute
(‘year’, or ‘mpg’), and find the highest and lowest values. It will return either the highest of lowest value, depending on the setting in a parameter direction
.
Input(s):
attribute
: stringdirection
: string, default: ‘highest’
Procedure(s):
Initialize a variable called
lowest
to be the 0th element ofcars
, and another variablehighest
to be the sameLoop through each car in cars
If the value of the attribute for the car is less than the car stored as
lowest
, replacelowest
to be the current carSimilarly, if the value of the attribute for the car is greater than the car stored as
highest
, replacehighest
to be the current car
After the loop, if the value of
direction
is ‘highest’, set a new variableoutput
to be the variablehighest
Else if the value of
direction
is ‘lowest’, setoutput
to belowest
Return
output
# YOUR CODE HERE
raise NotImplementedError()
# Tests for the object
assert CarInventory
test_car_inv = CarInventory()
assert isinstance(test_car_inv, CarInventory)
assert test_car_inv.n_cars == 0
assert isinstance(test_car_inv.cars, list)
# Tests for add_car method
test_inv = CarInventory()
test_inv.add_car('Toyota', 'Prius', 2012, 36)
assert test_inv.n_cars == 1
assert test_inv.cars[0] == {'manufacturer': 'Toyota', 'model': 'Prius', 'year': 2012, 'mpg':36}
# Tests for compare method
test_inv = CarInventory()
test_inv.add_car('Toyota', 'Prius', 2012, 36)
test_inv.add_car('BMW', 'M3', 2017, 27)
assert test_inv.compare('mpg') == {'manufacturer': 'Toyota', 'model': 'Prius', 'year': 2012, 'mpg': 36}
assert test_inv.compare('year', 'lowest') == {'manufacturer': 'Toyota', 'model': 'Prius', 'year': 2012, 'mpg': 36}
b) Using our class¶
Using the inventory
instance created for you in the cell below, do the following:
Use
compare
to get the car with the highest mpg, and get the manufacturer of that car from the returned carStore the answer in a variable called
highest_mpg
Use
compare
to get the car with the lowest year, and get the model of that car from the returned carStore the answer in a variable called
oldest_car
# The following code provided for you
inventory = CarInventory()
inventory.add_car('Ford', 'Mustang', 2004, 20)
inventory.add_car('Honda', 'Civic', 2014, 40)
inventory.add_car('Toyota', 'Corrolla', 2010, 50)
inventory.add_car('Tesla', 'S', 2017, 1000)
# Example: Get the least efficient car (lowest mpg)
inventory.compare('mpg', 'lowest')
# Example: Get the newest car (highest year), and extract it's mpg
inventory.compare('year', 'highest')['mpg']
# YOUR CODE HERE
raise NotImplementedError()
assert isinstance(highest_mpg, str)
assert highest_mpg in ['Ford', 'Honda', 'Toyota', 'Tesla']
assert isinstance(oldest_car, str)
assert oldest_car in ['Mustang', 'Civic', 'Corrola', 'S']
assert highest_mpg
assert oldest_car
Example: Class Inheritance¶
The following is an extra example of class inheritance.
class TritonCourse:
university = "UC San Diego"
def __init__(self, department, code, title):
"""
department: string
code: int
title: string
"""
self.department = department
self.code = code
self.title = title
def print_info(self):
print(self.department + str(self.code) + ': ' + self.title)
# By passing in `TritonCourse` to our new class, we create a derived class that inherits from `TritonCourse`
class TritonProgCourse(TritonCourse):
def __init__(self, department, code, title, language):
# Call the initializer from the class we inherited from
# `super` refers to the class that this class inherits from
super().__init__(department, code, title)
# Add a new instance attribute to our derived class
self.language = language
# Example: create an instance from our derived class
cogs18 = TritonProgCourse('COGS', 18, 'Introduction to Python', 'Python')
# Note that our derived class inherits any class attributes & methods from the inherited class
print(cogs18.university)
cogs18.print_info()
# Our derived class also has any extra and unique attributes and/or methods that we add to it
cogs18.language
# We can check that our course is both an instance of 'TritonCourse', and of 'TritonProgCourse'
print(isinstance(cogs18, TritonCourse))
print(isinstance(cogs18, TritonProgCourse))
Q6 - Extending our Class through Inheritance (0.5 points)¶
Create a TritonCogsCourse
class that inherits from TritonCourse
.
You can model your answer to this based on how we made TritonProgCourse
above.
TritonCogsCourse
should inherit from TritonCourse
and calls it’s super’s __init__
.
In addition, in it’s own __init__
, it should take an extra parameter called area
, which will store which area of Cognitive Science the class is related to.
area
should have a default value of None
.
Finally, add a method called has_area
that returns True
if the instance has an area defined (is not None), and returns False
if area is equal to None
.
# YOUR CODE HERE
raise NotImplementedError()
assert TritonCogsCourse
test_class = TritonCogsCourse('COGS', '108', 'Data Science in Practice')
assert test_class
cogs108 = TritonCogsCourse('COGS', '108', 'Data Science in Practice', 'Data Science')
assert cogs108
assert cogs108.area == 'Data Science'
assert cogs108.has_area() == True
Part 3: Artificial Agents¶
In this last part of the assignment, we will create some ‘Bots’ - little artificial agents that can move around a predefined space.
They will be in the style of PacMan, or little exploration bots.
Each of these bots will be able to explore a predefined world, which is a grid of ‘dots’ (locations).
This grid has labelled locations that can be referenced by a list of integers, with [0, 0] being the top left most corner, and so on.
Each bot will have a move
method, which updates the bot’s position, thus moving it around the world.
As you start building some bots, there will be a series of test cells that test out your bots on a ‘board’.
Make sure these cells run to completion without errors - if the cells with play_board
in them raise an error, there is something wrong with your bot.
Note that some errors could come from the functions your wrote above that get used here.
# This function provided to you to run your bots on a grid world
# You don't have to do anything with this function
def play_board(bots, n_iter=25, grid_size=5, sleep_time=0.3):
"""Run a bot across a board.
Parameters
----------
bots : Bot() type or list of Bot() type
One or more bots to be be played on the board
n_iter : int, optional
Number of turns to play on the board. default = 25
grid_size : int, optional
Board size. default = 5
sleep_time : float, optional
Amount of time to pause between turns. default = 0.3.
"""
# If input is a single bot, put it in a list so that procedures work
if not isinstance(bots, list):
bots = [bots]
# Update each bot to know about the grid_size they are on
for bot in bots:
bot.grid_size = grid_size
for it in range(n_iter):
# Create the grid
grid_list = [['.'] * grid_size for ncols in range(grid_size)]
# Add bot(s) to the grid
for bot in bots:
grid_list[bot.position[0]][bot.position[1]] = bot.character
# Clear the previous iteration, print the new grid (as a string), and wait
clear_output(True)
print('\n'.join([' '.join(lst) for lst in grid_list]))
sleep(sleep_time)
# Update bot position(s) for next turn
for bot in bots:
bot.move()
Q7 - Bot Base Class¶
Create a class called Bot
. This will be our base class for all the bots that we make in this section.
Instance Attibutes:
character
- stringposition
- list of [int, int]moves
- list of list of [int, int]grid_size
-None
or int
Of these instance attributes, only character
should be taken in as an input to __init__
, with a default value of 8982.
Inside the init:
self.character
should be set as thechr
of inputcharacter
self.position
should be set to starting position[0, 0]
self.moves
should be set as the list of possible moves, which are[[-1, 0], [1, 0], [0, 1], [0, -1]]
self.grid_size
should be initialized as None
# YOUR CODE HERE
raise NotImplementedError()
assert Bot()
bot = Bot()
assert bot.position == [0, 0]
assert bot.character == chr(8982)
assert bot.moves == [[-1, 0], [1, 0], [0, 1], [0, -1]]
assert bot.grid_size == None
Q8 - WanderBot¶
Create a class called WanderBot
, that inherits from Bot
. WanderBot
is a bot that will wander around randomly.
In the
__init__
, it should simply call the init fromsuper
(and adds no extra instance attributes)Note that to do this, the
__init__
should take acharacter
input, with the same default (8982)This value will need to be passed into the super’s
__init__
Add two methods to WanderBot:
Method: wander
¶
This method will choose a random move from the possibilities, making sure that move is valid on the current grid.
Procedure:
Initialize a boolean variable
has_new_pos
asFalse
Use a while loop, with the condition
not has_new_pos
Set a variable
move
as the ouput of callingrandom.choice
onself.moves
Add
move
toself.position
, usingadd_lists
(a function we created earlier), and assign the output to a new variablenew_pos
Call
check_bounds
onnew_pos
, also passingself.grid_size
intocheck_bounds
Assign the output of
check_bounds
tohas_new_pos
This will lead to exiting the loop when a valid new position has been assigned
Return
new_pos
Method: move
¶
No inputs (other than
self
) or outputs, just setsself.position
to be the output of callingself.wander()
.
# YOUR CODE HERE
raise NotImplementedError()
assert WanderBot
wbot = WanderBot()
assert wbot
wbot = WanderBot()
wbot.grid_size = 3
assert wbot.wander()
assert isinstance(wbot.wander(), list)
wbot.move()
assert wbot.position != [0, 0]
# Test out our WanderBot
# You should see a 'bot' that steps around different positions randomly
bot = WanderBot()
play_board(bot, grid_size=5)
# Test out running a group of WanderBots
bots = [WanderBot(character=1175), WanderBot(character=1175), WanderBot(character=1175)]
play_board(bots, grid_size=8, n_iter=25)
Example: Random Probabilistic Choices¶
For our next bot, we want to be able to make random choice, but with a specified probability.
We will use a quick trick to do so:
from the
random
module, we can use therandom()
function to uniformly sample a decimal between 0 and 1by checking if that random sample is below some value
prob
, we will (on average) make that choiceprob
% of the time
An example of this idea is shown below.
# Print out a random decimal value between 0 - 1
print(random.random())
# Example of a random probabilistic choice with a specified probability
if random.random() < 0.75:
print('This will print out 75% of the time')
Q9 - ExploreBot¶
Create a class called ExploreBot
, that inherits from Bot
.
ExploreBot
is a bot that will explore more systematically, generally continuing in the same direction on consecutive steps.
In the
__init__
, it should call the__init__
fromsuper
Note that to do this, the
__init__
should take acharacter
input, with the same default (8982)This value will need to be passed into the super’s
__init__
The
__init__
should take an extra input,move_prob
with default value of 0.75Add
move_prob
as an instance attribute, and also add a new instance attributelast_move
, that’s initialized asNone
Add three methods to ExploreBot:
Method: biased_choice
¶
This method will chose a new move, but be biased to chose the same move as was taken on the previous step.
Procedure:
Initialize a variable called
move
asNone
if
self.last_move
is not equal toNone
Using the random probability procedure described above, if
random.random()
is less thatself.move_prob
Set
move
to beself.last_move
if
move
is still None, setmove
to be a random choice ofself.moves
return
move
Method: explore
¶
Explore should be the same as the wander()
method in WanderBot
, with two differences:
Inside the
while
loop,move
should be the return ofself.biased_choice()
(instead ofwander()
)At the end of the
while
loop (inside the loop), setself.last_move
tomove
Method: move
¶
No inputs (other than
self
) or outputs, just setsself.position
to be the output of callingexplore()
.
# YOUR CODE HERE
raise NotImplementedError()
assert ExploreBot
ebot = ExploreBot()
assert ebot
assert ebot.last_move == None
assert ebot.move_prob == 0.75
assert ExploreBot(move_prob=0.5)
assert ExploreBot
ebot = ExploreBot()
ebot.grid_size = 3
assert ebot.explore()
assert isinstance(ebot.explore(), list)
ebot.move()
assert ebot.position != [0, 0]
# Test out our ExploreBot
# You should see a 'bot' that steps around different positions, often moving in the same direction
bot = ExploreBot()
play_board(bot)
# Test out running a group of WanderBots & ExploreBots
bots = [WanderBot(character=1175), WanderBot(character=1175),
ExploreBot(character=1127), ExploreBot(character=1127)]
play_board(bots, grid_size=10, n_iter=50)
Q10 - TeleportBot¶
Create a class called TeleportBot
, that inherits from WanderBot
.
TeleportBot
is a modified version of WanderBot
, that will generally wander around randomly, but sometimes teleport to a brand new location.
In the
__init__
, it should call the__init__
fromsuper
Note that to do this, the
__init__
should take acharacter
input, with the same default (8982)This value will need to be passed into the super’s
__init__
The
__init__
should take an extra input,tele_prob
with default value of 0.2Add
tele_prob
as an instance attribute
Add two methods to TeleportBot
:
Method: teleport
¶
This method will chose a totally random location anywhere on the map, ‘teleporting’ there.
To do so, it needs to return a list of two random numbers that define a location of the map (for the current grid size).
Use random.choice
with range
and self.grid_size
to create a list of two randomly chosen numbers within the grid size.
Note - this will entail using each of these three things twice - one for each number.
Return this list.
Method: move
¶
No inputs (other than
self
) or outputsUsing the random probability procedure from before, use an
if
withrandom.random() < self.tele_prob
.Inside the
if
, setself.position
to the ouput ofself.teleport()
else
, setself.position
as the ouput ofself.wander()
Note that this bot inherits
wander()
from it’s super (WanderBot
)
# YOUR CODE HERE
raise NotImplementedError()
assert TeleportBot
tbot = TeleportBot()
assert tbot
assert tbot.tele_prob == 0.2
assert TeleportBot(tele_prob=0.5)
assert TeleportBot
tbot = TeleportBot()
tbot.grid_size = 3
assert tbot.teleport()
assert isinstance(tbot.teleport(), list)
tbot.move()
assert tbot.position != [0, 0]
# Test out our TeleportBot
# You should see a 'bot' that steps around randomly, sometimes teleporting to a new location
bot = TeleportBot()
play_board(bot, grid_size=5)
Running it all together¶
# Define a group of bots
bots = [WanderBot(character=1078), WanderBot(character=1078), WanderBot(character=1078),
ExploreBot(character=1127), ExploreBot(character=1127), ExploreBot(character=1127),
TeleportBot(character=1279), TeleportBot(character=1279)]
# Play the board with our bot list
play_board(bots, grid_size=15, n_iter=50)
Extending Our Agents¶
So far, we have some ‘artificial agents’ that can explore a world, with different strategies to do so.
Note that if you want to explore using these bots some more, you can add a new cell, defining a list of bots (changing some inputs to them, if you want to), and use the play_board
function to run a ‘board’ (also changing some inputs to play_board
, if you want to).
From here, we could think about ways we could make these agents interact with each other, and/or respond more directly the environment.
More broadly - there is any number of ways we could build in more ‘cognitive’ behaviour, given this starting point.
If you are interested in this topic, extending these kinds of ‘artificial agents’ (or ones like them) is one of your project options.
The End!¶
After you’ve explored running the bots, you are done!
Have a look back over your answers, and also make sure to Restart & Run All from the kernel menu to double check that everything is working properly.
When you are ready to submit your assignment, upload it to TritonED under Assignment-4.