The program: Rogue

(This PA is adapted from the same assignment from COS 226 at Princeton University)

  • First milestone due April 11 (Tue.), 2017, 11:59pm
  • Final milestone due May 11, 2017, 11:59pm

This assignment was developed by Andrew Appel and Kevin Wayne. Copyright 2004.

Files

Change logs

  • Milestone #1 solution update (rogue-M1-v2.7z), April 25
  • Milestone #1 solution posted, April 25
  • Milestone #2 is updated on April 11
  • Rubrics for milestone #1 is updated with more specific details on March 5, 2017, at 3:26 PM
  • Assignment created on February 28, 2017, at 11:16 AM

Description

Design and implement an effective strategy to seek out and intercept a moving adversary. Design and implement an effective counter-strategy to avoid being intercepted by such an adversary.

Historical perspective

In the late 1970s, Ken Arnold designed a C library (later to be named curses) that enabled the user to put a character at a specific location on the screen, enabling a crude form of interactive graphics. While experimenting with this new library, Michael Toy and Glen Wichman, designed a graphical adventure game coined Rogue. The purpose of Rogue is "to descend into the Dungeons of Doom, defeat monsters, find treasure, and return to the surface with the amulet of Yendor using its levitation capabilities." This revolutionary game became the undisputed most popular game on college campuses after it was included in BSD Unix 4.2 in 1980. It would later spawn the role-playing game (RPG) genre, including its direct descendant NetHack.

In 1984, a group of grad students at CMU developed a computer program named Rog-o-matic to automatically play the game of Rogue. At one time, the Rog-o-matic player was the highest rated Rogue player at CMU. A crucial component of the Rog-o-matic algorithm was to avoid contact with the monster for as long as possible, so that the your health could regenerate before confronting the monster in a battle to the death. This involves an interesting graph search problem, and is the inspiration for this programming assignment.

Rules of the game

The game of Rogue is played on an N-by-N grid that represents the dungeon. The rogue (typically a human player) is represented with the character @. The monster is represented by an uppercase letter. (In the real game of Rogue, there are 26 different monsters named A through Z, each with different capabilities.) The monster and rogue take turns making moves, with the monster going first. If the monster intercepts the rogue (occupies the same site), then the monster burns/freezes/bludgeons the rogue to death, and the game ends. In each turn, a player either remains stationary or moves to an adjacent site. There are three types of sites: room, corridor, and wall, and they are represented by '.', '+', and ' ', respectively. If the player is in a room site, then they can move to an adjacent room site in one of the 8 compass directions (N, E, S, W, NW, NE, SW, SE) or a corridor site in one of the 4 directions (N, E, S, W). If the player is in a corridor site, then they can move to an adjacent room or corridor site in one of the 4 directions (N, E, S, W). The walls are impenetrable.

          + + + + +
          +       +
. . . . . . . .   +
. . . . . @ . .   +
. . I . . . . .   +
. . . . . . . .   +
. . . . . . . .   +
          +       +
          +       +
          + + + + +
. . . . . . . . A .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . @ . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .

In the first dungeon above, the rogue can avoid the Ice Monster I indefinitely by moving N and running around the corridor. In the second dungeon, the Aquator Monster A can use the diagonal moves to trap the rogue in a corner.

Monster's strategy

The monster is tenacious and its sole mission is to chase and intercept the rogue. A natural strategy for the monster is to always take one step toward the rogue. In terms of the underlying graph, this means that the monster should compute a shortest path between itself and the rogue, and take one step along such a path. This strategy is not necessarily optimal, since there may be ties, and taking a step along one shortest path may be better than taking a step along another shortest path. For example, in the first dungeon below the Bat Monster's only optimal strategy is to take a step in the NE direction. Moving N or E would enable the rogue to make a mad dash for the opposite corridor entrance.

    + + + + + + + +
    +             +
. . . . . . .     +
. . . . . . .     +
. . . . @ . .     +
. . B . . . .     +
. . . . . . .     +
. . . . . . . + + +
. . . . . . .      
. . . . . . .      

This dungeon,the corridor does not form a loop so the Bat Monster can trap the rogue inside.

    + + + + +  
    +             
. . . . . . .     
. . . . . . .     
. . . . @ . .     +
. . B . . . .     +
. . . . . . .     +
. . . . . . . + + +
. . . . . . .      
. . . . . . .      

In the dungeon below, the Centaur Monster can guarantee to intercept the rogue by moving E.

          + + + + +
          +       +
. . . . . . . .   +
. . . . . . . .   +
. . C . . @ . .   +
. . . . . . . .   +
. . . . . . . .   +
          +       +
          +       +
          + + + + +

Rogue's strategy

