// L-7 MCS 360 Wed 8 Sep 2010 : guess_character.cpp

/* The program below generates a sequence of random characters
   and then prompts the user to make a guess for a character to
   occur in the generated sequence.

The search function looks for a given character in the string,
returns -1 if the character does not occur, or otherwise return
the position in the string of the first occurrence.

The purpose of this program is to illustrate the use of assert
to enforce preconditions and postconditions of the functions. */

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cassert>

using namespace std;

char random_char();
/*
   Generates a lower case alphanumeric character,
   uniformly distributed at random.

   Postcondition: 
      96 < int(random_char()) < 123.  */

string random_string ( int n );
/*
   Returns a random string of n
   lower case alphanumeric characters.

   Precondition: n >= 0.
   Postcondition: if s = random_string(n),
      then s.length() == n and for all k
      in 0..n-1: 96 < int(s[k]) < 123. */

int search ( string s, char c );
/*
   Searches the string s for the character c.

   Postcondition: if r == search(s,c), then
      either r == -1 if 
        for all k in 0..s.length()-1: s[k] != c,
      or 0 <= r < s.length() and s[r] == c. */

int main()
{
   const int L = 10;
   string s = random_string(L);
   cout << "generated \"" << s << "\"" << endl;

   char guess;
   cout << "Make a guess : ";
   cin >> guess; cout << guess;

   int index = search(s,guess);
   if(index == -1)
      cout << " does not occur";
   else
      cout << " is at position " << index;
   cout << " in string \"" << s << "\"" << endl;

   return 0;
}

char random_char()
{
   const int m = int('z') - int('a') + 1;
   const int r = int('a') + rand() % m;
   const char c = char(r);

   assert(int(c) > 96 && int(c) < 123);

   return c;
}

string random_string ( int n )
{
   string result = "";

   assert(n>=0);
   
   srand(time(0));
   for(int i=0; i<n; i++)
      result = result + random_char();

   assert(result.length() == n);
   for(int i=0; i<n; i++)
      assert(int(result[i]) > 96
          && int(result[i]) < 123);
  
   return result;
}

int search ( string s, char c )
{
   int result = -1;

   for(int i=0; i<s.length(); i++)
      if(s[i] == c)
      {
         result = i; break;
      }

   assert(result >= -1 ||
          result < s.length());
   if(result > -1)
      assert(s[result] == c);
   else
      for(int i=0; i<s.length(); i++)
         assert(s[i] != c);      

   return result;
}

