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
The Driver
class will contain a number of helper methods along with the main()
method. As a general rule, every method should perform exactly one task. If you have multiple tasks that need to be done, a separate helper method should be created for each task. This means that generally the main()
method will consist of declaring and initializing variables, calling helper methods, and handling some of (but not necessarily all of) the exceptions that may arise.
The main()
method for this program will perform the following tasks:
- 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 main()
method will do this by calling the following helper methods:
getInput()
This method will ask the user for three numbers, entered on a single line and separated by spaces and return these values in the same order as they were entered in an array. 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 take as parameters the number of dice to create and the number of sides the dice will have, returning an array ofDie
objects.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.findMax()
This method will take the array that contains the rolling statistics and find and return the largest count. Which value has the largest count is not important here, just what the count is.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 to determine the next value when the Die
is
"rolled". It will have three methods:
- A constructor with a single parameter
numSides
that will set the number of sides for thatDie
. If the number of sides is out of range, anIllegalArgumentException
will be thrown. You should not setcurrentValue
to 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 theDie
must be rolled again before a value can be gotten. IfcurrentValue
is not in the expected range of theDie
, a customDieNotRolledException
will be thrown.roll()
will use theRandom
object to generate a new random value for theDie
and assign it tocurrentValue
Storing the frequencies
To keep track of how many times each value has been rolled, create an int[]
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 Exception
may be thrown by the Virtual Machine while executing as well as a few spots where you will need to throw an Exception
manually. 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
Exception
if the current value is not in range - When getting input from a user, if the wrong type of data is entered, an
Exception
is possible
Bear in mind you do not need to throw every Exception
yourself. Some will be thrown by Java. When and how you handle the Exception
will be for you to determine. Also, please note that if an Exception
is 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 Exceptions
you 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 findMax()
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
If the number of rolls is so few that the scale is 0, set the scale to 1.
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
Your program must run as a .jar
file from the command line
Once the .jar
file is created, move it from the out/artifacts/...
folder into the project folder (same folder as the README.md file) and rename
it lab2.jar
.
Acknowledgment
This laboratory assignment was developed by Prof. Sean Jones.