Fall 2014, The College of Saint Rose

Lab 9: Simon
Due: 11:59 PM, Sunday, November 23, 2014

For this lab, you will get some practice using ArrayLists by enhancing a class example, then you will use them to complete a (mostly-written) program that plays the children's memory game called Simon.

You may work alone or with a partner on this lab.

Getting Started

Start by downloading the folder containing two starter BlueJ projects. Download and extract this archive and you should see two folders: CourseGrades, which is a copy of the class example you will be extending for the practice program, and Simon, which is the game you will be completing for the programming assignment.

Create a document where you will record your answers to the lab questions. If you use plain text, call it "lab9.txt". If it's a Word document, you can call it whatever you'd like, but when you submit, be sure you convert it to a PDF document "lab9.pdf" before you submit it.

Practice Program: Enhancing the CourseGrades Example

In the starter, open the BlueJ project for the copy of the CourseGrades example, and read through the existing code to make sure you understand how it all works. You will be making several enhancements to this program:

• Add a command to print out a student's average across all course grades. So if a student named Alice had course grades of 78.3, 98.4, and 88.8, the command
```average Alice
```

would print

```Alice has an average of 88.5.
```

Print the average with one digit after the decimal point.

Question 1: Did you add a new field (i.e., instance variable) to the StudentGrades class that stores the average? Why or why not? What would you need to do differently if you chose the opposite approach? (2 points)

• Add a command to delete a student from the system:
```delete Bob
```

• Add a command "stats" to print the student(s) with the highest and lowest overall averages, and the highest and lowest grade for any individual course. Unlike in some previous programs, you need to handle ties here (consider introducing some ArrayLists to keep track of multiple students who had the same "top" scores).

Setting up for Sounds: JFugue

Your second program has the option to use sounds. It uses a library called "JFugue" from David Koelle to make this task easier. Much like objectdraw, this library is not part of a standard Java or BlueJ installation, so you will need to add it.

First, visit http://www.jfugue.org/download.html and download the first file in the list (jfugue-4.0.3.jar). Save this to your account and then add it to BlueJ's list of libraries. You can accomplish this by going into BlueJ's preferences, choosing "Libraries", then adding the path to the JFugue library to the list of User Libraries. After doing this, quit and restart BlueJ so it can load the library correctly.

Make sure you have done this correctly by downloading, compiling and running the SoundPlayerDemo example on the computer where you are doing your work for this lab.

Programming Assignment: Completing the Simon Game

Many of you are probably familiar with the electronic toy named "Simon". Simon is a simple solitaire memory game. The toy is composed of a plastic base with four colored plastic buttons on top. Each button has a different color, and a different musical note is associated with each button. The toy "prompts" the player by playing a sequence of randomly chosen notes. As each note is played, the corresponding button is illuminated. The player must then try to play the same "tune" by pressing the appropriate buttons in the correct order. If the player succeeds, the game plays a new sequence identical to the preceding sequence except that one additional note is added to the end. As long as the player can correctly reproduce the sequence played by the machine, the sequences keep getting longer. Once the player makes a mistake, the machine makes an unpleasant noise and restarts the game with a short sequence.

Your task is to implement two classes that will complete a program to play a simple game like "Simon". Like the original, our game involves four buttons which the player will have to press in an order determined by the computer. We will keep the graphics simple by placing the four buttons in a 2 by 2 grid.

As soon as the buttons are displayed, your program should generate a sequence consisting of a single note/button. It should "play" a sequence by briefly highlighting the buttons that belong to the sequence in order. After a sequence is played, your program should wait while the player tries to repeat the sequence by clicking on the buttons in the appropriate order. If the player repeats the sequence correctly, the program should randomly pick a button to add to the end of the sequence and "test" the player on this new sequence. If the user makes a mistake, the program makes a "razzing" sound and then starts over with a one note sequence.

While this is a complex program with several classes that interact with each other, your task is limited to the management of the "songs" that are played by the Simon game.

Provided Classes

Several classes are provided, most of which you will not need to modify or even look at (unless you wish to do so). The SimonController manages the game, NoisyButton and NoisyButtonListener provide the capability for our big, colorful buttons to be pressable, and the ButtonCollection keeps track of the four buttons and is able to pick one of the buttons it contains randomly.

Classes to be Completed

The Song and SongPlayer classes are where you will need to do your work. A skeleton of each class is provided.

The Song class needs to keep track of the sequence of notes/buttons that makes up the song that the player is trying to match.

• You are to use an ArrayList of NoisyButton objects to store the song.
• Notes are added to the end of the song with the add method.
• The play method creates a SongPlayer to play the current song. As you will see soon, SongPlayer is an ActiveObject that you will be implementing as well. The Song class should pass its ArrayList of NoisyButton objects, and a reference to the SimonController class as a parameter, as that will be needed by the SongPlayer class.

The last three methods are used by the SimonController to keep track of whether the song being "entered" by the player trying to match what Simon played is correct. To do this, your Song class will need to keep track of a "current position" which indicates the next note in the song that should be played to continue to match the song.

• The restart method "rewinds" the song so that the next note to be matched is the first in the array.
• The atEnd method indicates whether the song's current position is at the end of the song. That is, the getNextButton has been called a number of times equal to the length of the song since the last call to restart.
• The getNextButton method returns the NoisyButton representing the note at the current position in the array then advances the current position so that the next call to this method will return the next note. If called when the current position is already pointing beyond the last note of the song, this method should return null.

The SongPlayer class is used to play the current song to the player of the game so he or she has a chance to repeat it back. Since we need to be able to do things like play notes and flash buttons for a given amount of time and pause between the notes, this needs to be an ActiveObject.

The provided code includes all of the instance variables you need and a complete constructor. Your task is to fill in the run method to pause for one second, then play each note in the song. This is done by calling each NoisyButton's flash method. When all of the notes have been played, the run method calls the SimonController's playComplete method to inform the game that it is OK to allow the player to start pressing buttons to try to match the sequence just played.

Fill in these methods. When your Song and SongPlayer classes work properly, you should be able to play Simon. If you have trouble with the sounds or just prefer to work quietly, you can set the PLAY_NOISE constant in the NoisyButton class to false.

You need not comment classes you did not modify, but you should augment the comments in the Song and SongPlayer classes to describe in some detail how they work. You should also make sure you name(s) are in each of those files.