Project 2 - Lime Maze


Due Date

For this assignment, you will work alone (except as specifically noted below). Each individual will turn in separate work.

The short assignment is due on Monday, October 29, 2001, at 11:59pm (one minute before midnight). You will turn it in as a text email message to cs290e@csug.rochester.edu

The programming part of the assignment is due on Monday, November 19, 2001, at 11:59pm. As before, turnin a directory with the turnin script.


Project Description

This project is designed to learn about interactions both physical and logical mobility scenarios in Lime. First, let's talk about physical mobility. The setting is a maze of rooms. Each room has several doors. Your task is to create a complete map of the maze by moving from room to room. You have a team of three people (total). You should minimize the amount of work that you and your teammates repeat, plus you should minimize the amount of time that you spend in the maze.

What is a room? In the physical environment, each room has inside of it a computer, running Lime. Each room has a set of doors. Some rooms take longer to get through than others. You cannot communicate with players in other rooms, but you can communicate with players in the same room (assume a wireless medium such as infrared which limits communication to a single room).

You will need to program a room agent. When it is initialized, it should create a shared tuple space containing the following tuples: <_room, agentID> (where "_room" is a string, and agentID is the agent id of the room agent>. It will also have several door tuples of the format <_door, limeServerID, muCodePort> where "_door" is a string, LimeServerID is the LimeServerID of the LimeServer on the other side of the door, and muCodePort is the port that you bound muCode to when starting that LimeServer (note: this can be ignored for the physical mobility case). Finally, it will have a tuple <_delay, integer> where "_delay" is a string, and the integer represents the minimum number of miliseconds that a player must spend in the room. It can spend longer, but it need not. Think of this as the minimum amount of time that it takes to walk across the room.

Below is a sample map of several rooms. The circles are the doors.

Part 1 - Physical Mobility

After you have designed your room agent, design a player agent. The player agent will be a stationary agent, and will not move from the LimeServer from which it is launched. The purpose of this part is to play around with the physical mobility aspect a little, while realizing that the you will be doing all of your testing in a static environment.

You will test with only a single room (on one host) and three players on three different hosts. You can move your players in and out of the room, by engaging and disengaging the LimeServers.

Initialize your players to some random point in the game, after they have discovered some amount of information about the layout of the maze. Bring them into the room, one at a time, let them share the information they have about the maze, and leaving information with the room about which door they are leaving through.

The intent of this part of the assignment is for you to get familiar with Lime programming, creating reactions, and sharing information from the room to the players and among the players.

Part 2 - Logical Mobility

Now that you have this working with host-to-host engagement with a single host for each player and one for the room, save your work! Keep this in a safe place which you will not touch.

Your room will still be a stationary agent, but now your players will be mobile agents and will not have their own hosts. Instead they will actually hop from the LimeServer of one room to the LimeServer to another room, collecting information about the maze.

Make sure that as your agent travels around the maze that it stays in each room for the minimum delay imposed by that room.

Your three players will start at the same place, but they do not need to move together through the maze. In fact, to minimize the amount of time needed to explore the maze, they will need to split up.

You can decide on a strategy for exploration before your agents to explore the maze. The goal is to enter every room of the maze, effectively building a map of the space, by going through as few doors as possible. You must count the number of doorways you go through. When you think that you have mapped the maze, all of your agents must return to the starting room (by going through adjacent rooms), sum up the number of steps all the players have taken, and print out a map of the maze. This map can be as simple as a list of pairs of connected rooms.

To facilitate the optimization of the steps that your players will take, your players can leave "some" information behind in each room, but this is limited. Basically, you can leave a marker tuple with your ID and the "door" which you intend to leave through. If you return to a room, you can leave another tuple (at your option). The intent of these tuples is to help in your discovery of the layout of the maze. If these tuples will not help you, you do not need to leave them. You may NOT leave any information except your id, and the door you intend to leave through.

When two of your agents meet (in the same room), they can exchange any kind of information you can dream up (e.g., what part of the maze they have explored, where they are going next, etc.). You have several options here. You can either monitor the LimeSystemTupleSpace for other agents arriving (be careful to ignore the "room agent") and then put information into directly into their tuple space for them to process at any time. Alternately, you can simply put the information that you want to share into a tuple space, and set a reaction that looks for data which matches that pattern (be careful to ignore your own data).

We will post several room configurations to this web site that you can test your agents. These room configurations will be lists of host:port:port triples, where the host is a host on the csug network, the first port is for the LimeServer, and the second port is for muCode. To use these files, your room agent should scan through the file, looking for its own identifier (host:port:port). Each time it finds one, the room creates a "_door" tuple.

Why are we doing this?

The physical mobility part is like having a set of robots that are sent out into an unknown space to explore and map it. Each time they enter a space, they leave a very simple device to mark that they have been there, and where they are going. That very simple device, in our case, is a machine running Lime and hosting the room agent.

The logical mobility part is like having a mobile agent that moves through web servers collecting information. The amount of time it spends at each node is analogous to the processing that is done at each node. The neighboring rooms are like links to new pages.


Short Assignment

Note: this is not as short as the last one! You have to do some learning to accomplish this short assignment.

To do this, you will need to set up your working environment properly. Specifically, set you CLASSPATH as described below to include lime.jar and lights.jar. Download the file MasterAgent.java and compile it.

  1. Launch MasterAgent with the following command line: java lime.util.Launcher -load MasterAgent What is the output?
  2. What is the command to find the AgentID of this agent?
  3. Write the code for the pattern tuple that will match the following tuple: ITuple testTuple = new Tuple().addActual("hello").addActual(new Integer(5)).
  4. Write your own a simple agent which will interact with MasterAgent on the same host as a peer agent. Call your agent SlaveAgent. All it does is create and share a LimeTupleSpace, remove a tuple with the pattern (AgentID, AgentID, Integer), output a tuple of its own with the MasterAgent as the destination and with it's own AgentID in the second position and incrementing the integer by 1, unsharing its tuple space, then exiting. You will test this by first starting Master agent as before. Then, from a different shell on the same machine, load your agent with java lime.util.Launcher -quit -load SimpleAgent. What is the output in the first window (where you started MasterAgent? If you start seeing "MASTER: I found no tuple!", then you have done something wrong. Keep a copy of this agent turn it in with the answers to these other questions.
  5. What is the flag -quit used for?
  6. Modify SlaveAgent into what you will call SlaveAgentOneHost. The goal here is to create an agent that will be be on a different host but will interact with MasterAgent. SlaveAgentOneHost should have the same basic processing, but it will be launched from a separate host. To get it to interact successfully with the MasterAgent, you will have to engage the hosts. So, the processing of SlaveAgentOneHost will be: create and share a LimeTupleSpace, engage the host-level, remove a tuple from the federated tuple space with the pattern (AgentID, AgentID, Integer), output a tuple to the MasterAgent's tuple space with it's own AgentID in the second field and incrementing the integer by 1, disengaging the hosts, then exit. To test this, you have two options. Option 1: get on two hosts on the same subnet, start MasterAgent as before and on the second machine start lime.util.Launcher -load SlaveAgentOneHost. Option 2: open two windows on the same machine, in the first window, start MasterAgent was before, in the second window, start lime.util.Launcher -port 1900 -load SlaveAgentOneHost. What is the output of the MasterAgent? Again, if you start seeing "MASTER: I found no tuple!", then you have done something wrong. Try starting a second SlaveAgentOneHost either on another machine, or another port. It should work! Turn in a copy of this agent.

    Note: when you do this, if you and one of your classmates are testing simultaneously, your Lime program may interact in a not-so-good manner. If you find this happening, use the -mcastport xxxx flag on the Launcher and choose a value different from your classmate. You may also need to choose a different unicast port if you are using the same machine by exploiting the -port xxxx flag.

  7. What is the difference between the commands lts.setShared(true) and LimeServer.getServer().engage()?

Resources


Hints