                /******************************/
				/* elaine chan                */
				/* er-chan@yahoo.com          */
                /* modified for HW4           */
				/*        CSC 142 Lab         */
				/*   Plotting a curve y=f(x)  */
				/*   y on the vertical axis,  */
                /*   x on the horizontal axis */
				/*                            */
				/*                            */
				/* Note: f must be continously*/
				/* increasing or decreasing   */
                /* over the x interval for    */
                /* for the plot.              */
				/*                            */
                /******************************/



/*****************************/
/* Headers for the libraries */
/*****************************/

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <process.h>
#include <ctype.h>
#include <time.h>

/*************************************/
/* Constants and function prototypes */
/*************************************/

/* Parameters for the binary search */
#define MAXITER 1000
#define PRECISION 0.001

/* Number of lines and columns for the graph */
#define LINES 20
#define COLS 70
#define HEIGHT 20.
#define DISTANCE 70.
#define PI 3.14159
#define GRAVITY 9.8
#define FRICTION .5
#define TRUE 1
#define FALSE 0
#define BEFORE 2 /* user about to hit the ball */
#define AFTER 3 /* the user has hit the ball */
#define GREENSIZE 5
#define OUTSIDE  (2.*DISTANCE)
#define WAYBELOW (-2.*HEIGHT)

/* function to plot */
/* double f(double x); */
double f(double x, double data[]);
/* Handy function to plot the graph */
/* Print the character symbol n times */
void repeatChar(char symbol, int n); 
int display(void);
/* Find a solution of y=f(x) in the interval (xleft,xright) */
/* Use a binary search algorithm */
/* double solve(double y, double xleft, double xright); */
   double solve(double y, double xleft, double xright, double data[] ); /* NEW */
/* Plot the graph of f in the interval xmin, xmax */
/* Assume that f is continuously increasing or decreasing */
/* in the interval (xmin, xmax) */
/* void plotCurve(double xmin, double xmax); */
void plotCurve(double xmin,double xmax, double data[] ); /* velocity,angle  */																			                                               
void empty_buffer(void);
/******************************************************************

  Main

*******************************************************************/

int main(void)
{
	/* x interval for the graph */
	double xmin, xmax;
	int green, playAgain,count,hits;
	double	data[3]; /* velocity,angle,green OR hits */
printf(" student Elaine Chan  er-chan@yahoo.com ");

printf("\n\n\n\n\n\n                 Take aim at the green 20 meters below.");
printf("\n*                          You will be asked to enter velocity ");
printf("\n *                             & angle of the golf ball.");
printf("\n   *                           Play computerized miniature golf!      ");
printf("\n     *  ");
printf("\n       * ");
printf("\n         * ");
printf("\n           * ");
printf("\n            * ");
printf("\n            *  ");
printf("\n             *  ");
printf("\n             *  "); 




printf("\n\npress enter to continue ==> ");
empty_buffer();
     
count=0;
hits=0;
playAgain=0;
	 /* new game */
do{
	 
	 system("cls");
	 
	 
	 green=display();
	 data[2]=(double)green;


	do{
	printf("\nEnter (0 to 100 km/sec) velocity ==> ");
	 /*  empty_buffer(); */
	scanf("%lf",&data[0]);
	/* empty_buffer(); */
	if(data[0] < 0. || data[0] > 100.) printf(" velocity out of range   ");
	}while(data[0] < 0. || data[0] > 100.);
	if (data[0]==0) data[0]=0.0001;
	
	
	do{
	printf("Enter declination (0 to 90 degrees) angle ==>");
	/* empty_buffer(); */
	scanf("%lf",&data[1]);
	/*empty_buffer();	*/	
	if( data[1] < 0. || data[1] >90. ) printf("  angle out of range    ");
	}while(data[1] < 0. || data[1] > 90. );
	if (data[1] == 90) data[1] = data[1] - 0.0001;
	
	data[1]= data[1]* PI/ 180. ;
	/* Get the x interval for the graph */

	/* set xmin =0 and xmax = 70  */
	
    
	xmin=0.;
	xmax=70.;
	/* Clear the screen */
	system("cls");
 
	/* Plot the graph on the interval (xmin,xmax) */
	/* plotCurve(xmin, xmax);  NEW */
	 plotCurve(xmin,xmax ,data);
	/* Skip a line for a nice display */
	printf("\n");

	count=count +1;
	hits=(int)( data[2]+.5) + hits;
	printf("score is %d hits out of %d games",hits,count);
	/* data[2] is doing double duty to hold green and hits */
printf("Play again? (0 for no and 1 for yes) ==> ");
scanf("%d",&playAgain);
empty_buffer();
}while(playAgain);




/* new game */



	return EXIT_SUCCESS;
}

/******************************************************************/

 /* Functions */

/*******************************************************************/


void repeatChar(char symbol, int n)
{

	/* print the character symbol n times */

int i;
for (i=1;i <=n;i++)
printf("%c",symbol);

}

