Week of Wednesday, 16 November, 2005
In this lab, you will gain experience programming using two-dimensional arrays. In particular, you will be working on a MapPrinter class, which will print out a map of a world in our game.
Using the procedures in the previous laboratories, copy the files MapPrinter.java to your home directory for your manipulation (right-click and select "save as..."). In addition, you will need to save the following .class files: Map.class, Room.class, Creature.class, Weapon.class, and Descriptions.class.
The TA will spend a bit of time explaining how to use the Map class and the 2-dimensional layout of Rooms within that class. You should read through the lab prior to that explanation.
You will develop the Map class in HW J8. In the meantime, we have provided the Map.class file, which is a fully working version of what you will develop in J8. The relevant methods that are used in this lab are as follows.
Map (int cols, int rows): This specific constructor will create a map of the specified dimensions, and use a random seed to start the random number generators.
Map (int cols, int rows, int seed): Similar to the previous constructor, except this one specifies the random seed. We provide the seed of 3 in the MapPrinter.java file, which means that the map that is generated is the exact same each time -- this helps with debugging your code. If you wanted a different map each time, you would use the previous constructor.
void populate (int weaponPercent, int monsterPercent): This method will go through each room, and possibly give it a weapon and/or a creature. Each of the parameters is between 0 and 100, and specifies the percentage chance that any given room will have a weapon or a creature. Thus, if each was 50, then each room would have a 1 in 2 chance of having a weapon (and the same for a creature). In our main() method in MapPrinter.java, we use the value of 25 for each -- thus, each room has a 1 in 4 chance of having a creature (and the same for an item).
void generateMaze(): This method generates the maze, connecting the rooms in some manner that will be discussed in HW J8. The connections are doorways -- thus, not all adjacent rooms are connected to each other, as shown below.
Room getRoom (int col, int row): This method allows you to get a particular Room from the Map. Although the Map represents the world by a 2-dimensional array, that array is private. Thus, to get ahold of a particular Room in the map, you call this method.
Your task is to complete the MapPrinter.java file. There are two required methods, each of which prints out a map of the current world.
This method should go through the entire Map, and print out a single character for each room. The following characters are potentially printed:
For the map provided by the main() method in the MapPrinter.java file, the resulting map is as follows.
X W WWWW W WM W W M M WB
This may make a bit more sense if we put it into a table:
Because we set the random seed at 3, it will generate the same map each time. Thus, if yours does not look like the above, you have a bug somewhere -- ask a TA! Note that the main() method told the printSimpleMap() method that the player is in the upper-left hand corner of the map. If you were to change the height and width each to 10, and keep the random seed at 3, you would get the following map:
X W WMWW W M B WWW B W WW MM W M M WM M W W W M WW W M M MMM WWBM MM M
How to start: Your printSimpleMap() method will need nested for loops. The outer one will go through each row, while the inner one will go through each column. The inner one will print out the specific character via the System.out.print() method (as all the rooms in a given row need to be on the same line). Once each row is completed, then you move to the next line via the System.out.println() method.
The printSimpleMap() method is useful, but it does not tell us which rooms are connected to each other. In particular, from any given room, you can not necessarily go between them, as there may not be doors present. Thus, we are going to enhance our printSimpleMap() method to add door information. If there is a doorway between two rooms next to each other (i.e. a east-west doorway), then we will print a '-' (dash) between the rooms. If there is a doorway between two rooms on top of each other (i.e. a north-south doorway), then we will print a '|' (vertical bar) between those two rooms. Thus, our original 6x6 map will look like the following when finished:
X- -W - - | | W-W W W- - | | | | W W-M | | | | | -W | | | | | | W M | | | | | M- - -W B-
Note that this is the same map as above -- the method is just printout out the doorway information this time. The 'X' tells us that the player's current location is in the upper-left corner. From there, s/he can head south, then east, then south, then west, etc.
To print the dashes for the east-west doors, you will most likely want to use the getRoomToEast() method, which will return null if there is no doorway present. We are assuming that if there is a doorway going one way, then there is a doorway going the other way (so the situation with the Pit in HW J7 will not occur here). Thus, after printing the character for each room, you will either print a space (if there is no doorway) or a dash (if there is a doorway). Thus, the code (so far) is the same as the printSimpleMap() method, with the addition of a character after each room, depending on whether there is a door to the east of a given room. It will be easiest to make sure this is working before you continue to the north-south doors. The 6x6 map with only east-west doors will look like the following.
X- -W - - W-W W W- - W W-M -W W M M- - -W B-
To print the north-south doorways, you will most likely need to use the getRoomToSouth() method, which also returns null if there is no doorway present. Again, we are assuming that all doorways go in both directions. After the for loop that prints out a line of rooms, you will need a separate for loop to print out a line of spaces (if there is no doorway) or vertical bars (if there is a doorway). This for loop is still within the outer for loop, but separate from the inner for loop used above. Note that between each doorway character (space or vertical bar) there is an additional space (so that it lines up with the east-west doorway). Thus, in this for loop, you either print out two spaces (if there is no north-south door) or a vertical bar and a space (if there is a north-south door). The extra space is so that the north-south doors line up with the rooms above and below (because of the east-west doors, the rooms are now every other spot).
A 10x10 map with a random seed of 3 will look like the following.
X -W -W-M-W-W- - | | | | | W- - - -M -B | | | | | W-W-W - B W | | | | | | | W-W- M-M- -W | | | | | - -M -M- W-M | | | | | M- - W W- W | | | | | | | - -M W W- - | | | | | | W- - M- -M | | | | | | | - - -M M M | | | | | | W-W-B M- -M-M- -M