#include <iostream>
#include <string>
#include <vector>
using namespace std;
/* Prototype all the happy lil functions we get to use, woo! */
void menuPrint();
bool dateInvalid(int year=1900, int month=1, int day=1);
void playLeapYear();
bool leapYear(int year);
void playZodiac();
string zodiac(int year);
void playDayOfWeek();
int julian(int year, int month, int day);
string dayOfWeek(int year, int month, int day);
void playSols();
vector<int> sols(int year, int month, int day);
int main()
{
string menuChoice;
while (true)
{
menuPrint();
cin >> menuChoice;
if ((menuChoice == "q") || (menuChoice == "-1"))
{
break;
}
else if (menuChoice == "1")
{
playLeapYear();
}
else if (menuChoice == "2")
{
playZodiac();
}
else if (menuChoice == "3")
{
playDayOfWeek();
}
else
{
cout << "FIXME" << endl;
}
}
return 0;
}
void menuPrint()
{
/* For printing the program menu */
cout << "\nMain Menu — Enter an item's menu-number or input q or -1 to "
"exit the program \n"
" 1) Leap years \n"
" 2) Zodiac \n"
" 3) Day of the week \n"
" 4) Martian Calendar \n"
" 5) Square (by value) \n"
" 6) Square (reference) \n"
" 7) Square (by pointer) \n" << endl;
}
void playLeapYear()
{
/* The "leap year" game */
int year = 0;
cout << "Leap year:" << endl;
while (dateInvalid(year))
{
cout << "Please enter a year 1900 or later:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> year;
}
cout << year << " is" << (leapYear(year) ? "" : " not") << " a leap year.";
cout << endl;
}
bool leapYear(int year)
{
/* Returns true if a year is a leap year, returns false otherwise */
if (year % 4 != 0)
{ // Years that aren't divisible by 4 arent' leap years.
return false;
} // All years past here are divisible by 4
else if (year % 100 != 0)
{ // 4th years which aren't divisble by 100 are always leap
return true;
} // All years past here are divisble by 4 and 100.
else if (year % 400 != 0)
{ // Years divisible by 4 and 100 but not by 400 aren't leap years
return false;
}
else
{ // All years divisible by 4, 100, and 400 are leap years.
return true;
}
}
bool dateInvalid(int year, int month, int day)
{
/* Returns true if the given date is invalid. Defaults to valid date. */
bool yearInvalid = (year < 1900);
bool monthInvalid = (month < 1 || month > 12);
int monthMax;
switch(month)
{
case 2:
monthMax = (leapYear(year) ? 29 : 28);
break;
case 4:
case 6:
case 9:
case 11:
monthMax = 30;
break;
default:
monthMax = 31;
break;
}
bool dayInvalid = ((day < 1) || (day > monthMax));
return (yearInvalid || monthInvalid || dayInvalid);
}
void playZodiac()
{
/* The "zodiac game" */
int year = 0;
cout << "Zodiac:" << endl;
while(dateInvalid(year))
{
cout << "Please enter a year 1900 or later" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> year;
}
cout << year << " is the year of the " << zodiac(year) << ". " << endl;
}
string zodiac(int year)
{
/* Return a string representing the zodiac animal for year. Function reduces
years to a 12-year cycle starting at 1900, the year of the rat. */
switch((year - 1900) % 12)
{
case 0: return "rat";
case 1: return "ox";
case 2: return "tiger";
case 3: return "rabbit";
case 4: return "dragon";
case 5: return "snake";
case 6: return "horse";
case 7: return "goat";
case 8: return "monkey";
case 9: return "rooster";
case 10: return "dog";
case 11: return "pig";
default: return "unknown";
}
}
void playDayOfWeek()
{
/* The "Day of the Week" game */
int year = 0;
int month = 0;
int day = 0;
cout << "Day of the Week:" << endl;
while (dateInvalid(year, month, day))
{
cout << "Please enter a date 01-01-1900 or later. Use MM DD YYYY format.";
cout << endl;
cout << "Month:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> month;
cout << "Day:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> day;
cout << "Year:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> year;
}
cout << month << "-" << day << "-" << year << " falls on a ";
cout << dayOfWeek(year, month, day) << endl;
}
int julian(int year, int month, int day)
{
/* Where 1900-01-01 is 1, 1900-01-02 is 2, and so on */
int julianDate = 0;
// lDays is used for leap years, cDays is used for common years.
// These vectors represent the sum of the days in all previous months.
vector<int> lDays = {0,31,60,91,121,152,182,213,244,274,305,335,366};
vector<int> cDays = {0,31,59,90,120,151,181,212,243,273,304,334,365};
// yDays is equal to cDays on a common year or lDays on a leap year.
vector<int> yDays = leapYear(year) ? lDays : cDays;
for(int i = 1900; i < year; i++)
{
julianDate += leapYear(i) ? 366 : 365;
}
julianDate += yDays.at(month-1);
julianDate += day;
return julianDate;
}
string dayOfWeek(int year, int month, int day)
{
/* Returns the day of the week of a given date as a string */
/* We Subtract 1 from our julian date so that 1900-01-01 is 0. There
is no real reason to do this other than that Monday is CLEARLY
the start of the week and deserves to be 0, not 1. */
int julianDate = julian(year, month, day) - 1;
julianDate %= 7;
switch(julianDate)
{
case 0: return "monday";
case 1: return "tuesday";
case 2: return "wednesday";
case 3: return "thursday";
case 4: return "friday";
case 5: return "saturday";
case 6: return "sunday";
default: return "unknown";
}
}
void playSols()
{
int year = 0;
int month = 0;
int day = 0;
cout << "Martian Calendar:" << endl;
while (dateInvalid(year, month, day))
{
cout << "Please enter a date 01-01-1900 or later. Use MM DD YYYY format.";
cout << endl;
cout << "Month:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> month;
cout << "Day:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> day;
cout << "Year:" << endl;
cin.clear(); cin.ignore(10000, '\n');
cin >> year;
}
cout << "FIXME";
}
vector<int> sols(int year, int month, int day)
{
int marsJulian = julian(year, month, day) / 1.027;
int marsYear = marsJulian / 672;
int marsMonth = (marsJulian - marsYear * 672) / 56;
int marsDay = (marsJulian - marsYear * 672 - marsMonth * 56);
Comments