# AgentSpeak - custom agents and actions

In these practicals, we will use one of the more complex Jason examples. First, we will show how to implement custom world model and how to add custom internal actions.

You can find the source codes for this lesson in the Jason distribution in the examples/gold-miners-II directory. It is an older scenario from a multi-agent competition. There are two teams of six agents and a leader. The agents move in the environment and their goal is to mine gold. Every agent can carry at most three pieces of gold and they have to carry it towards a warehouse. They try to get as many pieces of gold as possible before the other team.

## Custom agent architecture

So far, we used the default functions for the processing of messages and precepts and the environment was represented with the information in the belief base. Such an implementation is simple, but not very convenient in more complicated cases. Therefore, Jason allows us to create a custom agent architecture. We can provide methods for the processing of percepts and incoming messages; we can write custom internal actions (because some things are easier in Java than in AgentSpeak) and we can create our own representation of the environment (so that we can, for example, more easily implement the A* algorithm for pathfinding).

In order to create a custom agent architecture, we need to implement the AgArch class. In this class, we can redefine the java.util.List<Literal> perceive() and void checkMail() methods (and others).

We redefine the checkMail() method if we want to process some messages in a specific way. In the example, the messages about obstacles and agents’ positions are removed and the model is updated according to them. Thanks to this, the agent is able to process more than one message in each loop instead of only one. At the same time, we correctly update the internal representation of the environment (see arch/MinerArch.java).

We can also re-define the perceive() method for similar reasons. In the example, again, the method processes all the percepts and updates the model of the environment. It keeps only those percepts the agents needs to act upon in the queue (arch/LocalMinerArch.java, and methods from arch/MinerArch.java).

The agents use a copy of the environment as their internal representation. They use it to represent what they know about the environment, either from messages or from their own percepts (arch/LocalWorldModel).

The architecture used by the agent is specified in the .mas2j file as agentArchClass (see the example).

## Custom BeliefBase

Sometimes it is convenient to change the behavior of the belief base in a specific way. This can be done by implementing a new offspring of the DefaultBeliefBase class with a custom add method. There are two such classes in the example – one of them ensures that a belief with the same functor is presented only once in the belief base (it is automatically updated when a new belief with the same functor is added), the other ensures that some beliefs are discarded before they are even added to the belief base (the agent does not care about these as they are already represented in the model of the environment). For the implementation details see agent/UniqueBelsBB.java and agent/DiscardBelsBB.java.

The belief base used by the agent is again specified in the .mas2j file – as beliefBaseClass.

## Custom event selection function

In some cases we need to change the event selection function. For example in such a way that some events have priority over other ones. One of the example agents uses this approach to quickly react to any new gold that is discovered (this event thus has the highest priority). In case we want to change these functions, we need to implement a custom Agent class.

The agent class is specified in the .mas2j file and an example of such a class is in the agent/SelectEvent.java file.

## Custom internal actions

Agent’s internal actions can be used to change its internal representation, communicate with other agents, or do anything that is easier in Java than AgentSpeak (e.g. pathfinding).

In order to create a custom internal action, you need to implement a DefaultInternalAction class and its execute() method. The method has three parameters, one of them is TransitionSystem, which contains the information about the agent’s environment representation and its internal state. Another parameter is a unifier, which use can use to unify variables with variables in AgentSpeak and the last parameter is a list of Terms – the parameters of the action. Again, it is easier to look at the examples, you can find them in the jia directory. One of the simpler actions is obstacle, which indicates whether there is an obstacle at a given position.

# Assignment

In this assignment, the goal is to implement the strategy for the goal-miners-II scenario described above.

The environment is a square grid, where some locations contain gold, other locations can contain obstacles. One of the locations is a depot, where the agents take all the gold. It is in the same location for both teams. The agent mines the gold by executing the pick action, it can drop it by executing the drop action (if it drops the gold at the depot, its team gets a point for every piece of gold dropped). Each agent can carry at most three pieces of gold at the same time.

The environment provides the following actions:

• pick - pick the gold from the position where the agent stands
• drop - drop the gold to the position of the agent
• up,down,right,left - move one square in the respective direction

The actions are called as do(<action>), e.g. do(drop).

In the beginning of the simulation, the agents receive the following percepts:

• gsize(sID, W, H) - the environment for simulation with ID sID has width W and height H
• depot(sID, x, y) - the depot in simulation with ID sID is at x, y
• steps(sID, n) - simulation with ID sID will run for n steps

During the simulation, the environment provides the following percepts:

• pos(x,y,s) - in step s the agent is at position (x,y)
• cell(x,y,t) - at position (x,y) there is thing t (obstacle, gold, enemy, ally, empty) for all locations around the agent (up to distance 1)
• container_has_space - agent can carry more gold
• carrying_gold(n) - agent carries n pieces of gold

The agents also have fatigue, which determines the probability that percepts fail (i.e. agent does not get any new information in a given step) and the probability that actions fail (the action is not executed). The fatigue of an agent depends on the amount of gold it carries (linearly between 0.1 and 0.5 for 0-3 pieces of gold).

### Rules and Tips

You can use the example agents for inspiration, but try to implement the final strategy yourself. You can work in teams of up to 4 students. Choose a name for your team and use it as a prefix to all the files you submit.

There are two methods that can be useful = .send and .broadcast that send a message to a specific agent or to the whole team (respectively). The .send method has three parameters

• the performative (what the message in) - tell for information, achieve for request, and untell for information that should be removed, and
The .broadcast action has only the last two parameters. The .broadcast action in the example contains a bug and sends the message only to the first three agents on your team – you can fix it by re-implementing it (create a new version of arch/MinerArch.java and all classes that depend on it), or by creating a plan in AgentSpeak to explicitly .send the message to all agents.
Each member of a team will obtain 8 points if the team submits any strategy that beats the dummy agents implemented in the asl directory of the example. We will run a tournament and the four best strategies (from both groups combined) will get 10 points. (The number of teams that get the bonus points can be increased in case we have a lot of teams.)