=== Lab 2: Comparing Agent Programs ===
In this lab session we will finish [[public:t-622-arti-11-1:lab_1_materials|lab 1]] and write a new kind of agent program mantaining a state.
- **Getting Started**:\\ Start by getting the file {{:public:t-622-arti-11-1:agents2.zip|agents2.zip}} and unzipping it into your working directory. This is largely the same file as we had for the last lab session, except some fixes to accommodate agents having a state, and code to run experiments.
- In order to run the experiments later, you can use both functions: **random-agent-program** and **random-agent-measure** from lab 1 (that means you can copy them in the new file **agents2.lisp** =));
- You only have to change the **random-agent-program** declaration in order to accommodate a small change in the way the function is called during experiments.
;; OLD declaration
(defun random-agent-program (percept)
;; NEW declaration
(defun random-agent-program (agent percept)
- **Creating an Agent Program with a State**:\\ Fill in the function **RANDOM-AGENT-WITH-STATE-PROGRAM**, found in **agents2.lisp**. This should be the program of an agent that:
* Uses the **STATE** field of the agent struct to remember what squares has already visited (and eventually cleaned). Remember you can use this field in this way:
;; HINT: getting the value of the state field in the agent structure
(agent-state agent)
;; HINT: setting a new value for the state field
(setf (agent-state agent) )
* The agent should walk **randomly**, but it should avoid revisiting squares that has already visited (and then already cleaned up).
* The agent's objective is to clean the **whole** environment.
* The agent should return the **'''suck''** action when visiting a dirty square otherwise one of the following actions: **'''right''**, **'''left''**, **'''up''** or **'''down''**.
* If the agent is sure everything is clean, it should return the action **'''idle''** (i.e. forever).
* Be careful to not being too much strict, e.g. if it is absolutely impossible for the agent to travel through clean squares. Can it get in troubles so that it is unable to meet its objective? If so, find a solution.
* **NOTE 1**: when you are ready to fill in the agent program code you'll see that the agent stores the state as a list of squares id that it has seen (and clean) already. It would be useful for you to remember the following regarding lists:
;; HINT: getting the first item in a list
CL-USER> (first '(a b c))
A
;; HINT: adding an element to a list.
;; cons takes an item and a list, and returns a new list consisting of
;; the old list with the item tacked on the front.
CL-USER> (setf my-list '(a b c))
(A B C)
CL-USER> (setf my-list (cons 'item my-list))
(ITEM A B C)
;; HINT: checking for a list argument.
;; consp is a predicate which is true if its argument is a list...
CL-USER> (consp '(4 3 8))
T
;; ...but is not nil
CL-USER> (consp nil)
NIL
* **NOTE 2**: in order to keep track of the squares already seen, you can use two helper functions (see **agents2.lisp** for more details): **SQUARE-ID** and **GET-NEIGHBOURS**. The following picture show an example of possible 3x3 environment (**w** x **h**, **width** and **height** = 3) and how unique id are assigned to each square:\\ {{:public:t-622-arti-11-1:vacuum2-environment-2.jpg|}}
- **Running Experiments**:\\ Deal with the lines at the bottom of **agents2.lisp** to run experiments and evaluate your agent. The following lines, for example, allow you to try the **EXAMPLE-AGENT-PROGRAM** on all the possible **3x3 environments** with **2 dirty squares** (that is all the permutations of 2 dirty squares out of 3x3 = 9 squares in total). For each 3x3 generated environment, the agent program is executed for **1000 steps** and then automatically turned-off. Check this out entering these few lines in the **REPL**:
;; HINT: remember to load the definitions in "agent2.lisp" as shown in step 7 of Lab 1.
(run-experiment (generate-environments 3 3 2)
(lambda () (make-agent :program #'example-agent-program))
#'example-measure
1000)
This will return the **number** of **experiments** performed, and the **average performance value**.
- **Comparing Different Agents**:\\ Try different agents (e.g. random-agent-program) and **different performance measures**. Does the agent with state behave better than the others with any particular performance measure? You can add print commands to the experiment functions to get more information about the agents behaviour if you like.
- **Building an Orderly Agent (EXTRA)**:\\ Try to create an agent called **orderly-moving-agent-program** that moves through the environment with some orderly pattern (i.e. from left to right, then down, right to left, down and so on...). Make sure it visits all the squares and cleans the dirty ones. Is the orderly agent more efficient than the random one?