Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string>
- #include <sstream>
- #include <iostream>
- #include <time.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- #include <conio.h>
- using namespace std;
- //----------------------------A FANTASTICAL LOTTERY GAME BY THE AMAZING MIGUEL------------------------------
- // --------------------------------------------------------------------------------------------------
- // ------------------------COMES WITH FUNCTIONS AS STANDARD--------------------------
- // --------------------------------------------------------
- // ------------------------
- /*
- This is a simple lottery game by Michael Brandon. It is made to demonstrate the use of arrays and functions.
- Key features include:
- -The ability to choose 1-10 lines per ticket
- -Dynamically allocating the memory for array storing the user's ticket,
- and deleting that array from memory before creating a new one when changing the length
- -The option of re-using the same numbers or creating a new ticket. Re-using does not delete the array
- and the player cannot re-use a ticket if their wallet does not contain enough money for that many lines.
- -Input goes to string first, then checks if it can convert into the integer variable it is needed for.
- This prevents the program breaking into an infinite loop if the user accidentally types a character into an integer.
- -Array checking for both the ticket (per line) and the balls (including the bonus ball), that prevent any duplicate numbers
- from happening when they should not, and that they are generated between specific values, defined by a single global variable,
- and as mentioned above, prevents characters from being input, and prevents the user or the machine creating a value greater or
- lower than the amount allowed, referencing a global variables that mean I can generate numbers between 1-49 as intended, or 1-500.
- These values are also used when requesting input from the player, so changing the range of valid numbers still outputs correct
- information to the player.
- -Bubble sort applied to each line on the players ticket, meaning that the player's numbers print in ascending order per line.
- -Very few global variables, and only ONE that is ever affected by the running of the program,
- makes it much easier to debug, and easy to edit the value of the globals to make the game easier or harder.
- -Sleep funtion at certain places to make it easier to follow the progress of the game and also to add tension. The ball generator
- also uses the random function to pause a random amount within a certain range to increase inpredictability. All pauses reference a
- single global variable, meaning I can scale or entierly remove all pauses in the game by editing a single value.
- -Compare function that compares the 6 numbers on each line with the random numbers and the bonus ball, and assigns a score to a
- score array, as long as the number of lines the player is playing with. 10 points are won for a normal match, plus 1 point for
- matching a bonus ball. So a line with two matches would score 20, and four number plus a bonus ball would score 41. These scores
- are simply read by a number of if statements, and adds the winnings, if any, together, and tells the user how much they won,
- before adding the winnings into their wallet.
- */
- //chickity-check my globals yo
- const int BetLow (1); //minimum guess and ball value
- const int BetHigh (49); //maximum guess and ball value
- const char Pound = 156; //to use pound symbol in cout
- unsigned int Wallet (10); //Global wallet amount, only affected after user prints a whole ticket (removes £1 for each line) and when collecting winnings, if any
- // _________________________________________
- const int Payout2 (1); //2 balls |
- const int Payout3 (10); //3 balls |
- const int Payout4 (100); //4 balls |
- const int Payout4B (500); //4 balls and bonus |===P-p-pick up your p-prizes!!
- const int Payout5 (2500); //5 balls | (this does not follow official
- const int Payout5B (190000); //5 balls and bonus | Lottery prizes, as you would
- const int Payout6 (4000000); //JACKPOT DING DING DING __| never win a thing otherwise!)
- const float pause (1000); //default time to pause, can be adjusted per pause using operators, default 1 second
- bool running = true; //flag used to end program
- //----------------------------------------ENTER NAME--------------------------------------------
- string EnterName()
- {
- string input;
- cout << "Please enter your name:\n";
- cin.clear();
- cin >> input;
- return (input);
- }
- //----------------------------------------CHOOSE NUMBER OF LINES--------------------------------
- int Ticket()
- {
- int Lines = 0; //set number of lines to default of 0 upon entering this function
- int flag = 1; //break loop when unflagged
- do //loop breaks when number is found to be valid and unchecks the flag
- {
- cout << "\n\nHow many lines would you like to play with? (1-10)\n";
- string input = "";
- cin.sync();//does nothing ><
- cin >> input;
- stringstream myStream(input);
- if(myStream >> Lines)
- {
- if(Lines < 1 || Lines > 10) //feedback to player if they pick less than 1 or more than 10 lines
- {
- cout << "Must be between 1 and 10!\n\n";
- }
- else if(Lines > Wallet && Wallet > 1) //feedback if player cannot afford this many lines
- {
- cout << "You do not have enough money for this many lines! You can afford up to " << Wallet << " lines!\n\n";
- }
- else if(Lines > Wallet && Wallet == 1) //as above, correcting pluralisation for just £1
- {
- cout << "You do not have enough money for this many lines! You can only afford " << Wallet << " line!\n\n";
- }
- else
- {
- flag = 0;
- }
- }
- else
- {
- cout << "Must be a valid number between 1 and 10!\n\n";
- }
- }
- while ((Lines < 1 || Lines > 10 || Lines > Wallet) && (flag = 1));
- return Lines;
- }
- //----------------------------------------CHOOSE SIX NUMBERS PER LINE, BUBBLE SORT, AND PRINT---
- int Input(const int Lines, int **Guess)
- {
- cout << "\n\nPlease choose your lucky numbers: (" << BetLow << "-" << BetHigh << ")\n";
- Sleep(pause / 2);
- for (int Line = 0; Line < Lines; Line++)//loop per line
- {
- cout << "Line " << Line + 1 << " of " << Lines << ":\n";
- for(int n = 0; n < 6; n++)//loop per number on a line
- {
- bool duplicate = false;//flag for duplicates, will re-request input until this stays false
- do
- {
- string input = "0";
- cout << n + 1 << ")\t";
- cin >> input; //cin goes to input string first
- stringstream myStream(input); //puts input string into myStream of type stringstream
- if (myStream >> Guess[Line][n]) //if stringstream detects that myStream can go into the array as an int type variable...
- { //then loop continues as normal
- if (Guess[Line][n] < BetLow) //can't bet below 1
- {
- cout <<"Too low, try again! (" << BetLow << "-" << BetHigh << ")\n\n";
- Sleep(pause / 2);
- }
- else if (Guess[Line][n] > BetHigh) //can't bet over 49
- {
- cout << "Too high, try again! (" << BetLow << "-" << BetHigh << ")\n\n";
- Sleep(pause / 2);
- }
- if(n > 0)//checking for dupluicates, does not need to occur on first value
- {
- duplicate = false;//first set flag to false
- for(int count = 0; count < n; count++)//for each number on this line, upto the number before THIS one...
- {
- if(Guess[Line][n] == Guess[Line][count])//if This number matches checked number...
- {
- duplicate = true;//flag for re-entry is set to true
- cout << "You already have this number, please try again!\n\n";
- Sleep(pause / 2);
- }
- }
- }
- }
- else //else, stringstream CAN'T put myStream into the array...
- {
- cout << "\nInvalid number, please try again\n\n";//when invalid, number will not be between the required values, so loop for this number will not break
- Sleep(pause / 2);
- }
- }
- while((Guess[Line][n] < BetLow || Guess[Line][n] > BetHigh) || (duplicate == true));
- }
- }
- //--------------------------------BUBBLE SORT CODE-------------------------------------
- for(int Line = 0; Line < Lines; Line++)//for each line
- {
- bool swap = true;//flag, for detecting if a swap occured each iteration
- do
- {
- swap = false; //sets flag to false so loop only runs once, or until no swaps are detected.
- for (int sort = 0; sort < 5; sort++)
- {
- if(Guess[Line][sort] > Guess[Line][sort+1]) //if this number is greater than the next
- {
- int temp;
- temp = Guess[Line][sort+1]; //swap elements using temp data storage
- Guess[Line][sort+1] = Guess[Line][sort];
- Guess[Line][sort] = temp;
- swap = true; //indicates that a swap occurred.
- }
- }
- }
- while(swap);
- }
- //------print ticket-------
- cout << "\n\nYou picked:\n";
- Sleep(pause / 4);
- for (int Line = 0; Line < Lines; Line++)
- {
- for(int n = 0; n < 6; n++)
- {
- cout << "\t-" << Guess[Line][n] << "-";
- }
- cout << endl;
- }
- Sleep(pause * 2);
- }
- //----------------------------------------RANDOM NUMBER GENERATOR-------------------------------
- void Generate(int Ball[], int &BonusBall)
- {
- Sleep(pause * 1);
- cout << "Lets get those balls rolling...\n\n\t";
- srand ( time(NULL) );//sets random seed based on time
- bool duplicate = false;//flag for duplicates, provides same function as when used in Input
- //-----generate 6 random balls------
- for(int n = 0; n < 6; n++)
- {
- Sleep(pause * (rand() % 2 + 1.5));//pause a random amount of time
- do
- {
- Ball[n] = rand() % BetHigh + BetLow;
- duplicate = false;
- if(n > 0)//check for duplicates except one first ball
- {
- for(int count = 0; count < n; count++)
- {
- if(Ball[n] == Ball[count])
- {
- duplicate = true;
- }
- }
- }
- }
- while((Ball[n] < BetLow || Ball[n] > BetHigh) || (duplicate == true));
- cout << "*" << Ball[n] << "*\t";
- }
- do
- {
- BonusBall = rand() % BetHigh + BetLow;//generate bonus ball
- duplicate = false;
- for(int n = 0; n < 6; n++)//check bonus does not match any of the other balls
- {
- if(Ball[n] == BonusBall)
- {
- duplicate = true;
- }
- }
- }
- while(duplicate == true);
- Sleep(pause / 1.75);
- cout << "\n\t\t\t\tAnd the bonus is.....\t";
- Sleep(pause * (rand() % 5 + 2));//longer random pause before printing bonus ball
- cout << "*" << BonusBall << "*\n\n";
- }
- //----------------------------------------COMPARE RANDOM BALLS WITH GUESSES PER LINE------------
- void Compare(int Lines, int **Guess, int Ball[], int BonusBall, int Matches[])
- {
- for(int Line = 0; Line < Lines; Line++)
- {
- Matches[Line] = 0; //resets score per line to avoid winning on a line that you won on last round
- for(int n = 0; n < 6; n++)
- {
- if(Guess[Line][n] == BonusBall)
- {
- Matches[Line] = Matches[Line] + 1;//matching bonus ball scores 1 point
- }
- for(int b = 0; b < 6; b++)
- {
- if(Guess[Line][n] == Ball[b])
- {
- Matches[Line] = Matches[Line] + 10;//matching regular ball scores 10 points
- }
- }
- }
- /* if(Matches[Line] > 0) //can print score for each winning line, useful for debugging but user doesnt know what the score means...
- {
- cout << "\nYou scored " << Matches[Line] << " on line " << Line + 1 << " of " << Lines << "!";
- }*/
- }
- }
- //----------------------------------------PAYOUT------------------------------------------------
- void Payout(int Lines, int *Matches)
- {
- int Winnings = 0;//default winnings to 0
- for(int Line = 0; Line < Lines; Line++)//score for each line
- {
- //score will be of double digit format, ie two balls will score 20, and four balls and bonus ball will score 41
- if(Matches[Line] > 0)
- {
- if(Matches[Line] == 20 || Matches [Line] == 21)//2 matches (or 2 and bonus)
- {
- Winnings = Winnings + Payout2;
- }
- else if(Matches[Line] == 30 || Matches [Line] == 31)//3 matches (or 3 and bonus)
- {
- Winnings = Winnings + Payout3;
- }
- else if(Matches[Line] == 40)//4 matches
- {
- Winnings = Winnings + Payout4;
- }
- else if(Matches[Line] == 41)//4 matches and bonus ball
- {
- Winnings = Winnings + Payout4B;
- }
- else if(Matches[Line] == 50)//5 matches
- {
- Winnings = Winnings + Payout5;
- }
- else if(Matches[Line] == 51)//5 matches and bonus ball
- {
- Winnings = Winnings + Payout5B;
- }
- else if(Matches[Line] == 60)//6 matches == JACKPOT WINNAAAHHH
- {
- Winnings = Winnings + Payout6;
- }
- }
- }
- Sleep(pause * 1.5);
- if(Winnings != 0)
- {
- cout << "\n\nYou have won " << Pound << Winnings << "!! Congratulations!!\n\n";
- Wallet = Wallet + Winnings;
- Sleep(pause * 2);
- cout << "You now have " << Pound << Wallet << " in your wallet to play with!\n\n";
- }
- else if(Winnings == 0 && Wallet > 0)
- {
- cout << "\nSorry, you have not won this time.\n\n";
- Sleep(pause * 2);
- cout << "You still have " << Pound << Wallet << " left in your wallet to play with.\n\n";
- Sleep(pause);
- }
- }
- //----------------------------------------MAIN (LOOP FROM NUMBER OF LINES TO PAYOUT)-------------------------------------------------------------------------
- int main ()
- {
- SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), 11); //set text colour
- string Name = EnterName();
- //start game by asking for player's name(calls EnterName and sets local Name variable to the value returned by the function)
- Sleep(pause / 2);
- cout << "\nWelcome, " << Name << "!\n\tYou have " << Pound << Wallet << " in your wallet to play with!\n\n";
- Sleep(pause * 1.5);
- do //------------------------------------MAIN GAME LOOP---------------------------------------------
- {
- int Lines = Ticket(); //calls function for player to choose how many lines they want on this ticket
- //Lines takes value returned from Ticket function, and is then passed to the following functions to
- //the line length and therefore how each function will operate.
- int **Guess = new int*[Lines]; //declares the 2D array in heap memory
- for(int i = 0; i < Lines; i++) //sets the size of the array based on user input Lines
- {
- Guess[i] = new int[6];
- }
- Input(Lines, Guess);//calls the Input function so the user can set values, 6 numbers per number of lines
- int *Matches = new int[Lines];//declares array for winning score per line
- bool repeat = false;//declares and then sets repeat flag to false
- string input;//declares local input string, all cin data goes into this, then is checked if it can go into the int variable that needs it
- do//loop this if the user wants to re-use the same ticket
- {
- Wallet = Wallet - Lines; //subtract £1 for each line played
- Sleep(pause / 2);
- cout << "\nYou have " << Pound << Wallet << " left in your wallet.\n\n";
- int Ball[6] = {0};//declare balls array and set to 0
- int BonusBall = 0;//declare bonusball variable
- if(repeat == true) // Reprint ticket it repeat is detected
- {
- Sleep(pause);
- cout << "\nYour numbers are still:\n";
- for (int Line = 0; Line < Lines; Line++)
- {
- for(int n = 0; n < 6; n++)
- {
- cout << "\t-" << Guess[Line][n] << "-";
- }
- cout << endl;
- }
- Sleep(pause * 2);
- }
- Generate(Ball, BonusBall); //call the random ball generator to set values to Ball array and BonusBall
- Compare(Lines, Guess, Ball, BonusBall, Matches); //call the Compare function to check for matches and set score per line
- Payout(Lines, Matches);//call the Payout function to check score per line and total the winnings as needed.
- if(Wallet > 0 && Wallet >= Lines)//asks if player wants to reuse the same ticket, IF they can afford it
- {
- Sleep(pause * 1.5);
- bool valid = true;
- do
- {
- cout << "Would you like to play again with the same numbers? (Y/N)\n";
- input = "";
- cin >> input;
- if(input == "yes" || input == "Yes" || input == "y" || input == "Y" || input == "true" || input == "True" || input == "1")
- {
- repeat = true;
- valid = true;//accept answer, break loop, re using the same ticket
- }
- else if(input == "no" || input == "No" || input == "n" || input == "N" || input == "false" || input == "False" || input == "0")
- {
- repeat = false;
- valid = true;//accept answer, break loop without using same ticket
- }
- else
- {
- cout << "\nPlease answer with a yes or no, Y or N, true or false, or 1 or 0.\n\n";
- valid = false; //do not accept invalid answers
- Sleep(pause);
- }
- }
- while(valid == false);
- }
- }
- while((repeat == true && Wallet > 0) && (Wallet > Lines));
- delete Guess; //clear Guess array from memory if changing ticket size, to avoid memory leak
- delete Matches; //clear Matches array from memory if changing ticket size, to avoid memory leak
- //end game when out of money--------------
- if(Wallet <= 0)
- {
- running = false;
- Sleep(pause / 2);
- cout << "\n\n\nYou ran out of money. Thanks for playing!\n\n";
- Sleep(pause * 2);
- }
- }
- while(running==true);
- return 0;
- }
- /*
- I hope you enjoy playing my game and that you find my code interesting and informative.
- I believe I have written a very high standard of program, that is well structured, uses functions effectively,
- demonstrates knowledge of stack and heap memory and when and how to appropriately use them, as well as keeping
- in mind the actual mechanics of gameplay, such as the use of pauses to improve readability and excitement.
- I believe my code is now completely bug free, which took relatively little testing, as my functions made
- it extremely easy to find where and when something was broken.
- The only issue I have with my program, is that I cannot PREVENT a user inputting data into the cin input buffer
- and as such, whilst the game is printing the ticket, the player can input data and press enter during the pasues, and it will
- input into the next request for input, before the player even knows about it. The only way I can find to prevent
- this requires disabling ALL input, which, if I forget to ENABLE input, then the user cannot use their computer again
- short of using ctrl-alt-delete, or else simply take their keyboard away or tieing the user's hands behind their back,
- none of which are appropriate solutions.
- I have learned a great deal, considering that only a week ago, I only knew the basic fundamentals of declaring variables, performing
- equations and comparisons, and using input/output of information, as well as a limited understanding of loops.
- I look forward to learning more in the future, including visual programming, as well as applying my new knowledge and experience
- within scripting for pre existing game engines.
- -Michael Brandon
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement