/****************************************************************************** * bio.c - A Biorhythm Analysis Program * * * * Author : Jeff Mercer * * * * Purpose: This program is a biorhythmic analysis and compatibility program. * * It takes input from the user about a person (name and birthdate) * * and is able to use that information to generate biorhythms for * * that person. Multiple report formats are supported, as well as * * output to file, screen, or printer. * * This program can also do a "compatibility" check between two * * people to see how well (or poorly) their biorhythms are synced. * * * * Platform: All original code, written in Borland C++ under Win95. The * * target platform is 16-bit DOS. * * * * Copyright 1997, 1999 by Jeff Mercer. All rights reserved. This source code * * may be freely distributed and compiled, but may not be sold, modified, or * * utilized for profit without express written consent of the author. * * * Disclaimer: I make no claims or promises on the reliability, accuracy, or * * connection to reality of these calculations and readings. This * * program was developed soley for educational purposes. * * * ******************************************************************************/ /***************************************************************************** Preliminary Stuff *****************************************************************************/ /* Include all necessary libraries */ #include #include #include /* Macro definitions */ #define TRUE 1 /* Boolean values */ #define FALSE 0 /* Boolean values */ #define STRLEN 20 /* Standard string variable length */ #define MAX_MENU_CHOICE 4 /* Maximum number of choices in the output menu */ #define SCREEN_LENGTH 25 /* Number of lines in the standard display */ /* Data type declarations */ typedef unsigned char Bool; typedef struct {int year; int month; int day;} Date; typedef struct {char firstname[STRLEN+1]; char lastname[STRLEN+1]; Date bdate;} PersonType; typedef struct {int phys; int emot; int intel; char p; char e; char i;} BioType; typedef struct {int pcom; int ecom; int icom;} CompatType; /*********************** * Function prototypes * ***********************/ /* Input functions */ PersonType GetPerson(void); Date GetDate(void); /* Output functions */ void BlankDisplay(void); void PrintBioHeader(FILE *); void PrintADaysBio(BioType, Date, int, long, FILE *); void GiveDailyReading(PersonType, Date, FILE *); void PrintAMonthsBio(PersonType, Date, FILE *); void DoMultiMonthBio(PersonType, Date, int, FILE *); /* File input/output functions */ FILE *GetOutputType(void); /* Date functions */ long MJulianDay(Date); long DayDiff(Date, Date); int DayOfWeek(Date); int ZSign(Date); /* Biorhythm functions */ BioType CalcBiorhythm(Date, Date); CompatType CalcCompat(Date, Date); void CompatLookup(CompatType, char *, char *, char *); int InterpBiorhythm(BioType); /* Menu functions */ void DispOutputMenu(void); int OutputMenuChoice(void); void DoOutputMenu(int, PersonType, FILE *); void DoOutMenuOpt1(PersonType, FILE *); void DoOutMenuOpt2(PersonType, FILE *); void DoOutMenuOpt3(PersonType, FILE *); void DoOutMenuOpt4(PersonType, FILE *); /* Days of the week static strings */ const char *dowword[]={"Wednesday", "Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "unknown"}; /* Names of the month static strings */ const char *monthname[]={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "unknown"}; /* Zodiac names static strings */ const char *zodiacname[]={"Capricorn", "Aquarius", "Pisces", "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "unknown"}; /* Static interpretation code strings */ const char *peicode[]={"CCC", "CC+", "CC-", "C+C", "C++", "C+-", "C-C", "C-+", "C--", "+CC", "+C+", "+C-", "++C", "+++", "++-", "+-C", "+-+", "+--", "-CC", "-C+", "-C-", "-+C", "-++", "-+-", "--C", "--+", "---"}; /* Static interpretation paragraph strings */ const char *interpretation[]={ "On this day, all three of the rhythms pass through a zero, and each one\n" "begins a new phase. It is a time to stay calm and take things easy. Extreme\n" "caution in involvement and judgement is required. This is an accident-prone\n" "day.", "Both the Physical and Emotional rhythms on this day are under stress and\n" "strain. All deliberations should be made with extra care. Your Intellectual\n" "high favors clear thinking. This is an accident-prone day.", "At this time, as a result of both your Emotional and Physical rhythms being\n" "in the critical position, you are exposed to a sluggish disposition. This\n" "condition, coupled with a low in the Intellectual cycle, should encourage you\n" "to take special care to avoid trouble. This is an accident-prone day.", "In this phase, the critical day in your Intellectual rhythm serves to\n" "intensify your critical disposition Physically. It is a time for you to allow\n" "your favorable Emotional disposition to guide you. This is an accident-\n" "prone day.", "This is a time of tremendous instability and a spent quality for you\n" "physically. Compensation can be obtained from your high Emotional and\n" "Intellectual condition. This is an accident-prone day.", "Though you may feel spend Physically, your Emotions are in plus. This\n" "should provide some assistance to the Physically critical condition you are\n" "in. Awareness is required for you to take steps to adjust to and to\n" "overcome your Intellectual low. This is an accident-prone day.", "You are characterized by a Physical condition that is dead beat, on a\n" "crossover. It is possible that you feel down and low Emotionally. This day\n" "could be very trying and exceptionally enervating, especially since you are\n" "also at zero point in your Intellectual rhythm. This is an accident-prone\n" "day.", "The only fortunate thing about your condition this day is the Intellectual\n" "plus you will be operating under. You probably will feel wiped out\n" "Physically because of the critical status of this cycle. Emotionally, there\n" "will be depression. This is an accident-prone day.", "Lows in both your Emotional and Intellectual rhythms will further intensify\n" "the tired-out feeling that characterizes this day--a critical day for you\n" "Physically. This is an accident-prone day.", "This is a day for you to think before you act in general, the Physical\n" "plus indicates that you will have ample energy and endurance, but you may\n" "feel depressed Emotionally and Intellectually with both these rhythms at\n" "zero. This is an accident-prone day.", "At this time, a state of well being will influence your actions and your\n" "thinking, since your Physical and Intellectual rhythms are at plus.\n" "However, guard your Emotions--you may feel weary and lethargic. This is an\n" "accident-prone day.", "Though operating under a Physical plus, it is counter-balanced and offset\n" "this day by a critical day in your Emotions. It is necessary to think twice\n" "to avoid problems and pitfalls. Your Intellectual rhythms are coasting.\n" "This is an accident-prone day.", "It is a potent, positive, primed day for you Physically and Emotionally.\n" "However, with your Intellectual rhythm in critical, it is highly imperative\n" "that you carefully monitor your thinking. This is an accident-prone day.", "Triple plus--today is your day! this is an outstanding period, with all\n" "three rhythms in high. Take full advantage of this time and seize the\n" "moment. It is a day when you can go all out.", "Good cheer and brimming vitality are yours on this excellent day. You\n" "should be feeling very good The only caution might be that, because of the\n" "low in your Intellectual rhythm, you should weigh all decisions with the\n" "utmost care.", "It is a good time for you to concentrate on Physical activity, especially\n" "tasks that do not require much concentration. You may feel down\n" "Emotionally, and you should take into consideration the critical condition\n" "of your Intellectual rhythm. This is an accident-prone day.", "The only inopportune aspect of an otherwise fine phase is the minus\n" "Emotional rhythm. You should try not to let the blue feeling that can\n" "possibly derive from your Emotional rhythm affect you. Concentrate as much\n" "as possible on Physical activity. It is a good time for thinking, for\n" "decision making, for study--you are in top form Intellectually.", "From a Physical point of view, all things should be possible. You can go\n" "all out. However, you must guard your Emotions. Since your Intellectual\n" "rhythm is negative, carefully ponder and review all decisions.", "On this type of day, all kinds of things can happen to an unwary person.\n" "Extra caution is indicated, almost obligatory. Intellectual and Emotional\n" "critical signifies handicaps in ?? of themselves. Coupled with a\n" "Physical low, all activities must be undertaken with extreme preparedness.\n" "This is an accident-prone day.", "The best approach to behavior on a day such as this--a Physical low and\n" "an Emotional critical, both creating conditions making you feel weary and\n" "blue--is for you to utilize your Intellectual high and allow it to dominate\n" "your action. This is an accident-prone day.", "This is a day for you to just take it as easy as possible. Avoid hasty\n" "decisions and attempt to obtain as much as rest as possible. You will find\n" "your system sapped by physical fatigue with the Physical low. You will\n" "also feel uninspired as a result of your Emotional rhythm being at a cross\n" "point. It is not a day to be feared as much as it is a day to be guided by\n" "caution. This is an accident-prone day.", "You can concentrate on making this a good day as a result of the positive\n" "Emotional rhythm that should characterize your system. Physically you are\n" "below par, out of sorts and Intellectually you are at the zero point, but\n" "your Emotional cycle can help you through this day if you let it. This is\n" "an accident-prone day.", "You will have a tired feeling that evolves from your Physical low. It can\n" "easily be offset if you take advantage of your high Emotional and excellent\n" "Intellectual condition. Avoid physical activities, but enjoy other life\n" "pursuits.", "A low-pitched day for you Physically and Intellectually. The best thing to\n" "do is concentrate on your capacity for creative work and take advantage of\n" "your plus Emotional rhythm.", "In this condition, recharging your system is prescribed. You will find it\n" "to be a slow day, you are down Physically and Emotionally. Vitality and\n" "vigor are lacking. Be conscious of the effects of the zero position in your\n" "Intellectual rhythm and guard against it. This is an accident-prone day.", "A good book, cheerful company, a movie or any type of pleasant diversion\n" "might help you make it through this type of day more easily. You will find\n" "that your feet are dragging and that you feel down int he dumps. However,\n" "your positive in the Intellectual rhythm will enable you to think clearly.\n" "Take it easy and take advantage of your mind's capacity to enjoy the\n" "stimulation of diversion.", "This time is an interlude of calm--Physical, Emotional, Intellectual. Strive\n" "to shake off the anxieties of the triple low. Relax with the thought that\n" "better days are not far away.", "An error occurred during interpretation. You should never see this message."}; /***************************************************************************** The Main Event *****************************************************************************/ /****************************************************************************** * main - The main function of the entire program. * * * * Here is the function that is always executed first when the program is run. * * This function primarily just calls other functions. It gets input from the * * user, presents a menu, performs tasks based on menu selections and gives * * output. * * * * Inputs: none. * * * * Outputs: * * o Returns a zero when the program exits. * * * ******************************************************************************/ int main(void) { /* Declare variables */ PersonType per1; int choice; char c; Bool quit=FALSE; FILE *fp; /* Clear the screen */ BlankDisplay(); /* Print welcoming banner */ printf(" Welcome to the Biorhythm-o-Rama Program!\n\n"); /* Get necessary information for our target person in all transactions */ printf("Please enter a first name, last name, and birthdate for the person\n" "you want to do biorhythms of.\n\n"); per1=GetPerson(); /* The main loop. As long as the user hasn't chosen to quit... */ while (!quit) { /* Clear the screen */ BlankDisplay(); /* Display the output selections menu */ DispOutputMenu(); /* Get a valid choice from the user */ choice=OutputMenuChoice(); /* Find out where they want output to go and get a stream to that device */ fp=GetOutputType(); /* Perform the menu selection they chose */ DoOutputMenu(choice, per1, fp); /* Close the output stream */ fclose(fp); /* Clear the keyboard buffer */ getchar(); /* Find out if they want more output */ printf("\nDo you want to do more output(Y/n)? "); scanf("%c", &c); /* Nope, they want to quit */ if (c=='n' || c=='N') quit=TRUE; } /* Say goodnight, Gracie... */ BlankDisplay(); printf("Thanks for playing! Have a nice day. :)\n\n"); /* Nothing important to return. Program ends. */ return 0; } /***************************************************************************** Input Functions *****************************************************************************/ /***************************************************************************** * GetPerson - Gets vital information about a person for. * * * * This function gets the necessary information about a person to be able to * * calculate his biorhythm. The info are returned as a result of the function.* * * * Inputs: * * o None. * * * * Outputs: * * o A structure of the type Person, which consists of: * * o An array of characters for the first name. * * o An array of characters for the last name. * * o A structure of the type Date. * * * *****************************************************************************/ PersonType GetPerson(void) { /* Declare local variable */ PersonType per; /* Initialize variables */ per.firstname[0]=per.lastname[0]='\0'; /* Get first name from user */ printf("Enter first name: "); scanf("%s", per.firstname); /* Get last name from user */ printf("Enter last name: "); scanf("%s", per.lastname); /* Get the target's birthdate */ per.bdate=GetDate(); /* Return the results */ return per; } /***************************************************************************** * GetDate - Gets a Gregorian format date from the user and returns it. * * * * This function gets a date from the user of the standard Gregorian calendar * * type. It performs some simple validation of the date entered, and only * * returns a date that is valid. * * * * Inputs: * * o None. * * * * Outputs: * * o A structure of the type Date, which consists of: * * * *****************************************************************************/ Date GetDate(void) { /* Declare local variable */ Date adate; Bool bad; /* Get date from user. Loop if the date is an invalid one */ do { bad=FALSE; printf("Enter date (in yyyy/mm/dd form): "); scanf("%d/%d/%d", &adate.year, &adate.month, &adate.day); /* Check to see if any of the dates are invalid */ if (adate.year<0) bad=TRUE; else if (adate.month<1 || adate.month>12) bad=TRUE; else if (adate.day<1 || adate.day>31) bad=TRUE; /* Tell user if they entered a bad date */ if (bad) printf("Incorrect or invalid date entered. Please try again.\n"); } while (bad==TRUE); /* Return the results */ return adate; } /***************************************************************************** Output Functions *****************************************************************************/ /****************************************************************************** * BlankDisplay - A simple function to clear the screen. * * * * All this function does is clear the screen. The method used is to simply * * print numerous blank lines. The advantage is this is a highly portable * * method (platform independent). The disadvantage is that the cursor * * position is at the bottom instead of the top. * * * * Inputs: none * * * * Outputs: none * * * ******************************************************************************/ void BlankDisplay(void) { /* Declare local variable */ int i; /* Print enough blank lines to clear the screen */ for (i=0; i * * * *****************************************************************************/ long MJulianDay(Date gdate) { /* Declare and initialize variables */ double j=0; /* Add on eight millennia to the Gregorian year to simplify calculations */ gdate.year+=8000; /* Since leap days are added at the end of February, it makes sense to consider January and February as the last two months (numbered 13 and 14) of the previous year. That way, leap days are always added at the end of the notional year. */ if (gdate.month<3) { gdate.year--; /* Last year */ gdate.month+=12; /* Notional month */ } /* Ready to begin calculations, we start with the year precision. */ /* 365 days per year, plus one extra day every four years... */ j=gdate.year*365l+(gdate.year/4); /* ...except for every 100 years that is not also evenly divisible by 400 years, *except* for every 4000 years... */ j=j-(gdate.year/100)+(gdate.year/400)-(gdate.year/4000); /* Correct for the eight millennia offset added on earlier */ j=j-1200818l; /* Year precision has been reached, now we move on to month precision. This formula allows for a quick computation that bypasses tedious use of switching and/or arrays. :) */ j=j+(gdate.month*153+3)/5-92; /* Month precision has been reached, just add date specified and subtract 1 for date-of-month precision. This gives us the traditional Julian day date. */ j=j+gdate.day-1; /* Return the Modified form of the Julian day. This gives a more compact number that is easier to read and also corrects for the new day starting at noon in the Julian calendar system. */ j=j-2400000.5f; return j; } /****************************************************************************** * DayOfWeek - Give the day of the week for a given Gregorian date * * * * The function takes a standard Gregorian date and returns the day of the * * week for that date. * * * * Inputs: * * o A structure of the type Date, which consists of: * * o Whole year in integer form (i.e. 1997, not 97) as "year". * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o Day of the week is returned as an integer. The actual string is then * * looked up from a static array of day names. * * * ******************************************************************************/ int DayOfWeek(Date gdate) { /* Declare and initialize our variables */ int day=0; long j; /* Get the Julian day for the specified date */ j=MJulianDay(gdate); /* A week is seven days long, so we divide the Julian day form of the given date and take the remainder to determine what day of the week it was. This is possible because we know what day of the week the Julian calendar started on. */ day=(int)(j % 7); /* Just in case something didn't work, make sure we're sane */ if (day<0 || day>6) day=7; /* Return the result */ return day; } /****************************************************************************** * ZSign - Return the zodiac sign for a given date * * * * This function takes a standard Gregorian date (year/month/date) and gives * * the Zodiac sign for that date. The year value is actually irrelevant and * * can be initialized to anything, but must be present. * * * * Inputs: * * o A structure of the type Date, which consists of: * * o Whole year in integer form (i.e. 1997, not 97) as "year". * * (NOTE: This value is irrelevant to the function but is left in for * * internal consistency) * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o An integer representing a Zodiac sign is returned. This can then be * * to look up the actual Zodiac name in a static array of strings. * * * * Notes: * * The following is a table of the zodiac signs and their date ranges, as * * well as the arbitrary value that I've assigned to each sign. * * * * Capricorn Dec 22-Jan 19 1 * * Aquarius Jan 20-Feb 18 2 * * Pisces Feb 19-Mar 20 3 * * Aries Mar 21-Apr 19 4 * * Taurus Apr 20-May 20 5 * * Gemini May 21-Jun 21 6 * * Cancer Jun 22-Jul 22 7 * * Leo Jul 23-Aug 22 8 * * Virgo Aug 23-Sep 22 9 * * Libra Sep 23-Oct 23 10 * * Scorpio Oct 24-Nov 21 11 * * Sagitarius Nov 22-Dec 21 12 * * * ******************************************************************************/ int ZSign(Date adate) { /* Declare and initialize our variables */ int z=0; /* Here we check to see what month we've been given to check, and then see if the day of that month falls before or after a specific dividing point. Based on those two checks we assign a value to z that represents the zodiac sign for the given date. */ switch (adate.month) { /* January */ case 1:if (adate.day<20) z=0; else z=1; break; /* February */ case 2:if (adate.day<19) z=1; else z=2; break; /* March */ case 3:if (adate.day<21) z=2; else z=3; break; /* April */ case 4:if (adate.day<20) z=3; else z=4; break; /* May */ case 5:if (adate.day<21) z=4; else z=5; break; /* June */ case 6:if (adate.day<22) z=5; else z=6; break; /* July */ case 7:if (adate.day<23) z=6; else z=7; break; /* August */ case 8:if (adate.day<23) z=7; else z=8; break; /* September */ case 9:if (adate.day<23) z=8; else z=9; break; /* October */ case 10:if (adate.day<24) z=9; else z=10; break; /* November */ case 11:if (adate.day<22) z=10; else z=11; break; /* December */ case 12:if (adate.day<22) z=11; else z=0; break; /* Something very wrong */ default:z=12; break; } /* Return the result */ return z; } /****************************************************************************** * DayDiff - Return the difference in number of days between two dates * * * * This is a very simple function that takes two date inputs and then * * subtracts the second date (ending date) in Julian Day form from the first * * date (starting date) in Julian Day form and returns the difference. * * * * Inputs: * * o Two structures of the type Date, which consists of: * * o Whole year in integer form (i.e. 1997, not 97) as "year". * * (NOTE: This value is irrelevant to the function but is left in for * * internal consistency) * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o The difference in days between the two dates, as a long. * * * ******************************************************************************/ long DayDiff(Date adate1, Date adate2) { /* Return the difference between the two input dates */ return MJulianDay(adate2)-MJulianDay(adate1); } /***************************************************************************** Biorhythm Functions *****************************************************************************/ /****************************************************************************** * CalcBiorhythm - Calculate the biorhythm of a person for a particular date. * * * * This function determines a person's biorhythm for a given day, both as the * * actual values for the three cycles as well as the overall status of each * * cycle (gaining, losing, or critical). * * * * Inputs: * * o Two structures of the type Date, which consists of: * * o Whole year in integer form (i.e. 1997, not 97) as "year". * * (NOTE: This value is irrelevant to the function but is left in for * * internal consistency) * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * The first date is a birthdate, the second date is the day the biorhythm * * should be calculated for. * * * * Outputs: * * o A structure of the type BioType, which consists of: * * o Physical cycle value in integer form. * * o Emotional cycle value in integer form. * * o Intellectual cycle value in integer form. * * o Physical cycle status (+, -, or C) as a char. * * o Emotional cycle status (+, -, or C) as a char. * * o Intellectual cycle status (+, -, or C) as a char. * * * ******************************************************************************/ BioType CalcBiorhythm(Date bdate, Date adate) { /* Declare local variables */ BioType abio; long days; /* Figure out how many days old the person is/was/will be on the given date */ days=DayDiff(bdate, adate); /* Calculate actual biorhythm cycle values for each cycle */ abio.phys=(int)days % 23; /* Physical cycle */ abio.emot=(int)days % 28; /* Emotional cycle */ abio.intel=(int)days % 33; /* Intellectual cycle */ /* Here we look at each cycle value and determine if the person is gaining energy (negative or -), expending energy (positive or +), or on the tightrope between the two (Critical or C). The result is stored as a single character that represents the "status" for that cycle on that day. */ abio.p=(abio.phys<12 ? '+' : (abio.phys>12 ? '-' : 'C' ) ); abio.e=(abio.emot<14 ? '+' : (abio.emot>14 ? '-' : 'C' ) ); abio.i=(abio.intel<17 ? '+' : (abio.intel>17 ? '-' : 'C' ) ); /* All done. Return the results. */ return abio; } /****************************************************************************** * InterpBiorhythm - Interpret the biorhythm of a person * * * * This function interprets the biorhythm of a person for a given day, which * * must be already calculated. The interpretation is an integer code which * * is used to determine what textual interpretation to use. * * * * Inputs: * * o A structure of the type BioType, which consists of: * * o Physical cycle value in integer form. * * o Emotional cycle value in integer form. * * o Intellectual cycle value in integer form. * * o Physical cycle status (+, -, or C) as a char. * * o Emotional cycle status (+, -, or C) as a char. * * o Intellectual cycle status (+, -, or C) as a char. * * * * Outputs: * * o Returns an integer representing the interpretation of the biorhythm. * * * ******************************************************************************/ int InterpBiorhythm(BioType abio) { int i=0; char pei[4]; /* Create a short string out of the Biorhythm codes for comparison purposes */ pei[0]=abio.p; pei[1]=abio.e; pei[2]=abio.i; pei[3]='\0'; /* Check to see if codes match an existing interpretation */ for (i=0; i<27; i++) if (strcmp(pei, peicode[i])==0) break; /* Return the result */ return i; } /****************************************************************************** * CalcCompat - Calculate the biorhythmic compatibility of two people. * * * * This function determines the compatibility of two people by figuring out * * the difference between each of their cycles. That info can then be used to * * determine compatibility quality (Good, Fair, Poor) for each cycle. * * * * Inputs: * * o Two structures of the type Date, which consists of: * * o Whole year in integer form (i.e. 1997, not 97) as "year". * * (NOTE: This value is irrelevant to the function but is left in for * * internal consistency) * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * The first date is the birthdate of the first person, and the second date * * is the birthdate of the second person. * * * * Outputs: * * o A structure of the type CompatType, which consists of: * * o Physical cycle difference in integer form. * * o Emotional cycle difference in integer form. * * o Intellectual cycle difference in integer form. * * * ******************************************************************************/ CompatType CalcCompat(Date bdate1, Date bdate2) { /* Declare the local variables */ BioType per1, per2; CompatType cpat; Date adate; /* We need to get a sample biorhythm for each person. A reference date is thus needed. */ adate.year=1997; adate.month=7; adate.day=29; /* Calculate the sample biorhythms for both people */ per1=CalcBiorhythm(bdate1, adate); per2=CalcBiorhythm(bdate2, adate); /* Determine the absolute difference between each cycle for the two people. */ cpat.pcom=abs(per1.phys-per2.phys); /* Physical cycle difference */ cpat.ecom=abs(per1.emot-per2.emot); /* Emotional cycle difference */ cpat.icom=abs(per1.intel-per2.intel); /* Intellectual cycle difference */ /* We're done. Return the results */ return cpat; } /****************************************************************************** * CompatLookup - Lookup the compatibility ratings for two people. * * * * This function looks up the compatibility ratings (Good, Fair, Poor, etc) * * of two people based on their biorhythmic compatibility. The actual values * * for the compatibility must be calculated before this function is called. * * * * Inputs: * * o A structure of the type CompatType, which consists of: * * o Physical cycle difference in integer form. * * o Emotional cycle difference in integer form. * * o Intellectual cycle difference in integer form. * * * * Outputs: * * o Three evaluations of compatibility, one for each cycle. These are * * copied directly into strings by pointers that are passed into the * * CompatLookup function when it is called. * * * ******************************************************************************/ void CompatLookup(CompatType cpat, char *p, char *e, char *i) { const char prate[][9+1]={"Excellent", "Excellent", "Excellent", "Good", "Good", "Average", "Average", "Fair", "Fair", "Fair", "Poor", "Poor", "Poor", "Poor", "Fair", "Fair", "Fair", "Average", "Average", "Good", "Good", "Excellent", "Excellent", "Excellent"}; const char erate[][9+1]={"Excellent", "Excellent", "Excellent", "Good", "Good", "Good", "Average", "Average", "Average", "Fair", "Fair", "Fair", "Poor", "Poor", "Poor", "Poor", "Poor", "Fair", "Fair", "Fair", "Average", "Average", "Average", "Good", "Good", "Good", "Excellent", "Excellent", "Excellent"}; const char irate[][9+1]={"Excellent", "Excellent", "Excellent", "Excellent", "Good", "Good", "Good", "Average", "Average", "Average", "Fair", "Fair", "Fair", "Fair", "Poor", "Poor", "Poor", "Poor", "Poor", "Poor", "Fair", "Fair", "Fair", "Fair", "Average", "Average", "Average", "Good", "Good", "Good", "Excellent", "Excellent", "Excellent", "Excellent"}; strcpy(p, prate[cpat.pcom]); strcpy(e, erate[cpat.ecom]); strcpy(i, irate[cpat.icom]); } /***************************************************************************** Menu Functions *****************************************************************************/ /****************************************************************************** * DispOutputMenu - A simple function that displays an output choice menu. * * * * All this function does is display a menu of choices for what sort of output * * a user wants for their biorhythm. It does nothing else. * * * * Inputs: none * * * * Outputs: none * * * ******************************************************************************/ void DispOutputMenu(void) { /* Nothing to declare */ /* Print the output options menu and prompt */ printf(" Output Options Menu\n"); printf(" =====================\n"); printf("1. Do a full biorhythm reading and interpretation for a given day.\n"); printf("2. Do a months worth of biorhythm readings for a given month.\n"); printf("3. Do a range of months worth of biorhythm readings.\n"); printf("4. Do a compatibility check for two people.\n"); printf("\nEnter your choice: "); /* Nothing to return */ } /****************************************************************************** * OutputMenuChoice - Get a menu choice from the user and return it. * * * * This function reads a menu choice from the user for the Output options menu * * and then returns the choice as an integer. Validation is performed on the * * choice to make sure it is valid. * * * * Inputs: None * * * * Outputs: * * o Returns an integer for the menu choice the user selected. * * * ******************************************************************************/ int OutputMenuChoice(void) { /* Declare and initialize local variable */ int i=0; /* As long as a valid choice has not been entered... */ while (i<1 || i>MAX_MENU_CHOICE) { /* Get a choice from the user */ scanf("%d", &i); /* Is it valid? */ if (i<1 || i>MAX_MENU_CHOICE) /* No, so print a warning and reprint input prompt */ printf("Invalid choice. Please try again.\nEnter your choice:"); } /* Return the validated choice */ return i; } /****************************************************************************** * DoOutputMenu - Perform the operation that the user selected from the menu. * * * * With this function we perform the action that the user selected from the * * Output options menu. Additional input, if needed, is taken in this function * * and passed into the necessary output functions. When done, the function * * prompts the user to press return to continue. * * * * Inputs: * * o An integer representing which menu choice to execute. * * o A structure of the type PersonType, which consists of: * * o A string for the person's first name. * * o A string for the person's last name. * * o A structure of the type Date to hold their birthdate, which consists of:* * o Whole year in integer form (i.e. 1997, not 97) as "year". * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o No values are returned or stored. * * * ******************************************************************************/ void DoOutputMenu(int i, PersonType p, FILE *fp) { /* Depending on what the user selected... */ switch (i) { /* Option #1, a full reading and analysis */ case 1:DoOutMenuOpt1(p, fp); break; /* Option #2, a months worth of readings */ case 2:DoOutMenuOpt2(p, fp); break; /* Option #3, a whole bunch of months worth of readings! */ case 3:DoOutMenuOpt3(p, fp); break; /* Option #4, do a compatibility check between two people */ case 4:DoOutMenuOpt4(p, fp); break; /* No valid choice, give error */ default:printf("Error! Invalid menu choice was received.\n"); } /* Nothing to return */ } /****************************************************************************** * DoMenuOpt1 - Performs selection #1 from the Output Menu choices. * * * * This function performs option #1 from the Output Menu: generating a full * * biorhythm reading for a person for a specific date, with interpretation. * * * * Inputs: * * o A structure of the type PersonType, which consists of: * * o A string for the person's first name. * * o A string for the person's last name. * * o A structure of the type Date to hold their birthdate, which consists of:* * o Whole year in integer form (i.e. 1997, not 97) as "year". * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o No values are stored or returned. * * * ******************************************************************************/ void DoOutMenuOpt1(PersonType aper, FILE *fp) { /* Declare our local variables */ Date d; /* Print input prompt and get date for reading */ printf("\nPlease enter the exact the date you want the reading for:\n"); d=GetDate(); /* Clear the display */ BlankDisplay(); /* Give the detailed reading for the specified date */ GiveDailyReading(aper, d, fp); /* Nothing to return */ } /****************************************************************************** * DoMenuOpt2 - Performs selection #2 from the Output Menu choices. * * * * This function performs option #2 from the Output Menu: generating a full * * months worth of biorhythm readings for a person, for any month of any year. * * * * Inputs: * * o A structure of the type PersonType, which consists of: * * o A string for the person's first name. * * o A string for the person's last name. * * o A structure of the type Date to hold their birthdate, which consists of:* * o Whole year in integer form (i.e. 1997, not 97) as "year". * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o No values are stored or returned. * * * ******************************************************************************/ void DoOutMenuOpt2(PersonType aper, FILE *fp) { /* Declare local variables */ Date d; /* Print input prompt and get date for reading */ printf("Please enter the month and year you want the reading for:\n"); d=GetDate(); /* Clear display */ BlankDisplay(); /* Print what month these readings are for */ fprintf(fp, "Biorhythm readings for the month of %s, %d:\n", monthname[d.month-1], d.year); /* Print the nice biorhythm reading header */ PrintBioHeader(fp); /* Display the biorhythm readings for the entire specified month */ PrintAMonthsBio(aper, d, fp); /* Nothing to return */ } /****************************************************************************** * DoMenuOpt3 - Performs selection #3 from the Output Menu choices. * * * * This function performs option #3 from the Output Menu: generating a range * * of months worth of biorhythm readings for a specific person. All months * * in the range must be in the same year. * * * * Inputs: * * o A structure of the type PersonType, which consists of: * * o A string for the person's first name. * * o A string for the person's last name. * * o A structure of the type Date to hold their birthdate, which consists of:* * o Whole year in integer form (i.e. 1997, not 97) as "year". * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o No values are stored or returned. * * * ******************************************************************************/ void DoOutMenuOpt3(PersonType aper, FILE *fp) { /* Declare local variables */ Date d; int m; /* Get the starting month and year */ printf("Enter the starting month and year for the range.\n"); do { /* Input prompt */ printf("Enter date (yyyy/mm): "); /* Read in the month and year from the user */ scanf("%d/%d", &d.year, &d.month); /* If an invalid month is entered, give an error */ if (d.month<1 || d.month>12) printf("Invalid month entered. Try again.\n"); /* Loop as long as there's not a valid month given */ } while (d.month<1 || d.month>12); /* Initialize day of month to one */ d.day=1; /* Get the ending month of the range */ printf("Enter an ending month (more than %d, up to 12) for the range:", d.month); scanf("%d", &m); /* Make sure a valid month was entered. If not, use the starting month */ if (m12) m=d.month; /* Clear the display */ BlankDisplay(); /* Do the whole range of months worth of readings */ DoMultiMonthBio(aper, d, m, fp); /* Nothing to return */ } /****************************************************************************** * DoMenuOpt4 - Performs selection #4 from the Output Menu choices. * * * * This function performs option #4 from the Output Menu: a compatibility * * report between two people. This is not dependant on a specific date except * * for birthdates. * * * * Inputs: * * o A structure of the type PersonType, which consists of: * * o A string for the person's first name. * * o A string for the person's last name. * * o A structure of the type Date to hold their birthdate, which consists of:* * o Whole year in integer form (i.e. 1997, not 97) as "year". * * o Month in integer form (1=January, 2=February, etc) as "month". * * o Date in integer form as "day". * * * * Outputs: * * o No values are stored or returned. * * * ******************************************************************************/ void DoOutMenuOpt4(PersonType p1, FILE *fp) { /* Declare local variables */ PersonType p2; CompatType com; char pword[STRLEN+1], eword[STRLEN+1], iword[STRLEN+1]; /* Clear the screen */ BlankDisplay(); /* Prompt for and get info for second person */ printf("Please enter the name and birthdate of the person you wish to\n"); printf("compare to %s %s:\n", p1.firstname, p1.lastname); p2=GetPerson(); /* Calculate the compatibility for these two bozos */ com=CalcCompat(p1.bdate, p2.bdate); /* Lookup the meaning of the compatibility we calculated */ CompatLookup(com, pword, eword, iword); /* Clear the screen */ BlankDisplay(); /* Print the header for the compatibility report */ fprintf(fp, "Compatibility report for %s %s (%02d/%02d/%d)\n" "and %s %s (%02d/%02d/%d):\n", p1.firstname, p1.lastname, p1.bdate.month, p1.bdate.day, p1.bdate.year, p2.firstname, p2.lastname, p2.bdate.month, p2.bdate.day, p2.bdate.year); fprintf(fp, "===================================================\n"); /* Print the actual compatibility report */ fprintf(fp, " Physical compatibility rating: %02d -- %s\n", com.pcom, pword); fprintf(fp, " Emotional compatibility rating: %02d -- %s\n", com.ecom, eword); fprintf(fp, "Intellectual compatibility rating: %02d -- %s\n", com.icom, iword); }