Quick Pick (C++ HELP)
Quick Pick (C++ HELP)
The lottery commission wants you to write code in C++ to generate a quick pick lottery ticket. The output should be by standard out (cout) and look something like this…
This program should prompt the user for the number of draws from 1 to 5 using a data validation loop. If the user enters a zero, the program should acknowledge that and terminate, otherwise the program should display 5 blank lines before displaying the lottery ticket with the given number of draws.
Draw – this is a row on a ticket that consists of 6 randomly selected numbers with no repeating values from 1 to 53.
Ticket – this consists of 1 to 5 draws. No ticket will have less than one draw or more than the specified number of draws. Each ticket has a ticket number based on the seed value of the standard C++ random number generator and the number of draws.
There are five blank lines above the “LOTTERY TICKET” heading and three spaces to the left of it. This is important or the ticket will not print correctly on the preprinted forms.
The ticket number is an unsigned integer value used to seed the standard C++ random number generator.
Each number is displayed with cout and a set width of 5 characters, right justified.
Each draw contains non-repeating random numbers from 1 to 53, sorted in ascending order.
There are 6 numbers to a row (6 numbers to a draw).
There is a maximum of 5 rows per ticket (maximum of 5 draws per ticket).
The qpick Header File
The lottery commission is providing you with a header file. You will need to download this to your computer and use it in your program.
Right-click on the icon above and use Save Target As (or Save Link As )and save this file to your computer. To use this file, put it in the same folder with your main.cpp file and put in the following line in your code…
Side note: your program does not have to use the same line numbers as shown. The line numbers are only used in these notes so I can explain parts without having to draw so many red arrows.
The qpick.h file looks like this…
Your program must use these constants and prototypes. You must not change the contents of this file.
MAX_VAL – this is the maximum value on a lottery number. All lottery numbers must be from 1 to MAX_VAL. Currently, MAX_VAL is 53.
NUM_NUMS – this is the number of numbers per draw. Each draw is a row on the lottery ticket. Currently, NUM_NUMS is 6.
MAX_ROWS – this is the maximum number of rows (draws) per ticket. Currently, MAX_ROWS is 5.
Your program must be written in such a way that if any of these values change, your code should still work.
The required functions are as follows:
void quickPick( int row[NUM_NUMS] )
this function will get one quick pick draw and store it in the given array of integers. The draw will consist of non-repeating random numbers using the standard C++ random number generator.
void sortRow( int row[NUM_NUMS] )
this function will take the given integer array and sort the contents in ascending order.
void displayTicket( int ticket[MAX_ROWS][NUM_NUMS],
long long ticketNum )
this function will display a quick pick ticket using the given two-dimensional array. This will only display the number of rows passed to it by the ticketNum parameter.
You must write the code for these prototypes in your main.cpp program. Do NOT change these prototypes. If your function does not match these prototypes, your program will not compile with the qpick.h header file.
Random Number Generator
Your program must use the standard C++ random number generator. This was introduced in chapter 3. To use this generator, you will need the srand(), rand(), and time() functions. You will also need a random number generator seed variable. Only use srand(), rand(), and time() functions and no other random number generator because the lottery machine firmware only supports these functions.
The quickPick() Function
Since the quick pick draw must have non-repeating random numbers, we must keep track of the numbers that were already selected to make sure that they are only selected once. One way to do this is by using a boolean array.
In case you have forgotten, a boolean variable is a variable that can store a true or false value. Internally, a boolean variable is really an integer variable. If the value is zero, the boolean is considered false. If the value is not zero, it is considered true. But for C++ programming, we will use the bool data type (old C programmers used int) and the pre-defined values for true and false as defined in the C++ programming language.
The algorithm for picking a non-repeating random number looks like this…
In the example above, line 50 defines the used array to indicate which numbers were used. This array uses as its index the values from 1 to MAX_VAL. Since MAX_VAL is 53, to get 1 to 53 in an array, we have to use MAX_VAL+1. That is how arrays work. If we did not use +1, we would get 0 to 52. Review the lesson on arrays if you do not see this.
Lines 55-56 sets all values in the used array to false. This is to indicate that no numbers have been used, yet. On line 55, it does not matter if we use i++ or ++i. The result will be the same either way. If you don’t get it, review the lesson on for loops.
Lines 61-69 does the processing to get the non-repeating random numbers. It consists of two loops: a for-loop with a do-while loop inside.
The for-loop, from lines 61 to 69, is used to get NUM_NUMS numbers. NUM_NUMS is the number of numbers in a draw (or row). NUM_NUMS is 6 numbers per draw.
The do-while loop, lines 63 to 65, inside the for-loop, checks to make sure that there are no repeating numbers. It gets a random number from 1 to MAX_VAL on line 64 and if that number is in the used array (line 65), it goes back to 64 to get another random number. It will continue to do this until it finds an unused number.
At first, all numbers are unused because no numbers were selected and all values in the used array are false to indicate such. So, with a random number selected, that number is placed in the row array (line 67) and the used array is set to true (line 68) to indicate that we have used that number.
So when we get the next number, we will have one used number and the way the code works, that number will never be selected again.
Run this program in your head or type it up on the computer to test and run it. This really works to make sure that you never get a repeating random number.
The sortRow Function
Use an algorithm from chapter 8 using the Bubble Sort or Selection Sort. The algorithm in the textbook shows a prototype with a size parameter, but our sortRow() function does not have such a parameter and you are not allowed to change this.
You must write this function using NUM_NUMS instead of the size parameter. NUM_NUMS is a constant defined in the qpick.h header file that you included in your code. So to make this work, start your function with the prototype, without the colon, and continue programming to sort the contents of the given row array parameter with a size of NUM_NUMS elements.
The displayTicket Function
You should be able to display the ticket using the two-dimensional array given in the parameter so that the output will look like this…
The given prototype for this function is…
The ticketNum parameter has the number of rows (aka draws) as the last digit. In this example, 14463617335 is means there are 5 rows because 5 is the last digit of this number. To get the number of rows from the ticket number, use ticketNum%10.
Your output should display five blank lines before displaying the ticket. The headings must be as shown in the example above. The numbers should be displayed using cout and setw to display each number, 5 characters wide.
The algorithm for displaying a two dimensional array looks like this:
FOR i=0; WHILE i<rows; i++
FOR j=0; WHILE j<NUM_NUMS; j++
DISPLAY end of line;
The main Function
Finally, the main function…
You will need to create a function called getDraws that will get the number of draws from 1 to 5 or zero to cancel the transaction.
Line 29 defines the variable that will hold the number of draws that the user will enter from the keyboard on line 34 using the getDraws function. If the user enters zero for the number of draws, the program must end, for example…
Side note: in this example the keyboard input is marked in green, but your program does not have to do this.
When the user enters a number that is not in the valid range, a message “Number of draws must be from 1 to 5” is displayed, but if the user enters a zero, the program must cancel the transation and end as shown on the if statement on line 35.
The ticket number (ticketNum) will be the seed value with the number of draws. For example, if the seed value was 1446365166 and there were 3 draws, the ticket number will be 14463651663. This is calculated on line 41 of the main function code shown above. Note that the ticket number is a long long integer. For a 32 bit program, an int and long int are the same at 32 bits. The maximum value for a 32 bit integer is 2,147,483,648, but the seed value 1,446,365,166 x 10 would make it overflow at 14,463,651,660 so we have to use a long long integer (64 bit) with a maximum value of 9,223,372,036,854,775,808 which is more than enough to handle out ticket number.
Note that the calculation on line 41 looks like this…
ticketNum = seed * 10LL + numDraws;
…and since ticketNum and numDraws are both 32 bit and C++ defaults all integer literals to 32 bit, the result of the calculation would be a 32 bit result even though ticketNum is a 64 bit integer. To force it to calculate in 64 bit, we have to either typecast one of the 32 bit variables to long long (64 bit) or use a 64 bit literal using LL in order to get a proper 64 bit integer result.
In case you haven’t figured it out, to put a digit at the end of a number, multiply that number by 10 and add that digit to the number. So if the seed value was 1446365166 and the number of draws was 3, take the seed value and multiply it by 10 to get 14463651660 then add the number of draws to it to get 14463651663.
This is what the program should display for that ticket number…
The program displays five blank lines before displaying the lottery ticket and only displays three draws.
Make sure to use the constants in your program logic and input prompts. Using the constants makes it easier to update this program when changes have to be made. For example, MAX_ROWS is the maximum number of draws and is currently set to 5, but if MAX_ROWS changes in the future, your program and input prompt must still work. In other words, if I change MAX_ROWS to 6, the input prompts should display “1 to 6” and not “1 to 5” and the logic must work accordingly. Same for the other constants in this program.
Be sure to ask if you have any questions.