The rogue's goal is to avoid the monster for as long as possible. A naive strategy is to move to an adjacent site that is as far as possible from the monster's current location. It is easy to see that this strategy may lead to a quick and unnecessary death, as in the second dungeon below where the rogue can avoid the Jabberwock Monster by moving SE. Another potentially deadly strategy would be to go to the nearest corridor. To avoid the Flytrap Monster, the rogue must move towards a northern hallway.

A more effective strategy is to identify a sequence of adjacent corridor and room sites which the rogue can run around in circles forever, thereby avoiding the monster indefinitely. This involves identifying and following certain cycles in the underlying graph. Of course, such cycles may not always exist, in which case your goal is to survive for as long as possible.

+ + +              
+   +              
+ + +              
  . . . .          
  . . . .          
  . . . .          
  . . . . + + + + +
  @ . . . +       +
  . . . . + + + + +
  . . . F   
. . . . . . .      
. . . . . . .      
. . . . . @ .      
. . . . . . . + + +
. . . . . . .     +
. . . . . . . + + +
. . . . . . J      
. . . . . . .      
. . . . . . .      
. . . . . . . 

Input format

The input dungeon consists of an integer N, followed by N rows of 2N characters each.

10
    + + + + + + + +
    +             +
. . . . . . .     +
. . . . . . .     +
. . . . @ . .     +
. . B . . . .     +
. . . . . . .     +
. . . . . . . + + +
. . . . . . .      
. . . . . . .  

A room is a contiguous rectangular block of room sites. Because of dungeon construction safety requirements, rooms may not connect directly with each other. That is, any path from one room to another will use at least one corridor site. There will be exactly one monster and one rogue, and each will start in some room site.

The rogue game engine

So that you can concentrate on the strategy part of the program, we provide some of the infrastructure. Your task is to write programs in Rogue.java and Monster.java that have the following interface.

public Monster(Game g) // create a new monster who is playing a game g
public Site move() // return the adjacent site to which you are moving and an analogous program Rogue.java.
public Rogue(Game g) // create a new rogue who is playing a game g
public Site move() // return the adjacent site to which you are moving

Program Game.java reads in the dungeon from standard input and does the game playing and refereeing. It has three primary interface functions that will be needed by Rogue.java and Monster.java.

public Site getMonsterSite() // return the site occupied by the monster
public Site getRogueSite() // return the site occupied by the rogue
public Dungeon getDungeon() // return the dungeon

Program Dungeon.java represents an N-by-N dungeon.

public boolean isLegalMove(Site v, Site w) // is moving from site v to w legal?
public boolean isCorridor(Site v) // is site v a corridor site?
public boolean isRoom(Site v) // is site v a room site?
public int size() // return N = dimension of dungeon

Program Site.java is a tiny data type that represents a location site in the N-by-N dungeon.

public Site(int i, int j) // instantiate a new Site for location (i, j)
public int i() // get i coordinate
public int j() // get j coordinate
public int manhattan(Site w) // return Manhattan distance from w

To hand in

You will submit on blackboard.

  • Your submission should include your (well organized and well commented) source cod
  • Complete README.txt
  • You should include both source code and a binary called "310pa2.jar".
  • A terminal session showing you running your program with sample input that will be posted on this website
  • Your should zip all the files in a file called "PA2.Firstname.Lastname.zip"
  • Your TAs should be able to run your program by typing: "java -jar 310pa2.jar"

Rubrics

For your first milestone
  • Only classes in Java Collection Framework are allowed in your code. You should implement your own tree or graph data structure if needed.
  • Your monster should be able to find the shortest path from its current location to the current location of rogue and moves toward the rogue 40%
  • Your rogue should be able to greedily move away from the monster, always move in to a loop corridor if the rogue is near the entrance 45%
    • In every move, the rogue should move to a site that is furthest away from the monster
    • In every move, if the rogue can move into a loop corridor and the monster is not inside the corridor, the rogue should move into the corridor.
  • Design an interesting dungeon at least 10x10 in size and explain why it is interesting 5%
  • README.txt 5%
  • Code organization/comments 5%
  • Total points: 100
For your second milestone (optional)
  • Only classes in Java Collection Framework are allowed in your code. You should implement your own tree or graph data structure if needed.
  • Design intelligence of your monster that can catch the rogue from the first milestone (of my implementation)
    • One bonus point for catching the rogue in a given dungeon
  • Design intelligence of your rogue that can escape from the monster from the first milestone (of my implementation)
    • One bonus point for escaping from the monster forever in a given dungeon
  • README.txt
    • Your readme file must clearly state% the strategies you have implemented for the monster and rogue. No bonus points will be provided if you do not provide enough detail and your TA cannot understand your implementation.
    • Your code should be well organized and commented so your TA can understand your implementation
  • 15 new dungeons will be revealed after the deadline and used to test your code
  • The bonus points will be added to milestone #1 (however, you total score from all programming assignment is still capped at 50%)
  • Total bonus points: 30