Lab 2: Exceptions
Overview
This lab will focus on handling and using Exception objects in a program with a Driver and a custom class.
Additionally, we will be creating our own custom Exception class to handle an issue specific to our custom class.
The program will be performing an experiment to verify the frequency of values generated by rolling a certain collection of dice.
Pre-Lab (DUE BEFORE LAB - see due date in Canvas)
As part of the pre-lab activity you must ensure that you have accepted the assignment in GitHub Classroom and cloned your repository to a new project in IntelliJ on your computer.
Assignment
Driver class
The provided Driver class will call the run() method of the DiceApp class to begin the program execution.
DiceApp class
The run() method for this program will perform the following tasks:
- Print an introductory message to the user explaining the experiment.
- Get input from the user regarding how many dice will be rolled, how many sides the dice will have, and how many times the dice will be rolled.
- Store the results of the user input in an array
- Create the dice described in the user input
- Roll all the dice and store the result as many times as the user has requested
- Find the result that appeared most frequently during all the rolls
- Print the results of the experiment
The run() method will do this by calling the following helper methods:
intro()This method will print out instructions for the user.getInput()This method will ask the user for three numbers, entered on a single line and separated by spaces and store these values in the appropriate instance variables. These numbers will be:- The number of dice to roll in the experiment
- The number of sides these dice will have
- How many times the dice will be rolled
createDice()This method will create the correct number of dice with the correct number of sides the dice will have, storing it in the appropriate instance variable.rollDice()This method will roll all the dice, total up the values, and add to that value's total. It will do this as many times as the user specifies.findMaxIndex()This method will find and return the index inrollsof the largest count.report()This method will print the results as a horizontal bar chart using asterisks. See below for more details.
If at any time during the execution of the program an exception halts the program, an appropriate message will be printed to the console and the program will return to step 1 (getting input from the user) and ask the user for input. Once the program successfully completes, it will end.
Die class
The Die class will keep track of the number of sides on the Die, which should be between 2-100 inclusive, and whatever the current value of the top side of the Die is. It will also use a Random object called random to determine the next value when the Die is
"rolled". It will have three methods:
- A constructor with a single parameter
numSidesthat will set the number of sides for thatDie. If the number of sides is out of range, anIllegalArgumentExceptionwill be thrown. You should not setcurrentValueto anything in the constructor. getCurrentValue()which will return the last value generated by rolling theDie. It will also reset the current value to 0, so that theDiemust be rolled again before a value can be gotten. IfcurrentValueis not in the expected range of theDie, a customDieNotRolledExceptionwill be thrown.roll()will use theRandomobject to generate a new random value for theDieand assign it tocurrentValue
Storing the frequencies
To keep track of how many times each value has been rolled, we will create an int[] rolls where each index in the array will correspond to a value in the possible range for the number of sides and the number of dice.
For example, two 6-sided dice will have the value range 2-12, inclusive. This means you would create an int[]of length 11 (the total possible number of distinct values) and initialize all the indexes to 0. You would then use the indexes to hold a count for each of possible values, so index 0 would hold the number of times a 2 was rolled, index 1 would hold the number of times a 3 was rolled, etc. Below is an illustration of how it would look.
| Index | Value |
|---|---|
| 0 | 2 |
| 1 | 3 |
| 2 | 4 |
| 3 | 5 |
| 4 | 6 |
| 5 | 7 |
| 6 | 8 |
| 7 | 9 |
| 8 | 10 |
| 9 | 11 |
| 10 | 12 |
Whenever you roll a new value, increment the index that corresponds to that value. For example, if you were to roll a 6, you would increment the value at index 4. When the rolling is finished, each index should contain the number of times the corresponding value was rolled.
Exception Handling
There will be various places where an Exceptionmay be thrown by the Virtual Machine while executing as well as a few spots where you will need to throw an Exceptionmanually. Specifically
- If there is ever a time you will need to enforce a specific range of values, you will likely need to validate the given value and throw an
Exceptionif the current value is not in range - When getting input from a user, if the wrong type of data is entered, an
Exceptionis possible
Bear in mind you do not need to throw every Exceptionyourself. Some will be thrown by Java. When and how you handle the Exceptionwill be for you to determine. Also, please note that if an Exceptionis not something that can be handled or fixed while the program is running, it should not be caught and allowed to crash the program.
Some Exceptionsyou may end up using would be IllegalStateException, IllegalArgumentException, InputMismatchException, and NumberFormatException, along with your custom DieNotRolledException
Your program will be expected to generated output that matches the sample output shown below. Note your actual values will differ, but the formatting and error messages should be identical.
Report Formatting
Your report format should match the sample output format exactly, though the values themselves will be different. The spacing and justifying should be handled by formatting the output String either through the printf() command or the String.format() command. You should not attempt to hard-code spacing.
You will use the findMaxIndex() method to determine what the scale of the report will be. Each asterisk will represent roughly 10% of the max value, so the value with the highest count will have 10 asterisks and the rest will scale down based on the max value, using the following equation to calculate how many asterisks to print for each value:
// scale is how many rolls is 10% of the max
scale = maxNumRolls / 10
// Number of asterisks for a value is the number of rolls divided by the scale
numStars = numRolls / scale
Sample Output
Please enter the number of dice to roll, how many sides the dice have,
and how many rolls to complete, separating the values by a space.
Example: "2 6 1000"
Enter configuration:2 6
Invalid input: Expected 3 values but only received 2
Please enter the number of dice to roll, how many sides the dice have,
and how many rolls to complete, separating the values by a space.
Example: "2 6 1000"
Enter configuration:2 101 10000
Bad die creation: Illegal number of sides: 101
Please enter the number of dice to roll, how many sides the dice have,
and how many rolls to complete, separating the values by a space.
Example: "2 6 1000"
Enter configuration:2 6 fff
Invalid input: All values must be whole numbers.
Please enter the number of dice to roll, how many sides the dice have,
and how many rolls to complete, separating the values by a space.
Example: "2 6 1000"
Enter configuration:3 6 100000
3 :454
4 :1368 *
5 :2757 **
6 :4714 ***
7 :6922 *****
8 :9821 *******
9 :11601 *********
10:12413 *********
11:12555 **********
12:11521 *********
13:9697 *******
14:6856 *****
15:4661 ***
16:2770 **
17:1396 *
18:494

Acknowledgment
This laboratory assignment was developed by Prof. Sean Jones.