Important: This is a combination Project 3 and Problem Set 4. That means that it is to be done as a group. The rules for the assignment follow those for the Problem Sets rather than programming projects, which is to say that there is to be no discussion or exchange of ideas with anyone outside your group. Discussion within the group is, of course, not only OK, but kind of the whole point!
The abstract problem we consider is called WORMWORLD. It takes place on an infinite grid on which we have as input:
The concrete problem you'll have to address in your program is slightly simplified from the abstract WORMWORLD problem: the grid will be finite (so you don't wander off the screen, which makes for dull animation), and the food will all have value 1 (thereby simplifying our programming job a bit), which means we are trying to maximize the number of food items eaten within duration steps. Your program will act as the "brain" for a worm. I've written a simulator that takes an input, spawns a process of your brain program, and shows the worm as your brain drives it around. Your main goals are to make a worm brain that steers the worm so that lots of food gets eaten, and also a brain that operates successfully in an environment in which there are several worms competing for food. This planning problem is hard, so you'll have to find ways to make it fast enough to compete in WormWorld.
Important: Look closely at pages: The Protocol and An Example. The interaction between the simulator and the worm brains you write is not difficult. If you read these pages closely, you'll know everything you need.
./p3game i1a ./dbgreedyand see a game play out. Here are the basic pieces I've given you:
./p3game i1a ./greedy
| |
| \_ the executable to run for worm brain 0
|
\_ the board file to run on
You can modify this to create your own solution. The
original "greedy" worm brain is also in "dbgreedy" in case
you want to run the original in the simulator after you've
made modifications to Greedy.jar.
./greedyThe greedy algorithm I gave you in the original Greedy.java attempts to follow the strategt of finding a path in this graph by following the edge of least weight that connects the current vertex to an unvisited vertex (i.e. we try to make the "nearest food" choice). However, this algorithm is flawed! It uses the "manhatten distance" between position $i$ and $j$, which is $|row_i - row_j| + |col_i - col_j|$, to compute edge weights (i.e. to decide which food is "nearest"). The problem is that this doesn't take the barriers into account! So you need to be able (in a single worm environment) to determine the true distances between different pieces of food (and between food and your starting point), where "true distance" means the actual number of steps it will take given that there may be barriers in your way.
To Do:
The class ShortestPathOracle provides functionality for
finding shortest paths on a grid like ours. Look carefully at
the documentation for it. (Note: it just does breadth-first
search. I didn't have the heart to make you guys implement it
thoough!) Modify the Greedy.java so that your worm uses the
"nearest food" greedy choice using true distances on the board
(not Manhattan distance!). Feel free to use the
ShortestPathOracle to get those distances.
Note: You should see improvement on i1a, i1b and i1c in
terms of the number of food items eaten. Also, qualitatively,
you should see that the worm moves in a more direct, logical
manner; avoiding barriers. Try board-file
i2a if you want a real obvious example of
where the original greedy worm is bad and yours is good.
Requirements: You must have a makefile with
target "Sol1" that compiles your worm brain to a single
executable file named sol1. If you add
these lines to the Makefile that
came in "stu", and call your driver .java file "Sol1.java",
that should do the trick. I will make and run your program as
follows:
make Sol1 ./p3game i2a ./sol1So if that works when you try it, you should be OK. WRITTEN PROBLEMS
To Do: Describe a modification to the greedy algorithm that incorporates some randomness, so that we get different solutions, but still benefit from the "pretty good" quality of solutions produced by our greedy algorithm. Then, implement your randomized greedy algorithm in a new worm, which runs the randomized greedy algorithm many times, keeping the highest quality solution to use as the actual path you follow. Note: You have 5 seconds from the time you receive the s (start) message to plan your path. Then you have to respond to each m (move) message within 50ms. This is "wall clock" time, not CPU time. You can use
System.currentTimeMillis()to keep track of ellapsed time. You should stop trying to generate new randomized greedy solutions when you get near to 5000 milliseconds of ellapsed time. That way you'll get an answer within the time limit.
Requirements: You must have a makefile with
target "Sol2" (or add the target to your Sol1 Makefile) that
compiles your worm brain to a single
executable file named sol2.
I will make and run your program as
follows:
make Sol2 ./p3game i5a ./sol2So if that works when you try it, you should be OK. WRITTEN PROBLEMS
To do: describe your local refinement operator
in pseudo-code, then implement it to create a new (and
hopefully even better) worm brain.
Important: Try your worm brain on boardfiles
i3e and i4c. It should be
able to do better than your Problem 2 worm brain, which only
uses randomized greedy.
Requirements: You must have a makefile with
target "Sol3" (or add the target to your Sol1/Sol2 Makefile) that
compiles your worm brain to a single
executable file named sol3.
I will make and run your program as
follows:
make Sol3 ./p3game i3e ./sol3So if that works when you try it, you should be OK. WRITTEN PROBLEMS
~/bin/submit -c=SI335 -p=Proj03p1 *
~/bin/submit -c=SI335 -p=Proj03 *Make sure you have the target Sol3 in your makefile, and make sure it builds an executable named sol3.
Note: I will run your Sol3 worm brain in the tournament. If, however, you have a different version you would like me to use in the multi-worm portion of the tournament, have a special target Sol4 in the makefile that builds that executable, and name the executable sol4.