/*
* Arup Guha & Puwei Chen (TA for COP 3223 Fall 2006)
* COP 3223 
* Oct 09, 2006
* Edited on 11/3/09 to be solution for COP 3223 2009 Fall Program #4.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

// Used for various user menu choices.
#define ADD 1
#define MULT 2
#define ARITH 1
#define FACTOR 2
#define QUIT 4

double arithGame(int max, int quantity, int op);
int menu();
int numPoints(double timesec);
double factorGame(int max, int quantity);

int main() {

	// Seed the random number generator so we get different games each time.
	srand(time(0) + rand());

	// Show menu and get choice
	int choice = menu();
	int score = 0, whichop = 0, mymax = -1, numprob = -1; 

	// Loop until the user quits.
	while (choice != QUIT) {

		// Arithmetic Game
		if (choice == ARITH) {

			// Find out which skill they want to test. 
			do {
				printf("Would you like, 1)Addition or 2)Multiplication?\n");
				scanf("%d", &whichop);
			} while(whichop != ADD && whichop != MULT);

			// the maximum number in game, should be positive number 
			do {
				printf("What is the maximum positive number you would like?\n");
				scanf("%d", &mymax);
			} while(mymax <= 0);

			// and the number of problems they want. should be positive number 
			do {
				printf("How many problems do you want?\n");
				scanf("%d", &numprob);
			} while(numprob <= 0);  

			// Play the game, calculate the round score and print it. 
			int roundscore = numPoints(arithGame(mymax, numprob, whichop ));
			printf("Your score for the round is %d\n", roundscore);
			score += roundscore;      
		}      

		// Guessing Game
		else if (choice == FACTOR) {

			// Get the range of values for the game. should be positive number
			mymax = 0;
			do {
				printf("Enter the maximum value for a factor.\n"); 
				scanf("%d", &mymax);
			} while(mymax <= 0);
			
			do {
				printf("How many factoring problems do you want?\n");
				scanf("%d", &numprob);
			} while(numprob <= 0);
			
			// Play the game, calculate the round score and print it.
			int roundscore = numPoints(factorGame(mymax, numprob)); 
			printf("Your score for the round is %d\n", roundscore);
			score +=roundscore;

		}

		// Print the user's score.
		else if (choice == 3) { 
			printf("Your score is %d\n", score);      
		}

		choice = menu();
	}

	system("PAUSE");
	return 0;
}

// Plays the arithmetic game with the maximum input operand being max,
// with quantity number of questions. The problems with be using the
// op operation, where op is either ADD or MULT.
double arithGame(int max, int quantity, int op) { 

	int cnt;
	double totaltime = 0, starttime, endtime;

	// Log the start time.
	starttime = time(0);

	// Ask quantity number of questions.
	for (cnt = 1; cnt <= quantity; ++cnt) { 

		// Create two random numbers in the desired range.
		int num1 = rand()%max + 1;
		int num2 = rand()%max + 1;

		int theirans, realans;

		// Print out the problem based on the operation and compute the 
		// correct answer.
		if (op == ADD) {
			printf("What is %d+%d?\n", num1, num2);
			realans = num1 + num2;
		}
		else {
			printf("What is %d*%d?\n", num1, num2); 
			realans = num1 * num2; 
		}   
		scanf("%d", &theirans);

		// Their answer is incorrect! Add five seconds to their score and
		// give them the correct answer. 
		if (theirans != realans) {
			printf("Sorry, that's incorrect, the answer is %d\n", realans);          
			totaltime +=5;
		}

		// They got it! 
		else
			printf("Correct, great job!\n");
	}

	// Check the clock again.
	endtime = time(0);

	// Calculate their total time including penalty seconds. 
	totaltime = totaltime + endtime - starttime;
	printf("You took an average of %lf seconds per question.\n", totaltime/quantity);
	return totaltime/quantity;
}

// Plays the guessing game where the random number for the user to guess
// is in between 1 and max, inclusive.
double factorGame(int max, int quantity) {
       
	int cnt;
	double totaltime = 0, starttime, endtime;

	// Log the start time.
	starttime = time(0);

	// Ask quantity number of questions.
	for (cnt = 1; cnt <= quantity; ++cnt) { 

		// Create two random numbers in the desired range.
		int num1 = rand()%(max-1) + 2;
		int num2 = rand()%(max-1) + 2;

		int ans1, ans2, theirans, realans = num1*num2;
         
		// Print out the problem based on the operation and compute the 
		// correct answer.
	 	
		printf("Please factor %d.\n", realans);
	
		scanf("%d%d", &ans1, &ans2);
        theirans = ans1*ans2;
        
        int correct = 0, numguesses = 1;
        
        while (!correct) {
        
		    // Their answer is incorrect! Add five seconds to their score and
		    // give them the correct answer. 
		    if (theirans != realans) {
			    printf("Sorry, %d x %d does NOT equal %d.\n", ans1, ans2, realans);     
                printf("Please try again.\n");     
                scanf("%d%d", &ans1, &ans2);
                theirans = ans1*ans2;
			    totaltime +=5;
			    numguesses++;
		    }
		
		    // Correct product but not the right factors. Go check both!
		    else if ((ans1 != num1 || ans2 != num2) && (ans1 != num2 || ans2 != num1))  {
                printf("Sorry, that is not the factorization we are loooing for.\n");
                printf("Please try again.\n");
                scanf("%d%d", &ans1, &ans2);
                theirans = ans1*ans2;
                totaltime += 2;
                numguesses++;
            }
        
		    // They got it! 
		    else {
			    printf("Correct, great job!\n");
			    if (numguesses > 1)
			        printf("You got the factorization in %d guesses.\n", numguesses);
			    else
			        printf("You got the factorization in 1 guess.\n");
			        
                correct = 1;
             }
        } // end while correct
	}

	// Check the clock again.
	endtime = time(0);

	// Calculate their total time including penalty seconds. 
	totaltime = totaltime + endtime - starttime;
	printf("You took an average of %lf seconds per question.\n", totaltime/quantity);
	return totaltime/quantity;

}

// Prints out the main menu for the user and returns their answer.
int menu() {
    
	int choice;

	printf("Please make a selection from the following:\n");
	printf("1. Play Arithmetic Game.\n");
	printf("2. Play Factoring Game.\n");
	printf("3. Print Score.\n"); 
	printf("4. Quit.\n");
	scanf("%d", &choice);   

	return choice;
}

// Converts a time value from a game to points the user earns for the game.
int numPoints(double timesec) {

	// If your time score was gte to 10 seconds, you get no points.
	if (timesec >= 10) 
		return 0;

	// Return the score based on the formula given in the problem description.   
	double reverse = 10 - timesec;
	return (int)(ceil(reverse));   
}
