/* Random sequence generator for classroom drill

   NOTE:  Requires Borland's <conio.h> routines for screen
          position and attributes.

   Alternative included for other environments.

   Author:  Timothy Rolfe

   Language:  C (without any C++ elements), with Borland conio extensions
*/
#include <time.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef __BORLANDC__
#include <conio.h>
#endif

#define SWAP(A,B)  { int t = A; A = B; B = t;  }

#define TOPCORNER

void Shuffle ( int *X, int N );

int Continue ( int Prompt );

int main ( int argc, char* argv[] )
{
   int N, *X = NULL, Idx;
   int Color = 10;
   int More = 1;

   system ( "mode con lines=25" );

#ifdef __BORLANDC__
   clrscr();
#else
   system("cls");
#endif

   srand(time(NULL));

   printf ("Number of participants:  "); fflush(stdout);

   if ( argc > 1 )
   {
      N = atoi(argv[1]);
      printf ("%d\n", N); fflush(stdout);
   }
   else
   {  scanf ("%d", &N); Continue ( 0 );  }

   if ( N < 1 )
   {  puts("No participants.  Exiting."); return 0;  }

   X = (int*) calloc ( N, sizeof *X );

   for ( Idx = 0; Idx < N; Idx++ )
      X[Idx] = Idx + 1;

   Shuffle ( X, N );

#ifdef __BORLANDC__
   clrscr();
   textcolor(15);

   Idx = 0;

#ifdef TOPCORNER
   gotoxy (1,1);
#else
   gotoxy (36, 9);
#endif
   cprintf ("Next up:");

   while (1)
   {
      textcolor(Color);
#ifdef TOPCORNER
      gotoxy ( 3, 3);
      cprintf ( "%2d", X[Idx++] );
      gotoxy ( 1, 5 );
      textcolor(7);
#else
      gotoxy ( 39, 12 );
      cprintf ( "%2d", X[Idx++] );
      gotoxy ( 27, 20 );
      textcolor(7);
#endif
      More = Continue(1);
      if ( Idx == 1 )
      {
#ifdef TOPCORNER
         gotoxy (8, 3);
#else
         gotoxy (38 ,15);
#endif
         textcolor(15);
         cprintf("      ");
      }
      if ( !More ) break;
      if ( Idx == N )
      {
         if (++Color > 15)
            Color = 10;
         Shuffle(X, N);
         Idx = 0;
#ifdef TOPCORNER
         gotoxy (8, 3);
#else
         gotoxy (38 ,15);
#endif
         textcolor(15);
         cprintf("Selah!");
      }
   }
   clrscr();
#else         // Just give the assignments one after the other
   Idx = 0;
   putchar('\n');
   while (1)
   {
      printf ( "\tNext up:  %2d\t", X[Idx++] );
      More = Continue(1);
      if ( !More ) break;
      if ( Idx == N )
      {
         Shuffle(X, N);
         Idx = 0;
         puts("\nNew sequence.\n");
      }
   }
#endif
   fputs("Press <ENTER> to exit.  ", stdout);
   while ( getchar() != '\n' )
      ;
   return 0;
}

void Shuffle ( int *X, int N )
{
   int Idx;

   while ( N > 1 )
   {
      Idx = (int) ( (double)(rand())*N--/(RAND_MAX+1) );
      SWAP ( X[Idx], X[N] );
   }
}

int Continue ( int Prompt )
{
   char Item[255];

   if ( Prompt )
#ifdef __BORLANDC__
      cprintf ("Press ENTER for next (Q quits) ");
#else
      fputs ("Press ENTER for next (Q quits) ", stdout);
#endif

   fgets(Item, 255, stdin);

   return ( 'Q' != toupper(*Item) );
}
