Back to 111 Main Page

Mobius strip

Assignment 6

Task

Combine everything you've learned so far to write a very simple maze game. (The maze is simple, not the program! Compare to Rogue and NetHack.)

Details

Write a turn-based maze game. The maze is a simple 10x10 square with a single exit. (So it's really just a big room, not a maze.) The player is represented by a single character on the screen. The player starts at a random place somewhere in the maze-room, and the exit is at some random location on the right/east side of the maze-room.

Each turn, print the current map of the maze-room and ask the user which direction they want to move. How you do this is up to you.

The game ends when the player reaches the exit. Print some congratulatory message and end the program.

Examples

Here is what the maze might look like on the screen using '*' for the player, '=' for the exit, and '.' for the room floor. In this example, the player moves north, east, south, or west by inputting the appropriate letter.

..........
..........
..........
...*......
..........
.........=
..........
..........
..........
..........
Enter next move (N/E/S/W):

On the other hand, you might use 'P' for the player, 'E' for the exit, and ' ' for the floor. (' ' works for the floor only if you do the borders extra credit, below.) Here, the player moves by typing in "up", "down", "left", or "right".

------------
|          |
|          |
|          |
|   P      |
|          |
|         E
|          |
|          |
|          |
|          |
------------
Which way do you want to move (up/down/left/right)?

Other Requirements

Use of Constants. In your program, use variables to hold the following details:

  • The width of the maze
  • The height of the maze
  • The characters used to print the player, floor, exit, and any other features of the maze-room.

You should be able to change only the values assigned to these variables in order to change the size, shape, or look of your maze. (Of course, your program should still work correctly after making such changes.)

If you want to use methods, you can declare your constants like this inside your class but outside of any method:

  //constants used in drawing the maze
  public static final int MAZE_WIDTH = 10;
  public static final int MAZE_HEIGHT = 10;
  //...etc...

If you do this, these variables will be accessible from any method.

Instructions to the User. Be sure to explain any necessary rules, important characters, or input requirements in your user interface.

Player Placement and Movement. Place the player and exit randomly at the start of the game. You can use the method Math.random() to do this. Math.random() returns a double between 0 (inclusive) to 1 (exclusive). Be careful not to initially place the player on the exit square. Also, do not let the player move beyond the bounds of the maze.

Error-checking. If the player enters something other than one of the valid movement choices, print an appropriate error message and ask the user to try again. (This does not extend to catching exceptions, however. For example, if you ask for a number and the user enters a string, your program will crash. That is fine at this point in the course. However, if they enter an invalid number, your program should report the error and have them try again until they get it right.)

Coding Standards. You must follow Java Coding Standards while writing the code for this program.

Sample output

Here is some sample output to give you a better idea of how a sample game might look from start to finish:

Move your character (*) to the exit (=).
You may move North, South, East, or West.

..........
..........
..........
..........
..........
.......*.=
..........
..........
..........
..........
Enter next move (N/E/S/W): N

..........
..........
..........
..........
.......*..
.........=
..........
..........
..........
..........
Enter next move (N/E/S/W): e

..........
..........
..........
..........
........*.
.........=
..........
..........
..........
..........
Enter next move (N/E/S/W): e

..........
..........
..........
..........
.........*
.........=
..........
..........
..........
..........
Enter next move (N/E/S/W): e
You can't leave the maze except through the exit!

..........
..........
..........
..........
.........*
.........=
..........
..........
..........
..........
Enter next move (N/E/S/W): quit
Sorry, but "quit" is not a valid direction choice.  Try again.
Enter next move (N/E/S/W): down
Sorry, but "down" is not a valid direction choice.  Try again.
Enter next move (N/E/S/W): d
Sorry, but "d" is not a valid direction choice.  Try again.
Enter next move (N/E/S/W): s

You've made it out of the maze!

Suggested Steps

As long as you satisfy the above requirements for the program (also see Grading, below, to double-check), you can go about solving this problem however you want. However, if you're stuck, here are the steps I'd suggest.

However you choose to go about it, remember to program one step at a time! You should be compiling, running, and testing your program after every few lines you write to make sure everything you've written so far is correct.

  1. Define constant variables for the maze details: width, height, floor, player, exit.
  2. Define a variable for the location of the exit. Since this will always be on the right wall of the maze-room, you really only need the row/y-coordinate. Consider something like this:
    mazeExitY = (int) (Math.random() * MAZE_HEIGHT);
    
    If MAZE_HEIGHT is currently 10, this will set mazeExitY to some random number between 0 and 9.
  3. Define two variables that will hold the player's location. You need an X (column) and Y (row) position of where the player is on the board. These will initially be assigned a random position.

    How you determine the coordinates of your maze-room is up to you. It's generally traditional in graphics to treat the upper-left corner as (0,0). This would make the lower-right corner of the room (MAZE_WIDTH - 1, MAZE_HEIGHT - 1). (The rest of these suggestions assume this system.) However, you could make the lower-left corner your origin, and/or you might want to start indexing at (1,1).

    Remember to try printing out your variables a few times before continuing to make sure you're getting random numbers in the complete range.

  4. Print the maze-room. This is probably the trickiest part of this assignment.
    • First, use a loop to print (one character at a time) a line of MAZE_WIDTH characters using the maze's floor character. This corresponds to a single row on the board/maze-room. (You might want to name the loop counter x for this loop.)
    • Now build a second loop around this first one in order to print each row MAZE_HEIGHT times. (You might want to name the loop counter y for this loop.) At this point, you should be able to print a 2D board/maze-room.
    • Now you can add conditionals within the inner loop to determine what to print based on the current (x,y) position that is being printed. For example, if the current (x, y) matches that of the player's location, print the character that represents the player.
  5. Get the next move from the player.
  6. Update the player's position accordingly. For example, if the player is moving north/up, playerY--; would update their position. However, before moving the character, make sure this doesn't move them off the board/out of the maze.
  7. Move loop. Now you're finally ready to build a loop that keeps asking the player to move until they reach the exit location.

It is recommended you use methods to break up the program into more manageable chunks, but it is not required.

Extra Credit

Once you meet the basic requirements for this maze game, you may add some additional features. Here are a few suggestions:

  • Draw a border around the maze-room. (1 point)
  • Randomly place the exit on any wall of the maze-room, rather than only on the east wall. (1 point)
  • Move the exit each time the player moves. This should be in some predictable manner. For instance, the exit might move up the east wall one space each turn until it reaches the top wall, and then it begins to move down the wall again. (2 points)
  • Add a monster to the room that moves each turn towards the player. Of course, the game ends gruesomely if the monster makes it to the player before the player makes it to the exit. (This might be a better game if you provide two exits to choose from, or a wormhole/teleport option, etc.)(2 points)

You may come up with additional ideas of your own. If you include any extra features, be sure to mention them in your initial class documentation.

Only a total +5 points of EC will be awarded, and only if the required features of the game work.

What to submit

Attach your FirstLast6.java file to an email. (Note the file name. This will probably be a studio program. LastFirst6.java is also acceptable.)

FAQs

How did that double for loop go?
Assuming you defined the necessary constants for MAZE_WIDTH, MAZE_HEIGHT, and FLOOR, this will print out a 2D grid that represents the room:
for (int y = 0; y < MAZE_HEIGHT; y++) {
  for (int x = 0; x < MAZE_WIDTH; x++) {
    System.out.print(FLOOR);
  }
  System.out.println();
}
This just prints the FLOOR for every character. So you will need to add some conditionals (if/else-if/else statements) to determine which character to print out at each square. The loop counters x and y tell you what location you are currently printing. You will need to check to see if that (x, y) location is the same as the player's location (playerX, playerY). If so, print PLAYER. If it's the location of the exit, print EXIT instead. Otherwise, just print FLOOR.
I still don't understand how to print the player and the exit in the maze.
As explained in the previous answer, you need to use some conditionals to determine which single character to print at each location in the room. Here is the basic structure, though you will need to replaces the /* comments */ with the appropriate code:
for (int y = 0; y < MAZE_HEIGHT; y++) {
  for (int x = 0; x < MAZE_WIDTH; x++) {
    if (/* x and y  == playerX and playerY */) {
      /* print the player */
    }else if (/* x and y  == exitX and exitY */) {
      /* print the exit */
    }else {
      System.out.print(FLOOR);
    }
  }
  System.out.println();
}
Note how only one character will be printed each time through the loop(s)--either the player, the exit, or the floor.
Do I have to repeat that map-printing code again after I move the player?
No, you only need the code that prints the map in one place. You will use a loop to return to the map printing code after you have moved the player. In other words, your code should have this basic structure:
while (player has not reached the exit) {

  /*
   * Print the map (using two nested for loops, as shown above
   */

  /*
   * Ask user to move.
   * (Make sure they enter a valid move.
   *  Don't move the player off the map.)
   * Update playerX/playerY to new player location.
   */
}

/*
 * (Loop ended because player finally reached the exit.)
 * Print congratulatory message.
 */
You might move some of this code out of the while loop and into a couple methods, but it's not required. You will still need this basic loop structure somewhere.

Grading

Out of 20 points:

1 - Submission
Follows required submission policies.
2 - Coding Standards
Follows required coding standards
2 - Compiles
1 - Constants
Maze details are defined and used through constants such that changing only the value initially assigned to these constants changes the program accordingly.
2 - Random placement
The player and exit are both randomly placed (though not at the same place).
5 - Prints room
Prints the room, displaying the current location of the player and of the exit.
3 - Player movement
The player can move their character around the maze-room board.
2 - Constrained to board
The player cannot move their character off the board.
2 - User Interface
The UI includes sufficient instructions on how to play the game; errors such as incorrect input are detected and clearly reported.
+5 (max) - Extra Credit
For clearly documented extra features. Only 5 points maximum, and only if all basic requirements have been met.


~ztomasze Index : TA Details: ICS111: Assignment 6
http://www2.hawaii.edu/~ztomasze
Last Edited: 25 Feb 2008
©2008 by Z. Tomaszewski.