// v1.21 19991011
const char USAGE[] =
"GPL(C):  Mohsin_Ahmed http://www.cs.albany.edu/~mosh " __DATE__ "\n"
"SYNOPSIS: sums - a game for all children to build arithmetic skills.\n"
"USAGE:   sums howmany level\n"
"EXAMPLE: sums 10 1  ... Solve ten sums at level 1.\n"
;

#include <stdlib.h> // for random()
#include <stdio.h>  // for printf()
#include <conio.h>  // for getche()
#include <ctype.h>  // for tolower()
#include <string.h> // for strpbrk()
#include <dos.h>    // for sound()

int
rating(int level,int correct,int tries,int numtries, int t)
{
    float r = (2*correct)/tries * (level*level*correct*10)/(t+1)
        +  tries/numtries;
    return int( r )+1;
}


int min(int i, int j){ return (i>j)? j:i; }
int randomnormal( int level )
{
    int i, x = 0;
    for( i=0; i< min(level,3) ; i++ ) x += random(3);
    for( i=3; i< min(level,6) ; i++ ) x += random(10);
    for( i=6; i< min(level,8) ; i++ ) x += random(50);
    for( i=8; i< min(level,10); i++ ) x += random(100);
    return x;
}

void
makeproblem( int& i, int& j ,int& k, char** op, int level)
{
    i = randomnormal(level);
    j = randomnormal(level);
    k = 0;    
    int lop = random(4);
    if( level <= 2 ) 
        lop = random(2);
    else if( level < 4 )
        lop = random( 3 );

    switch( lop ){
      case 0:
          *op = "+";
          k = i+j;
          break;
      case 1:
          *op = "-";
          if( j > i ){ int t=j; j=i; i=t; }
          k = i-j;
          break;
      case 2:
          *op = "*";
          j = random(10);  // no level;
          k = i*j;
          break;
      case 3:
          *op = "/";
          j = random(10);  // no level;
	  if( i == 0 ) i = 1;
	  if( j == 0 ) j = 1;
          k = i*j;
          { int t=k; k=i; i=t; }
    }
    return;
}
void music(int ok)
{
    for(int i=1;i<5;i++){
        if( ok ) sound(1000 +300*i);
        else     sound(5000-300*i);
        delay(4*i+1);
        nosound();
    }
}
void tune(int num)
{
    num %= 10;
    for(int i=1; i< 8; i++){
        sound(num*30*i+1000); delay(10+i%10); nosound();         
    }
}
int
main(int argc, char * argv[] )
{
    int numtries = 10;
    int level    = 1;
    int tries, correct=0, starttime = time(NULL);
    
    srand(starttime);

    if( argc == 2 && strpbrk(argv[1], "?hH" ) )
        fprintf(stderr,USAGE), exit(0);
    
    if( argc > 1 )
        numtries = atoi(argv[1]);
    if( argc > 2 )
        level = atoi(argv[2]);

    clrscr();
    gotoxy(1,1);
    printf(
    "sums, a game for all children, from http://www.cs.albany.edu/~mosh");
    clreol();
    gotoxy(1,2);
    printf("Do %d sums at level %d, 'q' to quit.",numtries, level);
    clreol();
    for( tries =1; tries <= numtries; tries++ ){
        // make up a problem.
        int i, j, k;
        char* op = "bug";
        makeproblem( i, j, k, &op, level );

        // print the problem.
        gotoxy(1,tries%20 +2+1); clreol(); // next line is blanked.
        gotoxy(1,tries%20 +2); 
        printf("(%2d) %2d %s %2d = ", tries, i, op, j ); clreol();

        // read required number of digits as integer ansk.
        int  ansk = 0;
		#ifdef 1 // scanf allows backspace in answers.
        scanf("%d",&ansk);
		#else	// getche needs no CR after each answer.
        int digits = k; 
        char inchar ='?';
        do{  
            inchar = getche();
            if( tolower(inchar) == 'q' ){
                goto done;
            }
            ansk *= 10;
            digits /= 10;
            ansk += int(inchar)-'0';
            // tune(int(inchar)-'0');
        }while( digits );
		#endif

        correct += ansk == k;
        
        // print the correct answer.
        // music( ansk==k ); 

        gotoxy(22,tries%20 +2); 
        
        printf(" %2s, %3d.", ansk==k?"ok":"no", k ); clreol();
        
        // print statistics at bottom
        gotoxy(1,24); 
        printf(
   "score %d / %d, %d left, rating=%d, level=%d, time=%d seconds.",
   correct, tries, numtries-tries,
   rating(level,correct,tries,numtries,time(NULL)-starttime),
   level,
   time(NULL)-starttime );
        clreol();
    }
 done:
    printf("\n%s", USAGE );
    return 0;
}


