//------------------------------------------------------------------- // File :hw2.C // Author :Alicia Thorsen // Course :CS1129 // Assignment :Hw2 Solution // // Astrology program which takes a user's numeric birthday as input, // then outputs the user's text birthday and Zodiac sign. // It then gives the user a menu with choices to get their daily // horoscope, zodiac profile, and lucky numbers. Displays the same // horoscope and lucky numbers in the same day for each zodiac sign. //------------------------------------------------------------------- #include #include #include using namespace std; // Enumerations. enum Month {JAN=1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC}; enum Zodiac {CAP=1, AQU, PIS, ARI, TAU, GEM, CAN, LEO, VIR, LIB, SCO, SAG}; // # of secs in a day. const int SECS_IN_A_DAY = 86400; // # of sentences to choose from in each category for the horoscope. const int ENTRIES = 4; // Functions. void getBirthDate(int& month, int& day); bool isValidDate(int month, int day); void dispPersData(int month, int day, int sign); int getZodiacSign(int month, int day); void displaySign(int sign); void zodiacProfile(int sign); void horoscope(int sign, int seed); void moneyHoroscope(); void openingLine(); void loveHoroscope(); void healthHoroscope(); void luckyNums(int sign, int seed); // Main Function. int main() { long int seed = 0; // Random number generator seed. int day = 0, month = 0; // User's birthday. int sign = 0; // User's zodiac sign. char quit = 'n'; // Flag to quit. int choice; // User entered menu choice // Get user's birthday. getBirthDate(month, day); // Determine zodiac sign. sign = getZodiacSign(month, day); //Display birthday & sign. dispPersData(month, day, sign); // Calculate random number generator seed. // Use number of days since UNIX epoch, then offset by zodiac sign to produce // different seeds for each sign. seed = (time(0) / SECS_IN_A_DAY) * sign; // Display menu until user quits. do { // Reseed random # gen to get same sequence in one day. srand(seed); cout << "\nASTROLOGICAL MENU\n" << "\t1. Zodiac Profile\n" << "\t2. Daily Horoscope\n" << "\t3. Lucky Numbers\n" << "\t4. Quit\n" << "\nTo view any of the above items, enter the corresponding number: "; cin >> choice; // Call function corresponding to menu choice. switch(choice) { case 1: // Show zodiac profile. zodiacProfile(sign); break; case 2: // Show daily horoscope. horoscope(sign, seed); break; case 3: // Show lucky numbers. luckyNums(sign, seed); break; case 4: // Confirm on quit. cout << "\nAre you sure you would like to quit? (y/n): "; cin >> quit; break; default: // Show error on invalid choice. cout << "\nInvalid menu choice. Please try again.\n"; } // Quit contains 'y' if user confirmed on quit, 'n' otherwise. } while(quit != 'y'); return 0; } // end main(). // ------------------------------------------------------------------- // Precondition :None. // Postcondition :month and day contain the user's birthday. // ------------------------------------------------------------------- void getBirthDate(int& month, int& day) { char slash = '/'; bool correct = false; // Loop until user enters a valid birthday. do { cout << "\nPlease enter your birthday using the m/d format.\n" << "For example, enter 1/15 for Jan 15\n" << "\nBirthday : "; cin >> month >> slash >> day;; // Checks if birthday is valid. correct = isValidDate(month, day); if (!correct) cout << "\nYou have entered an invalid birthday!\n"; } while (!correct); } // end getBirthDate(). // ------------------------------------------------------------------- // Precondition :month and day contains the user's birthday. // Postcondition :Returns true if month and day combination is valid // or false otherwise. // ------------------------------------------------------------------- bool isValidDate(int month, int day) { // Check general month range. if ((month < 1) || (month > 12)) return false; // Check general day range. if ((day < 1) || (day > 31)) return false; // Determine if month and day combination is valid. switch(month) { // Check Feb. // Assume every year is a leap year. case FEB: if (day <= 29) return true; else return false; // Check all months with 30 days. case SEP: case APR: case JUN: case NOV: if (day <= 30) return true; else return false; // All other months have 31 days. // So day is valid because of general day range // check done previously. default: return true; } } // end isValidDate(). // ------------------------------------------------------------------- // Precondition :month and day contains the user's birthday // and sign contains user's zodiac sign. // Postcondition :User's text birthday and zodiac sign is displayed. // ------------------------------------------------------------------- void dispPersData(int month, int day, int sign) { cout << "\nPERSONAL DATA\n\tBirthday : "; // Display text birthday. switch(month) { case JAN: cout << "January"; break; case FEB: cout << "February"; break; case MAR: cout << "March"; break; case APR: cout << "April"; break; case MAY: cout << "May"; break; case JUN: cout << "June"; break; case JUL: cout << "July"; break; case AUG: cout << "August"; break; case SEP: cout << "September"; break; case OCT: cout << "October"; break; case NOV: cout << "November"; break; case DEC: cout << "December"; break; default: // Should not occur. cout << "Month Error!\n"; } cout << " " << day << endl; // Display zodiac sign. cout << "\tZodiac Sign : "; displaySign(sign); cout << endl; } // end dispPersData(). // ------------------------------------------------------------------- // Precondition :month and day contains the user's birthday. // Postcondition :Returns user's zodiac sign. // ------------------------------------------------------------------- int getZodiacSign(int month, int day) { // Determine user's zodiac sign. switch(month) { case JAN: if (day <= 20) return CAP; else return AQU; case FEB: if (day <= 19) return AQU; else return PIS; case MAR: if (day <= 20) return PIS; else return ARI; case APR: if (day <= 20) return ARI; else return TAU; case MAY: if (day <= 21) return TAU; else return GEM; case JUN: if (day <= 21) return GEM; else return CAN; case JUL: if (day <= 22) return CAN; else return LEO; case AUG: if (day <= 21) return LEO; else return VIR; case SEP: if (day <= 23) return VIR; else return LIB; case OCT: if (day <= 23) return LIB; else return SCO; case NOV: if (day <= 22) return SCO; else return SAG; case DEC: if (day <= 22) return SAG; else return CAP; default: // Should not occur. cout << "Month Error!\n"; return CAP; } } // end getZodiacSign(). // ------------------------------------------------------------------- // Precondition :sign contains user's zodiac sign. // Postcondition :User's text zodiac sign is displayed. // ------------------------------------------------------------------- void displaySign(int sign) { switch(sign) { case CAP: cout << "Capricorn"; break; case AQU: cout << "Aquarius"; break; case PIS: cout << "Pisces"; break; case ARI: cout << "Aries"; break; case TAU: cout << "Taurus"; break; case GEM: cout << "Gemini"; break; case CAN: cout << "Cancer"; break; case LEO: cout << "Leo"; break; case VIR: cout << "Virgo"; break; case LIB: cout << "Libra"; break; case SCO: cout << "Scorpio"; break; case SAG: cout << "Sagittarius"; break; default: // Should not occur. cout << "Zodiac Sign Error!"; } } // end displaySign(). // ------------------------------------------------------------------- // Precondition :sign contains user's zodiac sign. // Postcondition :User's zodiac profile is displayed. // ------------------------------------------------------------------- void zodiacProfile(int sign) { cout << "\n---------- Zodiac Profile ---------- \n"; cout << endl; // Display user's text zodiac sign. displaySign(sign); // Display profiles. switch(sign) { case CAP: cout << " - The Goat\n" << "\tPractical and prudent\n" << "\tAmbitious and disciplined\n" << "\tPatient and careful\n" << "\tHumorous and reserved\n"; break; case AQU: cout << " - The Water Carrier\n" << "\tFriendly and humanitarian\n" << "\tHonest and loyal\n" << "\tOriginal and inventive\n" << "\tIndependent and intellectual\n"; break; case PIS: cout << " - The Fishes\n" << "\tImaginative and sensitive\n" << "\tCompassionate and kind\n" << "\tSelfless and unworldly\n" << "\tIntuitive and sympathetic\n"; break; case ARI: cout << " - The Ram\n" << "\tAdventurous and energetic\n" << "\tPioneering and courageous\n" << "\tEnthusiastic and confident\n" << "\tDynamic and quick-witted\n"; break; case TAU: cout << " - The Bull\n" << "\tPatient and reliable\n" << "\tWarmhearted and loving\n" << "\tPersistent and determined\n" << "\tPlacid and security loving\n"; break; case GEM: cout << " - The Twins\n" << "\tAdaptable and versatile\n" << "\tCommunicative and witty\n" << "\tIntellectual and eloquent\n" << "\tYouthful and lively\n"; break; case CAN: cout << " - The Crab\n" << "\tEmotional and loving\n" << "\tIntuitive and imaginative\n" << "\tShrewd and cautious\n" << "\tProtective and sympathetic\n"; break; case LEO: cout << " - The Lion\n" << "\tGenerous and warmhearted\n" << "\tCreative and enthusiastic\n" << "\tBroad-minded and expansive\n" << "\tFaithful and loving\n"; break; case VIR: cout << " - The Virgin\n" << "\tModest and shy\n" << "\tMeticulous and reliable\n" << "\tPractical and diligent\n" << "\tIntelligent and analytical\n"; break; case LIB: cout << " - The Scales\n" << "\tDiplomaitic and urbane\n" << "\tRomantic and charming\n" << "\tEasygoing and sociable\n" << "\tIdealistic and peaceable\n"; break; case SCO: cout << " - The Scorpion\n" << "\tDetermined and forceful\n" << "\tEmotional and intuitive\n" << "\tPowerful and passionate\n" << "\tExciting and magnetic\n"; break; case SAG: cout << " - The Archer\n" << "\tOptimistic and freedom-loving\n" << "\tJovial and good-humored\n" << "\tHonest and straightforward\n" << "\tIntellectual and philosophical\n"; break; default: // Should not occur. cout << "Zodiac Sign Error!\n"; } cout << "\n------------------------------------\n"; } // end zodiacProfile(). // ------------------------------------------------------------------- // Precondition :sign contains user's zodiac sign, seed contains // seed for random number generator. // Postcondition :User's randomly generated daily horoscope is // displayed. // ------------------------------------------------------------------- void horoscope(int sign, int seed) { cout << "\n---------- Daily Horoscope ---------- \n"; // Start each horoscope with user's sign. cout << endl; displaySign(sign); cout << ", "; // Create horoscope from 4 categories. openingLine(); moneyHoroscope(); loveHoroscope(); healthHoroscope(); cout << "\n------------------------------------\n"; } // end horoscope(). // ------------------------------------------------------------------- // Precondition :None. // Postcondition :Opening line of horoscope is displayed. // ------------------------------------------------------------------- void openingLine() { // Randomly choose sentence to display. int item = rand() % ENTRIES; switch(item) { case 0: cout << "your clever wit will be much in evidence as the " << "day begins.\n"; break; case 1: cout << "you're quite perceptive today and you'll have " << "good insights into what makes others tick.\n"; break; case 2: cout << "you may be making some innovative changes around " << "the home today.\n"; break; case 3: cout << "you'll be serious in outlook today, with an eye " << "for getting things accomplished.\n"; break; default: // Should not occur. cout << "Error in random number generator!\n"; } } // end openingLine(). // ------------------------------------------------------------------- // Precondition :None. // Postcondition :Money part of horoscope is displayed. // ------------------------------------------------------------------- void moneyHoroscope() { // Randomly choose sentence to display. int item = rand() % ENTRIES; switch(item) { case 0: cout << "Career hopes could escalate; hard work and " << "sacrifice will be needed.\n"; break; case 1: cout << "Where money is concerned, try not to argue. Meet " << "others halfway.\n"; break; case 2: cout << "A money delay is finally over.\n"; break; case 3: cout << "Watch for an important turning point in business, " << "perhaps a new job or assignment.\n"; break; default: // Should not occur. cout << "Error in random number generator!\n"; } } // end moneyHoroscope(). // ------------------------------------------------------------------- // Precondition :None. // Postcondition :Love part of horoscope is displayed. // ------------------------------------------------------------------- void loveHoroscope() { // Randomly choose sentence to display. int item = rand() % ENTRIES; switch(item) { case 0: cout << "You should avoid taking chances or speculating, " << "especially in romance.\n"; break; case 1: cout << "An unusual person becomes your friend.\n"; break; case 2: cout << "Find a more sensible approach to your romantic life " << "and stick with it.\n"; break; case 3: cout << "Tonight, a gift or favor may be just the thing you " << "have been looking for.\n"; break; default: // Should not occur. cout << "Error in random number generator!\n"; } } // end loveHoroscope(). // ------------------------------------------------------------------- // Precondition :None. // Postcondition :Health part of horoscope is displayed. // ------------------------------------------------------------------- void healthHoroscope() { // Randomly choose sentence to display. int item = rand() % ENTRIES; switch(item) { case 0: cout << "Take advantage of your good spirits and escalated " << "energy levels today.\n"; break; case 1: cout << "Keep plans and activities on the simple side, since " << "energy levels deplete quickly.\n"; break; case 2: cout << "Your mental energies are strong now and you'll be " << "quick to act on your ideas.\n"; break; case 3: cout << "It's time to moderate your food and alcohol " << "consumption and diet a little.\n"; break; default: // Should not occur. cout << "Error in random number generator!\n"; } } // end healthHoroscope(). // ------------------------------------------------------------------- // Precondition :sign contains user's zodiac sign, seed contains // seed for random number generator. // Postcondition :5 unique randomly generated numbers are displayed. // ------------------------------------------------------------------- void luckyNums(int sign, int seed) { int nums[5], x, i = 0; bool duplicate; cout << "\n---------- Lucky Numbers ---------- \n\n"; // Display user's sign. displaySign(sign); cout << " : "; // Generate 5 numbers. while (i < 5) { x = (rand() % 50) + 1; duplicate = false; for (int j = 0; j < i && !duplicate; ++j) if (nums[j] == x) duplicate = true; if (!duplicate) { nums[i] = x; i++; cout << x << " "; } } cout << "\n\n------------------------------------\n"; } // end luckyNums().