double solve(double y, double xleft, double xright, double data[] )
{ 
	/* double solve(double height,double d1, double d2,double velocity,double angle) */
	/* Return the solution of the equation y=f(x)  */
	/* in the interval (xleft,xright) */
	/* Use a binary search */
     
	/* solution of y = f(x) */
	double xsol;

	/* iteration counter */
	int count = 0;

	/* To measure how close we are to the solution */
	/* howClose is y-f(xsol) */

	double howClose;
	
    


	/* If xleft or xright is the solution, 
	   no need to iterate to find it */
	if (fabs(f(xleft,data)-y)<PRECISION)
		return xleft;
	else if
		(fabs(f(xright,data)-y)<PRECISION)
		return xright;
 
	
	/* Start the binary search */
	do 
	{
		/* xsol is the middle point of the search interval */
		xsol=  (xleft + xright) /2.;
		/* Is the solution between xsol and xleft */
		if ( (f(xsol,data)-y)*(f(xleft,data)-y) <=0 )
			/* xsol and xleft are on opposite sides of the solution */
			xright = xsol;
 		else
			/* xsol and xright are on opposite sides of the solution */
			xleft = xsol;

		/* How close are we to the exact solution? */
		howClose = y - f(xsol,data);

		/* next iteration */
		count++;
	}
	while( fabs(howClose) > PRECISION && count <= MAXITER /* Are we done? */);


	/* If we are beyond the maximum of iterations, a problem might have 
	   occured. Print a summary of what happened */
	if (count > MAXITER)
	{
		printf("\nsolve: Maximum of iterations (%i) attained\n",MAXITER);
		printf("Solution so far: %.3f\n",xsol);
		printf("Precision obtained: %.3f\n",howClose);
	}

	return xsol;
}



void plotCurve( double xmin,double xmax,double data[] )
/* void plotCurve(double xmin, double xmax) */
{
	/* Plot the graph of the function f on */
	/* the interval (xmin, xmax) */

    
	int k, green;	
     	


	/* A point on the curve has coordinates (x,y) */
	double x; 
	double y; 
     double scale = 1.;
	
	/* This point is plotted as a star located on a line and 
	   in a column */
	int line, col, lastcol;
	
	/* We assume that f is either increasing or decreasing 
	   on the interval (xmin, xmax) */
	/* ymin and ymax are the maximum and minimum values 
	   on the y axis */
	
	double ymax = max(f(xmin,data),f(xmax,data));
	double ymin = min(f(xmin,data),f(xmax,data));
    lastcol=50;
/*  true for HW4  
	double ymax = f(xmin,data);
	double ymin= f(xmax,data);
*/	


	/* print LINES lines to plot the graph of f */
	for ( line = 0 ; line <= LINES ; line++ )
	{
		/* y value on line with number line */
		/* On line 0, y is ymax     */

		
		/* on line LINES y is ymin  */
		/* Thus, */
		y=ymax+ line*(ymin-ymax)/LINES;

		/* Solve f(x) = y */
/*  
from double solveDistance(double height,double velocity,double angle) 
		"DO NOT CHANGE" */

		if ( f(DISTANCE,data) > y)  x = 2.*DISTANCE; /*OUTSIDE */
		
         else		x = solve(y,xmin,xmax, data); /*NEW */

		
		 
		 /* Number of the column for the corresponding star */
		/* Column 0 corresponds to xmin */
		/* Column COLS corresponds to xmax */
		

		col=(int)(COLS*scale*(x - xmin)/(xmax - xmin) +.5); /* NEW */
		/* Cast the result to an int and use the +0.5 trick */

		/* plot a star in column col */
		if (line ==LINES - 1) lastcol=col;
/* first plot some scale on left */


	if ((LINES-line)%5 ==0 )printf("%2d  m -",LINES-line);
	else printf("      |");

		/* print col spaces and then a "*" */

	if (line!=LINES) {
		repeatChar(' ',col);
		printf("*");} 
		
		
		printf("\n"); 
	}


	green=(int) (data[2]+.05);
 

	

/* bottom of graph  */

	  	repeatChar(' ',green + 7);printf("GREEN");
	printf("\n      +");
		for (k=0;k<7;k++)
		printf("---------+");
	printf("\n      ");
	for (k=1;k<8;k++)
		printf("      %2d m",k*10);
	if((lastcol + 1) >= green && (lastcol + 1) <= green + 4) 
	{printf("\n Wow! a hit!"); /* add to score */
		data[2]=1.;}
	else data[2]=0.;

	
}

double f(double x,double data[])
{
/*  double computeHeight(double distance,double velocity,double angle)  "DO NOT CHANGE " */
	double distance =x;

double height ;
double velocity = data[0];
double angle = data[1];
	
/*  already done
if (velocity == 0) velocity=0.0001;
if(angle == 90) angle = angle -.0001;
angle = angle * PI/180.; 
*/
/* distance = velocity*cos(angle)/FRICTION;  not used */

if (distance >=velocity*cos(angle)/FRICTION) return WAYBELOW; 
/*negative height which cannot appear on the screen */
else {
height=GRAVITY/FRICTION * distance/(velocity*cos(angle))-tan(angle)*distance
      + GRAVITY/pow(FRICTION,2)*log(1-FRICTION*distance/(velocity*cos(angle))) + HEIGHT;




return height; }

/*	return sin(x); */
	/* function to plot 
	return 2*x + 3;
*/
	/* some other functions */
/*  return -2*x + 3;	

	return exp(x);

	return exp(-x);

	return (x+1)*(x+2);*/

}
void empty_buffer(void)
{
	while (getchar() != '\n');
}

int display( void )

{
	
    
	int k, green;	

	
	double scale = 1.;
	
	
	   int line;
	
	  

     
	for ( line = 0 ; line <= LINES ; line++ )
	{
		
/* first plot some scale on left */


	if ((LINES-line)%5 ==0 )printf("%2d  m -",LINES-line);
	else printf("      |");
	if (line ==0 ) printf("    BALL");

		
		/* next line */
		
		printf("\n"); 
	}

	srand((unsigned)time(NULL)); /* seed the random number generator */
	green = rand() % (COLS - GREENSIZE +2);
/* bottom of graph  */
	/* printf(" 0  m -")*/
		repeatChar(' ',green + 7);printf("GREEN");
	printf("\n      +");
		for (k=0;k<7;k++)
		printf("---------+");
	printf("\n      ");
	for (k=1;k<8;k++)
		printf("      %2d m",k*10);
	
	return green;
}
