/********************************************************
*                                                       *
*  Brenda Sonderegger                Sept. 23, 1998     *
*                                                       *
*  Assignment 3  Guessing Game                          *
*                                                       *
*  Description: Generates a random number between 1 and *
*               a user defined high value.  Then has the*
*               user try to guess the number.  It keeps *
*               score and tells the user how many tries *
*               were needed to guess the number.        *
*                                                       *
********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


void print_header(void);
void play_game(int high);
void print_menu(void);
void get_int_bound(int *, int, int);
void get_int_low(int *, int); 
int get_random(int, int);

void main(void)
{
  int number, guess, attempts = 0;
  int choice, high = 100;

  print_header();
  do
  {
    print_menu();
    get_int_bound(&choice, 1, 3);
    switch(choice)
    {
      case 1: printf("\nEnter a value >= 1 ");
              get_int_low(&high, 1);
              printf("\nYour new high value is %d");
      case 2: play_game(high);
              break;
      case 3: printf("\nThanks for playing.\n\n");    
    } 
  }
  while (choice != 3);
}

void print_header(void)
{
  printf("\n\nWelcome to guessing game.\n");
  printf("\nI will think of a number between 1 and 100 or ");
  printf("\nyou may choose some other high value.\n\n");
}

void print_menu(void)
{
  printf("\n\n1 - Input a high value ");
  printf("\n2 - Play game ");
  printf("\n3 - Quit ");
  printf("\n\nEnter your selection ");
}

void play_game(int high)
{
  int value, guess, num_guesses = 0;

  value = get_random(1, high);
  printf("\nI'm thinking of a number between 1 and %d\n", high);
  do
  {
    printf("\nEnter your guess ");
    get_int_bound(&guess, 1, high);
    num_guesses++;
    if (guess < value)
       printf("\nToo low - try again ");
    else if (guess > value)
       printf("\nToo high - try again ");
    else
       printf("\nYou got it in %d guesses.\n", num_guesses);
  }
  while (value != guess);
}

   /*****************************************************
   * void get_int(int *value)                           *
   * Author: Brenda Sonderegger                         *
   * Last Modified: Sept. 22, 1998                      *
   * Parameters: single address                         * 
   * Return value: none                                 *
   * Side Effect: puts an integer value into the memory *
   *              location specified by the address and *
   *              if an error occurs, the input stream  *
   *              is emptied                            *
   * Description: guarantees that the input value is an *
   *              integer.  Inputs of a, 23c, 2.4 are   *
   *              all considered to be illegal          *
   *****************************************************/
void get_int(int *value)
{
  int iochar, error_check;

  do
  {
    error_check = scanf("%d", value);
    if (error_check != 1)
    {
      printf("\nError - not an integer. Try again. ");
      while ((iochar = getchar()) != '\n');
    }
    else
    {
      iochar = getchar();
      if (! isspace(iochar))
      {
        printf("\nError - not an integer. Try again. ");
        while ((iochar = getchar()) != '\n');
        error_check = 0;
      } 
    }
  }
  while (error_check != 1);
}



   /*****************************************************
   * void get_int_low(int *value, int low)              *
   * Author: Brenda Sonderegger                         *
   * Last Modified: Sept. 16, 1998                      *
   * Parameters: single address, and single integer     * 
   * Return value: none                                 *
   * Side Effect: puts an integer value into the memory *
   *              location specified by the address that*
   *              if guaranteed to be greater than or   *
   *              equal to the low value                *
   * Description: guarantees that the input value is an *
   *              integer greater than or equal to low  *
   * Functions called: get_int()                        *
   *****************************************************/
void get_int_low(int *value, int low)
{
   do
   {
     get_int(value);
     if (*value < low)
        printf("\nValue must be &gt;= %d.  Try again.\n", low);
   }
   while (*value < low);
}


   /*****************************************************
   * void get_int_bound(int *value, int low, int high)  *
   * Author: Brenda Sonderegger                         *
   * Last Modified: Sept. 16, 1998                      *
   * Parameters: single address, and two integers       * 
   * Return value: none                                 *
   * Side Effect: puts an integer value into the memory *
   *              location specified by the address that*
   *              if guaranteed to be greater than or   *
   *              equal to the low value and less than  *
   *              or equal to the high value            *
   * Description: guarantees that the input value is an *
   *              integer greater than or equal to low  *
   *              and less than or equal to high        *
   * Functions called: get_int()                        *
   *****************************************************/
void get_int_bound(int *value, int low, int high)
{
   do
   {
     get_int(value);
     if ((*value < low) || (*value > high))
        printf("\nValue must be between %d and %d, inclusive.  Try again.\n", 
                low, high);
   }
   while ((*value < low) || (*value > high));
} 
 


   /*****************************************************
   * int get_random(int low, int high)                  *
   * Author: Brenda Sonderegger                         *
   * Last Modified: Sept. 23, 1998                      *
   * Parameters: two integers                           *
   * Return value: random integer between low and high  *
   * Side Effect: none                                  *
   * Description: guarantees that the returned value is *
   *              between low and high inclusively      *
   * Functions called: from stdlib.h                    *
   *                       srand()                      *
   *                       rand()                       *
   *                   from time.h                      *
   *                       time()                       *
   *                                                    *
   *****************************************************/
int get_random(int low, int high)
{
   static int seeded = 0;
   int random;

   if (seeded == 0)
   {
     srand((unsigned)time((time_t *) NULL));
     seeded = 1;
   } 
   random = rand() % (high - low + 1) + low;

   return (random);
}