Project 5: A Baffling Assignment

Baffle is a game that was given to Wisconsin CS 1 students in the early 80's. At different schools, I have also used this as a project.   However, I only asked students to write a text-based version of the game.

I decided to update the project for graphics usage. However, doing the entire project yourselves would be way too much to ask.  Consequently, I've written a GUI applet of the game for you. My solution shows the working game (note: this will not work properly when viewed on a mac).  The same GUI applet with a stub game is provided as your starting point. This version actually requires less work than the original text version but you will have to create methods that meet my requirements for the GUI.

Note for mac users: I built the GUI interface at home using my Windows machine. On the Mac, you can't effectively change the background color of a button. So, instead, I used foreground coloring  for the Mac version. I revised the foreground color scheme 0n 04/23 so that the colors are easier to see. It's still not as clear as the window version but it'll suffice.

The Mac version of the starting point

The Mac version of the working game (For some reason, this game does not display correctly when using Internet Explorer or Netscape; however, it works fine if you use Safari).


The Game:

Baffle is a game that consists of a "black" box with numbers on all sides as shown below.  Hidden inside the box are five
double-sided reflective surfaces (called baffles).  The object of the game is to figure out where the baffles are.  To gain information about the location of the baffles, you can fire a laser beam into one of the locations and observe where it exits the box.  If the beam doesn't encounter a baffle then it will exit directly on the other side.  If the beam encounters a baffle, the beam will be deflected at a right angle -- to its left or right, depending on the direction of the baffle.  The game is scored by giving one point for each shot and two points for each incorrect guess. Obviously, a lower score is more desirable.

It is somewhat arbitrary to associate a left baffle with \. Beams shot from above (or below) deflect the beam to its left. On the other hand, beams shot from the left or right deflect the beam to its right. However, you can think of the left baffle as a char that leans to the left. Also, since \ is the escape character in Java, you must represent the left baffle as the character '\\'

Under normal circumstances, you would use a random number generator to position the baffles.  However to make it easier to test the correctness of the program,  the first game that your program plays must have five baffles placed in the following locations (using the standard row, column locations)

<0,9> = '\'
<4,2> = '/'
<6,0> = '\'
<8,2> = '/'
<8,7> = '\'
After the first game, your random number generator can select the baffle locations.

Textually, the screen (with baffles shown) would look like the display below. Notice that the labeling for the game edges does not correspond to the standard computer-based row & column numbering.

  10 11 12 13 14 15 16 17 18 19
9  .  .  .  .  .  .  .  .  .  \  20
8  .  .  .  .  .  .  .  .  .  .  21
7  .  .  .  .  .  .  .  .  .  .  22
6  .  .  .  .  .  .  .  .  .  .  23
5  .  .  /  .  .  .  .  .  .  .  24
4  .  .  .  .  .  .  .  .  .  .  25
3  \  .  .  .  .  .  .  .  .  .  26
2  .  .  .  .  .  .  .  .  .  .  27
1  .  .  /  .  .  .  .  \  .  .  28
0  .  .  .  .  .  .  .  .  .  .  29
  39 38 37 36 35 34 33 32 31 30
Given the above baffle locations, a beam shot from 7 would go out at 22 without being deflected. A beam shot from 5 would come out at 12 after 1 deflection.  A beam shot from 1 would be deflected twice and exit at 24. Given the baffle placements, there are only 1 or  2 deflection laser shots but higher numbers would be possible given random settings.

To keep the game simpler to write, laser beams can only be shot from the left or from the top. This doesn't really seem to detract from the game. For the above game, the only visually undetectable baffle (from left and top) would be one that is placed at row "3" column "2" - a smart player would recognize this after finding the other baffles and examing all shots.

Here is the windows version of the GUI version of this game after the player has guessed three baffles (in red) and has quit (so the other 2 baffles are displayed - in magneta).





Playing the GUI Game:

Making laser shots:

By clicking the mouse on one of the edge buttons on the left or top of the game, a laser beam is shot into the grid. In the example below, button 8 was clicked (appearing in blue) and the exit location (14) is displayed in cyan. Unless the random game placement of baffles was strange, there is likely a '/' at the intersection of row "8" and column "14". Every laser shot increases the "Shots" count by 1.

Making baffle guesses:

By clicking the mouse on a button in the grid, a right (/) baffle is first placed in the location (and the location turns red). Clicking the same button again, will toggle it to the left (\) baffle. A third click deselects the box. After  a box is selected, clicking the "Make Guess" button, indicates that the player is making a guess.

If the guess is correct, the grid button stays as it was. If the guess is incorrect, the button returns to the inactive state and the "Guesses" score is increased (by 2). If this guess finds the final baffle, the game is over and the "Quit Game" button changes to a "New Game" button.

Quit Game:
By clicking the "Quit" button, the player gives up on a current game. In this case, all baffles will be displayed. For the GUI, discovered baffles show up in red and undiscovered baffles show up in magenta. Once this button is pressed, the only logically active button is the "New Game" button.
New Game:
By clicking the "New Game" button, a random game will be created and the screen will be refreshed.

The stub Baffle Game:

Your job is to write the game itself. In the starting point program, I've provided the framework of the Baffle.java class (using stubs) that is needed by my GUI program.  In a sense, I've provided the interface that is needed for the GUI game to work.
Technically speaking, I cannot provide an interface for Baffle because interfaces cannot have constructors. Instead, I could have created an abstract class AbstractBaffle. If we had talked about such things, you could have derived  the Baffle class from AbstractBaffle (i.e., your  Baffle class would inherit (& override) the methods of the class AbstractBaffle).
The Baffle class has a number of  required public methods and you will probably want to create additional private (helper) methods to accomplish the major (but not the only) tasks which are
public Baffle (boolean fixed)
The constructor requires a boolean that, if true, will play a specific game (mentioned above). The GUI creates its first game with fixed true. The GUI creates subsequent games (with fixed false) in order to create randomly generated baffle placements. The game is assumed to use a 10x10 grid and that 5 baffles will be placed in it.
public boolean guess (int r, int c, char d)
This method makes a guess that row r, column c contains a character d representing a baffle. The method returns true if and only if this is the case and that baffle has not already been discovered.
public int beam (int hole)