This program does physics calculations within methods for a series of trajectory based games.
/*Spaced Invaders, Monster Hunter, & Trajectory Calculations by Jack P. Oakley This program uses subprograms with different parameter passing techniques*/ #include <iostream> using namespace std; #include <math.h> #include <stdio.h> #include <stdlib.h> #include <time.h> void dist2Points(void); void horizAngle(void); void distTravel(void); void destination(void); void basicCalcs(void); void displayTitle(void); void funcDecider(int choice); void firstPtText(void); void secondPtText(void); void mainMenu(void); void gameDecider(int choice); void artilleryTable(void); void targetPractice(void); void spacedInvaders(void); void monsterHunter(void); double obtainCoord(void); double obtainHAngle(void); double obtainVAngle(void); double obtainVelocity(void); double obtainDistance(void); double dist2PointCalc(double x1, double y1, double x2, double y2); double horizAngleCalc(double x1, double y1, double x2, double y2); double distTravelCalc(double elevAngleD, double velocMPH); void destinationCalc(double xStart, double yStart, double distance, double angleDeg, double &xEnd, double &yEnd); void getXY(double &xCoord, double &yCoord); int obtainPosInt(void); double obtainPosDouble(void); void targetPractCalc(int targetRadius, int &hitCount, int &missCount); void randomXY(int minX, int maxX, int minY, int maxY, int &xCoord, int &yCoord); int randomNum(int minNum, int maxNum); void spacedInvCalc(int targetRadius, int radarUses); int shotMenu(void); int velocPercent(void); void hAngleShift(double °rees, int &direction); double vAngleShift(void); void monsterHuntTitle(void); int werewolf(int &numStakes, int &numBullets, int &killCount, double playerHeight); int ghost(int &numStakes, int &numBullets, int &killCount, double playerHeight); int vampire(int &numStakes, int &numBullets, int &killCount, double playerHeight); void log(int &stakes); int zombie(int &numStakes, int &numBullets, int &killCount, double playerHeight); void monsterHuntStory(void); int randomMonster(int &killCount, int &numStakes, int &numBullets, double playerHeight); int weapons(int &numStakes, int &numBullets); double thrownVelocity(void); int difficultyMenu(void); void gameOver(void); const double pi = 3.14159; /******************************************************************************* * main function: * * PURPOSE: Drives the program * * IN: none * * OUT: none * *******************************************************************************/ void main(void) { srand(time(NULL)); displayTitle(); mainMenu(); } //End main() /******************************************************************************* * displayTitle function: * * PURPOSE: Display title & description by keeping main() a little cleaner * * IN: none * * OUT: none * *******************************************************************************/ void displayTitle(void) //CS Rep { cout << "Spaced Invaders, Monster Hunter, and Calculations" << endl << endl; cout << "This program provides a list of games that can be played." << endl << endl; } //End displayTitle() /******************************************************************************* * basicCalcs function: * * PURPOSE: Displays basic calcs menu, obtains user's choice, & directs to chce * * IN: none * * OUT: none * *******************************************************************************/ void basicCalcs(void) //CS Rep { int userChoice; do { cout << endl << "Basic Calculations" << endl << endl; cout << "Please choose one of the following options: " << endl; cout << "(1) Compute distance between 2 points" << endl; cout << "(2) Compute horizontal angle between 2 points" << endl; cout << "(3) Compute horizontal distance an object travels" << endl; cout << "(4) Compute a destination point" << endl; cout << "(5) Exit Menu" << endl; cin >> userChoice; funcDecider(userChoice); } while (userChoice != 5); cout << endl << "You have chosen to exit to the main menu." << endl << endl; } //End basicCalcs() /******************************************************************************* * funcDecider function: * * PURPOSE: Decides which function to call based off given input * * IN: int of user's chosen option * * OUT: none * *******************************************************************************/ void funcDecider(int choice) { if (choice == 1) { dist2Points(); } else if (choice == 2) { horizAngle(); } else if (choice == 3) { distTravel(); } else if (choice == 4) { destination(); } else if (choice != 5) { cout << endl << "That value was not from 1 to 5, please enter a value " << "that is from 1 to 5. " << endl << endl; } } //End funcDecider() /******************************************************************************* * dist2Points function: * * PURPOSE: Handles all input/output for dist2PointCalc() * * IN: none * * OUT: none * *******************************************************************************/ void dist2Points(void) //CS Rep { double distance, xEnd, xStart, yEnd, yStart; cout << endl << "Distance between two points: " << endl << endl; firstPtText(); getXY(xStart, yStart); secondPtText(); getXY(xEnd, yEnd); distance = dist2PointCalc(xStart, yStart, xEnd, yEnd); cout << "The distance between the two points is " << distance << " feet." << endl << endl; } //End dist2Points() /******************************************************************************* * dist2PointCalc function: * * PURPOSE: Calculates distance between 2 points * * IN: 4 doubles: (x,y) coords of 2 points * * OUT: Returns: double of calculated distance * *******************************************************************************/ double dist2PointCalc(double x1, double y1, double x2, double y2) //Engineer { double distance; distance = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); return distance; } //End dist2PointCalc() /******************************************************************************* * horizAngle function: * * PURPOSE: Handles all input/output for horizAngleCalc() * * IN: none * * OUT: none * *******************************************************************************/ void horizAngle(void) //CS Rep { double xStart, yStart, xEnd, yEnd, angle; cout << endl << "Horizontal angle between two points: " << endl << endl; firstPtText(); getXY(xStart, yStart); secondPtText(); getXY(xEnd, yEnd); angle = horizAngleCalc(xStart, yStart, xEnd, yEnd); cout << "The horizontal angle from the first point to the second point is " << angle << " degrees." << endl << endl; } //End horizAngle() /******************************************************************************* * horizAngleCalc function: * * PURPOSE: Calculates horizonatal angle between 2 points * * IN: 4 doubles: (x,y) coords of 2 points * * OUT: Returns: double of calculated angle * *******************************************************************************/ double horizAngleCalc(double x1, double y1, double x2, double y2) //Engineer { double diffx, diffy, radianAngle, degreeAngle; diffx = x2 - x1; diffy = y2 - y1; if (diffx > 0) { radianAngle = atan(diffy / diffx); } else if (diffx < 0) { radianAngle = atan(diffy / diffx) + pi; } else if (diffx == 0 && diffy >= 0) { radianAngle = pi / 2.0; } else { radianAngle = -pi / 2.0; } degreeAngle = radianAngle * 180.0 / pi; return degreeAngle; } //End horizAngleCalc() /******************************************************************************* * distTravel function: * * PURPOSE: Handles all input/output for distTravelCalc() * * IN: none * * OUT: none * *******************************************************************************/ void distTravel(void) //CS Rep { double angle, velocity, distance; cout << endl << "Distance travelled: " << endl << endl; cout << "What is the angle of elevation? (degrees) "; angle = obtainVAngle(); cout << "What is the initial velocity? (mph) "; velocity = obtainVelocity(); distance = distTravelCalc(angle, velocity); cout << "The distance travelled horizontally is " << distance << " feet." << endl << endl; } //End distTravel() /******************************************************************************* * distTravelCalc function: * * PURPOSE: Calculates distance using an elevation angle and velocity * * IN: 2 doubles: elevationAngle in degrees & velocity in MPH * * OUT: Returns: double of calculated distance in feet * *******************************************************************************/ double distTravelCalc(double elevAngleD, double velocMPH) //Engineer { double elevAngleR, velocFPS, horizDistance; const int ftmi = 5280; const int secHour = 3600; const double gravity = 32.172; elevAngleR = elevAngleD * pi / 180.0; velocFPS = velocMPH * ftmi / secHour; horizDistance = pow(velocFPS, 2) * sin(2 * elevAngleR) / gravity; return horizDistance; } //End distTravelCalc() /******************************************************************************* * destination function: * * PURPOSE: Handles all input/output for destinationCalc() * * IN: none * * OUT: none * *******************************************************************************/ void destination(void) //CS Rep { double horizAngleD, pointDistance, x1, y1, x2, y2; cout << endl << "Destination Point: " << endl << endl; cout << "What is the horizontal angle? (degrees) "; horizAngleD = obtainHAngle(); cout << "What is the distance between the two points? (feet) "; pointDistance = obtainDistance(); firstPtText(); getXY(x1, y1); destinationCalc(x1, y1, pointDistance, horizAngleD, x2, y2); cout << "The endpoint is (" << x2 << "," << y2 << ")." << endl << endl; } //End destination() /******************************************************************************* * destinationCalc function: * * PURPOSE: Calculates destination point given a distance, angle, & starting pt * * IN: 6 doubles: (x,y) coords start point, distance, angle in degrees, & * * container for (x,y) coords of destination * * OUT: Reference params: (x,y) coords of calculated destination point * *******************************************************************************/ void destinationCalc(double xStart, double yStart, double distance, double angleDeg, double &xEnd, double &yEnd) //Engineer { double angleRad, diffx, diffy; angleRad = angleDeg * pi / 180.0; diffx = distance * cos(angleRad); diffy = distance * sin(angleRad); xEnd = xStart + diffx; yEnd = yStart + diffy; } //End destinationCalc() /******************************************************************************* * obtainCoord function: * * PURPOSE: This is used to input any coordinate, x or y by reducing redundancy * * IN: none * * OUT: Returns: double of input coordinate * *******************************************************************************/ double obtainCoord(void) { double coordinate; cin >> coordinate; return coordinate; } //End obtainCoord() /******************************************************************************* * obtainHAngle function: * * PURPOSE: Obtain a horizontal angle from user and restrict to correct values * * IN: none * * OUT: Returns: double of input angle * *******************************************************************************/ double obtainHAngle(void) { double angle; do { cin >> angle; if (angle < 0 || angle > 360) { cout << "The angle must be from 0 to 360 degrees." << endl; cout << "Please enter an angle from 0 to 360 degrees. "; } } while (angle < 0 || angle > 360); return angle; } //End obtainHAngle() /******************************************************************************* * obtainVAngle function: * * PURPOSE: Obtain a vertical angle from user and restrict to appropriate values* * IN: none * * OUT: Returns: double of input angle * *******************************************************************************/ double obtainVAngle(void) { double angle; do { cin >> angle; if (angle <= 0 || angle >= 90) { cout << "The angle must be between 0 and 90 degrees." << endl; cout << "Please enter an angle between 0 and 90 degrees. "; } } while (angle <= 0 || angle >= 90); return angle; } //End obtainVAngle() /******************************************************************************* * obtainVelocity function: * * PURPOSE: Obtain a velocity from user and restrict to correct values * * IN: none * * OUT: Returns: double of input velocity * *******************************************************************************/ double obtainVelocity(void) { double velocity; do { cin >> velocity; if (velocity <= 0) { cout << "Velocity must be a positive number, please enter a " << "positive number. "; } } while (velocity <= 0); return velocity; } //End obtainVelocity() /******************************************************************************* * obtainDistance function: * * PURPOSE: Obtain a distance from user and restrict to correct values * * IN: none * * OUT: Returns: double of input distance * *******************************************************************************/ double obtainDistance(void) { double distance; do { cin >> distance; if (distance <= 0) { cout << "Distance must be a positive number, please enter a " << "positive number. "; } } while (distance <= 0); return distance; } //End obtainDistance() /******************************************************************************* * getXY function: * * PURPOSE: Obtain an (x,y) coord pair from user * * IN: 2 double containers for x & y coords * * OUT: Reference params: x & y coords * *******************************************************************************/ void getXY(double &xCoord, double &yCoord) { cout << "What is the x coordinate of the point? (ft) "; xCoord = obtainCoord(); cout << "What is the y coordinate of the point? (ft) "; yCoord = obtainCoord(); } //End getXY() /******************************************************************************* * firstPtText function: * * PURPOSE: Display text to obtain first pt by reducing redundancy * * IN: none * * OUT: none * *******************************************************************************/ void firstPtText(void) { cout << "Please enter the following for the first point: " << endl; } //End firstPtText() /******************************************************************************* * secondPtText function: * * PURPOSE: Display text to obtain second pt by reducing redundancy * * IN: none * * OUT: none * *******************************************************************************/ void secondPtText(void) { cout << "Please enter the following for the second point: " << endl; } //End secondPtText() /******************************************************************************* * mainMenu function: * * PURPOSE: Displays main menu, obtains user's choice, & directs to chce * * IN: none * * OUT: none * *******************************************************************************/ void mainMenu(void) //CS Rep { int userChoice; do { cout << "Please choose one of the following options: " << endl; cout << "(1) Basic Calculations" << endl; cout << "(2) Artillery Table" << endl; cout << "(3) TargetPractice" << endl; cout << "(4) Spaced Invaders" << endl; cout << "(5) Monster Hunter" << endl; cout << "(6) Quit the program" << endl; cin >> userChoice; gameDecider(userChoice); } while (userChoice != 6); cout << endl << "You have chosen to quit. Goodbye" << endl << endl; } //End mainMenu() /******************************************************************************* * gameDecider function: * * PURPOSE: Decides which game function to call based off given input * * IN: int of user's chosen option * * OUT: none * *******************************************************************************/ void gameDecider(int choice) { if (choice == 1) { basicCalcs(); } else if (choice == 2) { artilleryTable(); } else if (choice == 3) { targetPractice(); } else if (choice == 4) { spacedInvaders(); } else if (choice == 5) { monsterHunter(); } else if (choice != 6) { cout << endl << "That value was not from 1 to 6, please enter a value " << "that is from 1 to 6. " << endl << endl; } } //End gameDecider() /******************************************************************************* * artilleryTable function: * * PURPOSE: Displays table of varying distances calculated from a vertical angle* * & velocity * * IN: none * * OUT: none * * ADTNL NOTE: User can choose to vary table by velocity or angle * *******************************************************************************/ void artilleryTable(void) { double velocity, angle, increaseAmt, distance; int numRows, option, i; cout << endl << "Artillery Table" << endl << endl; cout << "What is the initial angle in degrees? "; angle = obtainVAngle(); cout << "What is the initial velocity in mph? "; velocity = obtainVelocity(); cout << "How many rows do you want displayed in the table? "; numRows = obtainPosInt(); do { cout << "Which do you want to vary? Enter:" << endl; cout << "(1) Angle" << endl; cout << "(2) Velocity" << endl; cin >> option; if (option != 1 && option != 2) { cout << "You must enter 1 or 2. "; } } while (option != 1 && option != 2); cout << "By how much would you like each row of the table to increase? "; increaseAmt = obtainPosDouble(); cout << endl << endl; if (option == 1) { cout << " Angle Distance" << endl; cout << " (Degrees) (Feet)" << endl; cout << "=========================" << endl; for (i = 0; i < numRows; ++i) { distance = distTravelCalc(angle, velocity); printf("%7.3f %10.3f\n", angle, distance); angle = angle + increaseAmt; } } else if (option == 2) { cout << " Velocity Distance" << endl; cout << " (MPH) (Feet)" << endl; cout << "=========================" << endl; for (i = 0; i < numRows; ++i) { distance = distTravelCalc(angle, velocity); printf("%7.3f %10.3f\n", velocity, distance); velocity = velocity + increaseAmt; } } cout << endl << endl; } //End artilleryTable() /******************************************************************************* * targetPractice function: * * PURPOSE: Simulate firing at a stationary target with 3 choices of difficulty * * IN: none * * OUT: none * * ADTNL NOTE: Target coords are chosen at random and changed upon being hit * *******************************************************************************/ void targetPractice(void) { int playerChoice, targetRadius, hitCount = 0, missCount = 0; const int easyRadius = 100, medRadius = 25, hardRadius = 5; cout << endl << "Target Practice" << endl << endl; do { playerChoice = difficultyMenu(); if (playerChoice == 1) { targetRadius = easyRadius; targetPractCalc(targetRadius, hitCount, missCount); } else if (playerChoice == 2) { targetRadius = medRadius; targetPractCalc(targetRadius, hitCount, missCount); } else if (playerChoice == 3) { targetRadius = hardRadius; targetPractCalc(targetRadius, hitCount, missCount); } } while (playerChoice != 4); cout << "You have chosen to exit to the main menu." << endl << endl; cout << "You hit the target " << hitCount << " times." << endl; cout << "You missed the target " << missCount << " times." << endl << endl; } //End targetPractice() /******************************************************************************* * spacedInvaders function: * * PURPOSE: Game of hitting moving stealth targets with 3 choices of difficulty * * IN: none * * OUT: none * *******************************************************************************/ void spacedInvaders(void) { int playerChoice, targetRadius, radarUses; const int easyRadius = 100, medRadius = 25, hardRadius = 5; const int easyRadar = 20, medRadar = 6, hardRadar = 2; cout << endl << "Spaced Invaders" << endl << endl; do { playerChoice = difficultyMenu(); if (playerChoice == 1) { targetRadius = easyRadius; radarUses = easyRadar; spacedInvCalc(targetRadius, radarUses); } else if (playerChoice == 2) { targetRadius = medRadius; radarUses = medRadar; spacedInvCalc(targetRadius, radarUses); } else if (playerChoice == 3) { targetRadius = hardRadius; radarUses = hardRadar; spacedInvCalc(targetRadius, radarUses); } } while (playerChoice != 4); } //End spacedInvaders() /******************************************************************************* * monsterHunter function: * * PURPOSE: DisplaysTitle and calls main story of game * * IN: none * * OUT: none * *******************************************************************************/ void monsterHunter(void) { monsterHuntTitle(); monsterHuntStory(); } //End monsterHunter() /******************************************************************************* * obtainPosInt function: * * PURPOSE: Otain an int from user and restrict it to being positive * * IN: none * * OUT: int of positive value * *******************************************************************************/ int obtainPosInt(void) { int posInteger; do { cin >> posInteger; if (posInteger <= 0) { cout << "The entry must be a positive number, please enter a " << "positive number. "; } } while (posInteger <= 0); return posInteger; } //End obtainPosInt() /******************************************************************************* * obtainPosDouble function: * * PURPOSE: Otain an double from user and restrict it to being positive * * IN: none * * OUT: double of positive value * *******************************************************************************/ double obtainPosDouble(void) { double posDouble; do { cin >> posDouble; if (posDouble <= 0) { cout << "The entry must be a positive number, please enter a " << "positive number. "; } } while (posDouble <= 0); return posDouble; } //End obtainPosDouble() /******************************************************************************* * targetPractCalc function: * * PURPOSE: Prompt user for values & calculate attempts to hit a single target * * in targetPractice game * * IN: int for target radius, 2 int containers: hit count & miss count * * OUT: Reference params: hitCount & missCount * *******************************************************************************/ void targetPractCalc( int targetRadius, int &hitCount, int &missCount) { int mortarX = 2500, mortarY = 0, targetX, targetY; double horizAngle, vertAngle, velocity, shellDist, shellHitX, shellHitY; double proximity; char repeat; const int minXY = 0; const int maxXY = 5001; randomXY(minXY, maxXY, minXY, maxXY, targetX, targetY); do { cout << "The target is located at (" << targetX << ", " << targetY << ")." << endl; cout << "Please enter the direction to face the barrel " << "(horizontal angle in degrees): "; horizAngle = obtainHAngle(); cout << "Please enter the elevation of the barrel in " << "degrees: "; vertAngle = obtainVAngle(); cout << "Please enter the velocity of the projectile in MPH: "; velocity = obtainVelocity(); shellDist = distTravelCalc(vertAngle, velocity); destinationCalc(mortarX, mortarY, shellDist, horizAngle, shellHitX, shellHitY); proximity = dist2PointCalc(shellHitX, shellHitY, targetX, targetY); if (proximity <= targetRadius) { cout << "You have hit the target. You can now choose a " << "new target." << endl << endl; repeat = 'n'; ++hitCount; } else { cout << "Sorry, you missed the target by a distance of " << proximity << " feet." << endl << "Would you like to " << "take another shot? (y/n) "; cin >> repeat; ++missCount; cout << endl; } } while (repeat != 'n' && repeat != 'N'); } //End targetPractCalc /******************************************************************************* * randomXY function: * * PURPOSE: Generate random (x,y) coord pair within given ranges * * IN: 4 ints: min and max x and y values, 2 int containers for generated (x,y) * * OUT: Ref. params: randomly generated (x,y) * *******************************************************************************/ void randomXY(int minX, int maxX, int minY, int maxY, int &xCoord, int &yCoord) { xCoord = randomNum(minX, maxX); yCoord = randomNum(minY, maxY); } //End randomXY() /******************************************************************************* * randomNum function: * * PURPOSE: Generate random num within given range * * IN: 2 ints: min and max values to be generated * * OUT: Returns: int of randomly generated num * *******************************************************************************/ int randomNum(int minNum, int maxNum) { int number, numRange; numRange = maxNum - minNum; number = rand() % numRange + minNum; return number; } //End randomNum() /******************************************************************************* * spacedInvCalc function: * * PURPOSE: Main Spaced Invaders game, runs the game * * IN: 2 ints: target radius & number of radar uses available * * OUT: none * *******************************************************************************/ void spacedInvCalc(int targetRadius, int radarUses) { int mortarX = 2500, mortarY = 0, targetX, targetY, menuChoice; int shotType, directionChoice, numShots = 0, numHits = 0, numETs = 0; double horizAngle = 90, vertAngle = 45, velocity, shellDist; double shellHitX, shellHitY, proximity, ETAngle, hDegreeShift; double vDegreeShift; int newET; const int minX = 0; const int maxX = 5001; int ETVelocity = 300; //ft per minute const int flashRadius = 500; const int tripwire1 = 5000; const int tripwire2 = 2000; do { newET = 0; targetY = tripwire1; targetX = randomNum(minX, maxX); cout << "The alien is located at (" << targetX << ", " << targetY << ")." << endl; do { do { cout << "Choose an option for this turn:" << endl; cout << "(1) Fire the Cannon" << endl; cout << "(2) Consult the Radar" << endl; cout << "(3) Adjust the Cannon's Horizontal Angle" << endl; cout << "(4) Adjust the Cannon's Elevation Angle" << endl; cout << "(5) Let this ET Go" << endl; cout << "(6) Quit the Game" << endl; cin >> menuChoice; if (menuChoice <= 0 || menuChoice > 6) { cout << "That entry was not from 1 to 6. Please enter a " << "choice from 1 to 6." << endl << endl; } } while (menuChoice <= 0 || menuChoice > 6); if (menuChoice == 1) { shotType = shotMenu(); velocity = velocPercent(); shellDist = distTravelCalc(vertAngle, velocity); destinationCalc(mortarX, mortarY, shellDist, horizAngle, shellHitX, shellHitY); proximity = dist2PointCalc(shellHitX, shellHitY, targetX, targetY); if (shotType == 1 && proximity <= flashRadius) { cout << "The target has been sighted at (" << targetX << ", " << targetY << ")." << endl; } else if (shotType == 1) { cout << "Nothing is revealed in the flash." << endl; } else if (shotType == 2 && proximity <= targetRadius) { cout << "The alien gobbles up the marshmallow and leaves " << "the planet." << endl; ++numShots; ++newET; ETVelocity = ETVelocity + randomNum(0, 501); } else { cout << "You missed the alien and it still approaches." << endl; ++numShots; } } else if (menuChoice == 2) { if (radarUses > 0) { ETAngle = horizAngleCalc(mortarX, mortarY, targetX, targetY); radarUses = radarUses - 1; cout << "The alien is at " << ETAngle << "degrees." << endl; } else { cout << "The radar malfunctioned." << endl; } } else if (menuChoice == 3) { hAngleShift(hDegreeShift, directionChoice); if (directionChoice == 1) { horizAngle = horizAngle - hDegreeShift; } else { horizAngle = horizAngle + hDegreeShift; } } else if (menuChoice == 4) { vDegreeShift = vAngleShift(); vertAngle = vertAngle + vDegreeShift; if (vertAngle <= 10) { vertAngle = 10; } else if (vertAngle >= 80) { vertAngle = 80; } } else if (menuChoice == 5) { ++numETs; ++newET; } if (targetY > tripwire2 && (targetY - ETVelocity) < tripwire2) { targetY = targetY - ETVelocity; cout << "The alien is located at (" << targetX << ", " << targetY << ")." << endl; } else { targetY = targetY - ETVelocity; } if (targetY <= 0) { cout << "The alien got past you." << endl << endl; ++numETs; ++newET; ETVelocity = ETVelocity + randomNum(0, 501); } if (ETVelocity > 3000) { ETVelocity = 500; } } while (newET == 0 && menuChoice != 6); if (numETs >= 10) { cout << "You lost the game." << endl << endl; cout << "You successfully fed " << numHits << " aliens and sent " << "them home." << endl; cout << numETs << " got across the border and infected the world." << endl; cout << "You shot " << numShots << " marshmallows at the aliens." << endl << endl; menuChoice = 6; } else if (menuChoice != 6) { cout << "The tripwire has been activated again!" << endl << endl; } }while (menuChoice != 6); } //End spacedInvCalc() /******************************************************************************* * shotMenu function: * * PURPOSE: Prompt user for type of shot they want to take in Spaced Invaders * * IN: none * * OUT: Returns: int of user's menu selection * *******************************************************************************/ int shotMenu(void) { int type; do { cout << "Which do you want to fire?" << endl; cout << "(1) Flash Grenade" << endl; cout << "(2) Marshmallow" << endl; cin >> type; if (type != 1 && type != 2) { cout << "Please enter either 1 or 2." << endl; } } while (type != 1 && type != 2); return type; } //End shotMenu() /******************************************************************************* * velocPercent function: * * PURPOSE: Prompt user for percentage of max velocity to use for a shot * * IN: none * * OUT: Returns: int for velocity based off percentage * *******************************************************************************/ int velocPercent(void) { int percent, velocity; const int maxVeloc = 250; do { cout << "What percentage of the maximum velocity to you want " << "to use? (1-100) "; cin >> percent; if (percent <= 0 || percent > 100) { cout << "Please enter a value from 1 to 100." << endl; } } while (percent <= 0 || percent > 100); velocity = (percent / 100) * maxVeloc; return velocity; } //End velocPercent() /******************************************************************************* * hAngleShift function: * * PURPOSE: Obtain direction & num of degrees to horizontally re-angle cannon * * IN: 2 int containers for degrees and direction * * OUT: Reference params: degrees & direction * *******************************************************************************/ void hAngleShift(double °rees, int &direction) { do { cout << "Which direction do you want to shift?" << endl; cout << "(1) Left" << endl; cout << "(2) Right" << endl; cin >> direction; if (direction != 1 && direction != 2) { cout << "Please enter a 1 or 2." << endl; } } while (direction != 1 && direction != 2); do { cout << "How many degrees do you want to shift? (0>30) "; cin >> degrees; if (degrees <= 0 || degrees >= 30) { cout << "Please enter a value between 0 and 30." << endl; } } while (degrees <= 0 || degrees >= 30); } //End hAngleShift() /******************************************************************************* * vAngleShift function: * * PURPOSE: Obtain num of degrees to vertically re-angle cannon * * IN: none * * OUT: Returns: double for num degrees change in cannon angle * *******************************************************************************/ double vAngleShift(void) { double shift; do { cout << "How many degrees do you want to shift? (-30>30) "; cin >> shift; if (shift <= -30 || shift >= 30) { cout << "Please enter a value between -30 and 30." << endl; } } while (shift <= -30 || shift >= 30); return shift; } //End vAngleShift() /******************************************************************************* * monsterHunterTitle function: * * PURPOSE: Display title & description by keeping main game a little cleaner * * IN: none * * OUT: none * *******************************************************************************/ void monsterHuntTitle(void) { cout << " X X XXX X X XXXX XXXXX XXXXX XXX " << endl; cout << " X X X X X X XX X X X X X X " << endl; cout << " X X X X X X X X XXX X XXX XXX " << endl; cout << " X X X X X X X X X X X X " << endl; cout << " X X XXX X XX XXXX X XXXXX X X" << endl; cout << endl; cout << " X X X X X X XXXXX XXXXX XXX " << endl; cout << " X X X X XX X X X X X " << endl; cout << " XXXXX X X X X X X XXX XXX " << endl; cout << " X X X X X X X X X X X " << endl; cout << " X X XXX X XX X XXXXX X X" << endl << endl; cout << " A text-based role-playing adventure!" << endl << endl; } //End monsterHuntTitle() /******************************************************************************* * werewolf function: * * PURPOSE: Drive werewolf encounter * * IN: 3 ints: number of each consumable item, kill count, double of player * * height * * OUT: Returns: int for whether player died or lived through encounter, * * Ref. Params: Number of each consumable item remaining, killCount * *******************************************************************************/ int werewolf(int &numStakes, int &numBullets, int &killCount, double playerHeight) { int heartHeight, wolfLocationX, wolfLocationY, weaponChoice, wolfHeight; int loot; double horizAngle, vertAngle, velocity; int playerPosition = 0; int death = 0; int exitLoop = 0; double gunHeight, bulletDist, bulletHitX, bulletHitY, proximity; const int minHeartHeight = 2; const int maxHeartHeight = 7; const int minWolfDistance = 5; const int maxWolfDistance = 200; const float heartSize = .75f; randomXY(minWolfDistance, maxWolfDistance, minWolfDistance, maxWolfDistance, wolfLocationX, wolfLocationY); heartHeight = randomNum(minHeartHeight, maxHeartHeight); wolfHeight = heartHeight + 1; gunHeight = playerHeight - 1; weaponChoice = weapons(numStakes, numBullets); if (weaponChoice == 2 && numBullets > 0) { do { cout << "The werewolf is located at (" << wolfLocationX << ", " << wolfLocationY << ")." << endl; cout << "He is about " << wolfHeight << " feet tall." << endl; cout << "You have " << numBullets << " bullets remaining." << endl; cout << "Please enter the direction to face the gun " << "(horizontal angle in degrees): "; horizAngle = obtainHAngle(); cout << "Please enter the elevation of the gun in " << "degrees: "; vertAngle = obtainVAngle(); cout << "Please enter the velocity setting of the gun in MPH: "; velocity = obtainVelocity(); bulletDist = distTravelCalc(vertAngle, velocity); destinationCalc(playerPosition, gunHeight, bulletDist, horizAngle, bulletHitX, bulletHitY); proximity = dist2PointCalc(bulletHitX, bulletHitY, wolfLocationX, wolfLocationY); if (proximity <= heartSize) { cout << "You have shot the werewolf in the heart. He is dead. " << endl << endl; ++killCount; ++exitLoop; loot = randomNum(2, 15); numStakes = numStakes + loot; cout << "You have found " << loot << " wooden stakes on the " << "dead werewolf." << endl; } else { cout << "Sorry, you missed the werewolf by a distance of " << proximity << " feet." << endl << endl; } numBullets = numBullets - 1; if (numBullets <= 0) { cout << "You are out of silvered bullets and cannot fire any " << "more shots." << endl; cout << "The werewolf is upon you within seconds. He rips your" << " heart out and mauls your body." << endl << endl; death = 1; //The player died ++exitLoop; } } while (exitLoop == 0); } else { cout << "The weapon has no effect on the werewolf. He is upon you " << "within seconds. He rips your heart out and mauls your body." << endl << endl; death = 1; //The player died } return death; } //End werewolf() /******************************************************************************* * ghost function: * * PURPOSE: Drive ghost encounter * * IN: 3 ints: number of each consumable item, kill count, double of player * * height * * OUT: Returns: int for whether player died or lived through encounter, * * Ref. Params: Number of each consumable item remaining, killCount * *******************************************************************************/ int ghost(int &numStakes, int &numBullets, int &killCount, double playerHeight) { int ghostLocationX, ghostLocationY, weaponChoice, ghostHeight, loot; double horizAngle, vertAngle, velocity; int playerPosition = 0; int death = 0; int exitLoop = 0; double knifeHeight, knifeDist, knifeHitX, knifeHitY, proximity; const int minGhostHeight = 1; const int maxGhostHeight = 12; const int minGhostDistance = 5; const int maxGhostDistance = 200; randomXY(minGhostDistance, maxGhostDistance, minGhostDistance, maxGhostDistance, ghostLocationX, ghostLocationY); ghostHeight = randomNum(minGhostHeight, maxGhostHeight); knifeHeight = playerHeight - 1; weaponChoice = weapons(numStakes, numBullets); if (weaponChoice == 1) { do { cout << "The ghost is located at (" << ghostLocationX << ", " << ghostLocationY << ")." << endl; cout << "It is about " << ghostHeight << " feet tall." << endl; cout << "Please enter the direction you want to face " << "(horizontal angle in degrees): "; horizAngle = obtainHAngle(); cout << "Please enter the angle you want to throw the knife in " << "degrees: "; vertAngle = obtainVAngle(); cout << "Please enter the velocity to throw the knife in MPH: "; velocity = thrownVelocity(); knifeDist = distTravelCalc(vertAngle, velocity); destinationCalc(playerPosition, knifeHeight, knifeDist, horizAngle, knifeHitX, knifeHitY); proximity = dist2PointCalc(knifeHitX, knifeHitY, ghostLocationX, ghostLocationY); if (proximity <= ghostHeight) { cout << "You have thrown the magic knife. It sticks into the " << "ghost as if the ghost is\nsolid. The ghost dissipates " << "into a mist, it is dead. As your knife falls to the\n" << "ground, it disappears and returns to its sheath." << endl << endl; ++killCount; ++exitLoop; loot = randomNum(2, 15); numBullets = numBullets + loot; cout << "You have found " << loot << " silvered bullets " << "embedded in the surrounding foliage." << endl; loot = randomNum(2, 15); numStakes = numStakes + loot; cout << "You have found " << loot << " wooden stakes on the " << "the ground." << endl; } else { cout << "Sorry, you missed the ghost by a distance of " << proximity << " feet. As you see your magic\nknife hit " << "the ground, it disappears and reappears in its " << "sheath." << endl << endl; } } while (exitLoop == 0); } else { cout << "The weapon passes right through the spirit, having no " << "effect, as if it isn't \nreally there. The ghost wisps up to " << "you and rips your soul from your body." << endl << endl; death = 1; //The player died } return death; } //End ghost() /******************************************************************************* * vampire function: * * PURPOSE: Drive vampire encounter * * IN: 3 ints: number of each consumable item, kill count, double of player * * height * * OUT: Returns: int for whether player died or lived through encounter, * * Ref. Params: Number of each consumable item remaining, killCount * *******************************************************************************/ int vampire(int &numStakes, int &numBullets, int &killCount, double playerHeight) { int heartHeight, vampLocationX, vampLocationY, weaponChoice, vampHeight; int loot; double horizAngle, vertAngle, velocity; int playerPosition = 0; int death = 0; int exitLoop = 0; double stakeHeight, stakeDist, stakeHitX, stakeHitY, proximity; const int minHeartHeight = 4; const int maxHeartHeight = 6; const int minVampDistance = 5; const int maxVampDistance = 200; const float heartSize = .45f; randomXY(minVampDistance, maxVampDistance, minVampDistance, maxVampDistance, vampLocationX, vampLocationY); heartHeight = randomNum(minHeartHeight, maxHeartHeight); vampHeight = heartHeight + 1; stakeHeight = playerHeight - 1; weaponChoice = weapons(numStakes, numBullets); if (weaponChoice == 3 && numStakes > 0) { do { cout << "The vampire is located at (" << vampLocationX << ", " << vampLocationY << ")." << endl; cout << "He is about " << vampHeight << " feet tall." << endl; cout << "You have " << numStakes << " wooden stakes remaining." << endl; cout << "Please enter the direction you want to face " << "(horizontal angle in degrees): "; horizAngle = obtainHAngle(); cout << "Please enter the angle you want to throw the stake in " << "degrees: "; vertAngle = obtainVAngle(); cout << "Please enter the velocity to throw the stake in MPH: "; velocity = thrownVelocity(); stakeDist = distTravelCalc(vertAngle, velocity); destinationCalc(playerPosition, stakeHeight, stakeDist, horizAngle, stakeHitX, stakeHitY); proximity = dist2PointCalc(stakeHitX, stakeHitY, vampLocationX, vampLocationY); if (proximity <= heartSize) { cout << "You have thrown a stake into the vampire's heart. " << "He bursts into a cloud of ash." << endl << endl; ++killCount; ++exitLoop; loot = randomNum(2, 15); numBullets = numBullets + loot; cout << "You have found " << loot << " silvered bullets on the" << " ground where the vampire vanished." << endl; } else { cout << "Sorry, you missed the vampire by a distance of " << proximity << " feet." << endl << endl; } numStakes = numStakes - 1; if (numStakes <= 0) { cout << "You are out of wooden stakes and cannot throw any " << "more." << endl; cout << "The vampire is behind you in the blink of an eye. He" << " sinks his teeth into your neck and entirely drains " << "your body of blood within seconds." << endl << endl; death = 1; //The player died ++exitLoop; } } while (exitLoop == 0); } else { cout << "The weapon has no effect on the vampire. He is behind you in " << "the blink of an\neye. He sinks his teeth into your neck and " << "entirely drains your body of\nblood within seconds." << endl << endl; death = 1; //The player died } return death; } //End Vampire() /******************************************************************************* * zombie function: * * PURPOSE: Drive zombie encounter * * IN: 3 ints: number of each consumable item, kill count, double of player * * height * * OUT: Returns: int for whether player died or lived through encounter, * * Ref. Params: Number of each consumable item remaining, killCount * *******************************************************************************/ int zombie(int &numStakes, int &numBullets, int &killCount, double playerHeight) { int headHeight, zombieLocationX, zombieLocationY, weaponChoice; int zombieHeight, loot; double horizAngle, vertAngle, velocity; int playerPosition = 0; int death = 0; int exitLoop = 0; double gunHeight, bulletDist, bulletHitX, bulletHitY, proximity; const int minHeadHeight = 2; const int maxHeadHeight = 7; const int minZombieDistance = 5; const int maxZombieDistance = 200; const float headSize = 1.0f; randomXY(minZombieDistance, maxZombieDistance, minZombieDistance, maxZombieDistance, zombieLocationX, zombieLocationY); headHeight = randomNum(minHeadHeight, maxHeadHeight); zombieHeight = headHeight; gunHeight = playerHeight - 1; weaponChoice = weapons(numStakes, numBullets); if (weaponChoice == 2 && numBullets > 0) { do { cout << "The zombie is located at (" << zombieLocationX << ", " << zombieLocationY << ")." << endl; cout << "He is about " << zombieHeight << " feet tall." << endl; cout << "You have " << numBullets << " bullets remaining." << endl; cout << "Please enter the direction to face the gun " << "(horizontal angle in degrees): "; horizAngle = obtainHAngle(); cout << "Please enter the elevation of the gun in " << "degrees: "; vertAngle = obtainVAngle(); cout << "Please enter the velocity setting of the gun in MPH: "; velocity = obtainVelocity(); bulletDist = distTravelCalc(vertAngle, velocity); destinationCalc(playerPosition, gunHeight, bulletDist, horizAngle, bulletHitX, bulletHitY); proximity = dist2PointCalc(bulletHitX, bulletHitY, zombieLocationX, zombieLocationY); if (proximity <= headSize) { cout << "You have shot the zombie in the head. He is dead. " << endl << endl; ++killCount; ++exitLoop; loot = randomNum(2, 15); numBullets = numBullets + loot; cout << "You have found " << loot << " silvered bullets on the" << " dead zombie." << endl; loot = randomNum(2, 15); numStakes = numStakes + loot; cout << "You have found " << loot << " wooden stakes on the " << "dead zombie." << endl; } else { cout << "Sorry, you missed the zombie's head by a distance of " << proximity << " feet." << endl << endl; } numBullets = numBullets - 1; if (numBullets <= 0) { cout << "You are out of silvered bullets and cannot fire any " << "more shots." << endl; cout << "The zombie gets close and bites you." << endl << endl; death = 1; //The player died ++exitLoop; } } while (exitLoop == 0); } else { cout << "The weapon allows the zombie to get too close. He is upon you" << " and bites you." << endl << endl; death = 1; //The player died } return death; } //End zombie() /******************************************************************************* * log function: * * PURPOSE: Drive falling tree encounter where the player can replenish wooden * * stakes * * IN: int for number of stakes * * OUT: Ref. Param: Number of stakes * *******************************************************************************/ void log(int &stakes) { int loot; char pause; loot = randomNum(3, 45); cout << "The tree falls with a loud crash. You notice that several " << "branches can be \nharvested and whittled down into stakes by " << "using your knife. You make " << loot << " stakes." << endl; stakes = stakes + loot; cout << "You now have " << stakes << " stakes." << endl; cout << "Enter any character to continue "; cin >> pause; } //End log() /******************************************************************************* * monsterHunterStory function: * * PURPOSE: Drive main monster hunter game story * * IN: none * * OUT: none * *******************************************************************************/ void monsterHuntStory(void) { int stakeCount, bulletCount, numKills, playerDied; double playerHeight; stakeCount = 3; bulletCount = 25; numKills = 0; playerDied = 0; cout << "Before we begin, how tall are you in feet? "; cin >> playerHeight; cout << "You adventure out into the world with minimal supplies. You " << "have " << stakeCount << " wooden \nstakes, a clockwork pistol " << "with a variable velocity, " << bulletCount << " silvered " << "bullets,\nand a magical knife. " << endl << endl; cout << "You begin wandering through the forest and come across a " << "clearing. In the \nclearing you see something move. It notices " << "you and begins charging. As it \ngets closer you can see what it " << "is. It is "; playerDied = randomMonster(numKills, stakeCount, bulletCount, playerHeight); while (playerDied == 0) { cout << "You continue on your quest and come across something " << "moving in the forest. It is "; playerDied = randomMonster(numKills, stakeCount, bulletCount, playerHeight); } gameOver(); cout << "You killed " << numKills << " monsters." << endl << endl; } //End monsterHuntStory() /******************************************************************************* * randomMonster function: * * PURPOSE: Randomly decide which monster user encounters * * IN: 3 ints: number of each consumable item, kill count, double of player * * height * * OUT: Returns: int for whether player died or lived through encounter, * * Ref. Params: Number of each consumable item remaining, killCount * *******************************************************************************/ int randomMonster(int &killCount, int &numStakes, int &numBullets, double playerHeight) { int monsterType, death; if (killCount == 0) { monsterType = rand() % 4; } else { monsterType = rand() % 5; } if (monsterType == 0) { cout << "a WEREWOLF!" << endl << endl; death = werewolf(numStakes, numBullets, killCount, playerHeight); } else if (monsterType == 1) { cout << "a ZOMBIE!" << endl << endl; death = zombie(numStakes, numBullets, killCount, playerHeight); } else if (monsterType == 2) { cout << "a GHOST!" << endl << endl; death = ghost(numStakes, numBullets, killCount, playerHeight); } else if (monsterType == 3) { cout << "a VAMPIRE!" << endl << endl; death = vampire(numStakes, numBullets, killCount, playerHeight); } else if (monsterType == 4) { cout << "not a creature, but a FALLING TREE!" << endl << endl; log(numStakes); death = 0; } return death; } //End randomMonster() /******************************************************************************* * weapons function: * * PURPOSE: Prompt user to choose weapon to use in encounter * * IN: 2 ints: number of each consumable item * * OUT: Returns: int for user's chosen option * *******************************************************************************/ int weapons(int &numStakes, int &numBullets) { int weaponChoice; do { cout << "Which weapon will you use to defend yourself? " << endl; cout << "(1) Magic Knife" << endl; cout << "(2) Clockwork Gun [" << numBullets << " silvered bullets]" << endl; cout << "(3) Wooden Stake [" << numStakes << " left]" << endl; cin >> weaponChoice; if (weaponChoice < 1 || weaponChoice > 3) { cout << "You must enter an option from 1 to 3." << endl; } } while (weaponChoice < 1 || weaponChoice > 3); return weaponChoice; } //End weapons() /******************************************************************************* * thrownVelocity function: * * PURPOSE: Prompts user for how hard to throw an object * * IN: none * * OUT: Returns: double for throwing velocity * *******************************************************************************/ double thrownVelocity(void) { double velocity; do { cin >> velocity; if (velocity <= 0) { cout << "Velocity must be a positive number, please enter a " << "positive number. "; } else if (velocity > 90) { cout << "You are not superhuman yet, please enter a velocity " << "that is less than 90 MPH."; } } while (velocity <= 0 || velocity > 90); return velocity; } //End thrownVelocity() /******************************************************************************* * difficultyMenu function: * * PURPOSE: Prompts user to choose difficulty level of game * * IN: none * * OUT: Returns: int for chosen difficulty * * ADTNL NOTE: Also gives user option to quit game * *******************************************************************************/ int difficultyMenu(void) { int playerChoice; do { cout << "Please select a difficulty:" << endl; cout << "(1) Easy" << endl; cout << "(2) Medium" << endl; cout << "(3) Hard" << endl; cout << "(4) Exit Game" << endl; cin >> playerChoice; if (playerChoice < 1 || playerChoice > 4) { cout << "That choice was not from 1 to 4. Please enter a choice " << "from 1 to 4." << endl << endl; } } while (playerChoice < 1 || playerChoice > 4); return playerChoice; } //End difficultyMenu() /******************************************************************************* * gameOver function: * * PURPOSE: Display game over screen by keeping main game a little cleaner * * IN: none * * OUT: none * *******************************************************************************/ void gameOver(void) { char wait; cout << "Enter any letter to continue... "; cin >> wait; cout << endl << "You have died... " << endl << endl; cout << " XXXXXX X X X XXXXX" << endl; cout << " X X X X X X X X " << endl; cout << " X XXX XXXXX X X X XXX " << endl; cout << " X X X X X X X " << endl; cout << " XXXXXX X X X X XXXXX" << endl; cout << endl; cout << " XXX X X XXXXX XXX " << endl; cout << " X X X X X X X " << endl; cout << " X X X X XXX XXX " << endl; cout << " X X X X X X X " << endl; cout << " XXX XX XXXXX X X" << endl << endl; } //End gameOver()