/*==========================================================================*/
/*                                                                          */
/*       Random Walks                                                       */
/*                                                                          */
/*       PROGRAM NAME:     walk                                             */
/*                                                                          */
/*       CALLING SEQUENCE:                                                  */
/*                                                                          */
/*         Main program without command line arguments.                     */
/*                                                                          */
/*       RETURN:                                                            */
/*                                                                          */
/*         Type int       - Retrun code                                     */
/*                                                                          */
/*   Version 1.00                                                           */
/*                                                                          */
/*   (c) Satoru Ozawa and Dieter W. Heermann                                */
/*   Hitachi, Heidelberg July 1994                                          */
/*                                                                          */
/*==========================================================================*/

/* ==== Program constants ==== */

# define l_max           800

/* ==== Include files for this program ==== */

# include <math.h>
# include <stdio.h>

# include "sgl.h"               /* include for the graphics library */
# include "mod.c"               /* modulo random number generator   */


#ifdef  __STDC__
void    main(int argc, char *argv[])
#else
void    main(argc,argv)
        int     argc;
        char    *argv[];
#endif
  {
    /* -------------------------------------------------------------------- */
    /*                        Declarations                                  */
    /* -------------------------------------------------------------------- */

    int    i,j, sample, l;
    int    N;
    int    d; 
    int    x,y, xc, yc;
    int    sample_size;
    int    return_code;
    int    modul,multi,inc,seed;
    int    OffLattice;

    float  *ran;
    int    *XWalk, *YWalk;

    void ShowWalk();
    /* -------------------------------------------------------------------- */
    /*                       End of Declarations                            */
    /* -------------------------------------------------------------------- */

    /* -------------------------------------------------------------------- */
    /*                Read in the simulation parameters                     */
    /* -------------------------------------------------------------------- */

    /* ====  Print the header for this program ==== */


    printf("======================================================\n");
    printf("======>  Random Walks on the Square Lattice   <=======\n");
    printf("======================================================\n");
    printf("\n\n");
    printf("(c) Satoru Ozawa and Dieter W. Heermann \n");
    printf("Version 1.00 (1994) \n");
    printf("\n\n");

    printf("Length of random walk (N)        = ");
    scanf("%d",&N);
    printf("Sample size                      = ");
    scanf("%d",&sample_size);
    printf("Seed for Random Number Generator = ");
    scanf("%d",&seed);

    printf("Initializing the graphics ...");

    sgl_winsize(l_max,l_max);
    sgl_init();

    printf("done\n");

    /* -------------------------------------------------------------------- */
    /*                    Set and Initialize                                */
    /* -------------------------------------------------------------------- */

    xc     = (l_max - 1) / 2;
    yc     = (l_max - 1) / 2;
    sample = 0;
    modul  = 2147483647;
    multi  = 16807;
    inc    = 0;

    /* ==== Grep the storage for the random numbers and the ==== */
    /* ==== distribitions.                                  ==== */

    ran = (float *) calloc(N, sizeof(float));
    if ( ran == NULL ) {
        printf("Out of memory: exit code -1\n");
        printf("Resize your request\n");
        exit(-1);
    }
    seed       = (seed << 2) + 1;

    /* ==== will hold the random walk coordinates ==== */

    XWalk = (int *) calloc(N, sizeof(float));
    YWalk = (int *) calloc(N, sizeof(float));
    if ( XWalk == NULL || YWalk == NULL ) {
        printf("Out of memory: exit code -1\n");
        printf("Resize your request\n");
        exit(-1);
    }

    /*----------------------------------------------------------------------*/
    /*                    Begin of Sample Loop                              */
    /*----------------------------------------------------------------------*/

    while ( sample < sample_size) {

      /* ==== Reset the walker to the origin ==== */

      for(i=0; i < N; i++) {
           XWalk[i] = YWalk[i] = 0;
      }

      XWalk[0]  = xc;
      YWalk[0]  = yc;
      x         = xc;
      y         = yc;
      l         = 0;
      seed      = seed + 1;
      OffLattice = 0;

      return_code = ModGenerator(modul,multi,inc,seed,N,ran);

      while ( l < N )  {           /* generate one random walk       */
        d  = (int) (ran[l] * 4);
        switch (d) {                 /* decide which direction to take */
            case 0:  x++;
                     break;

            case 1:  y++;
                     break;

            case 2:  x--;
                     break;

            case 3:  y--;
                     break;
        }
        if ( (x < 0) || (x > l_max-1) || (y < 0) || (y > l_max-1 )) {
            printf("walk went off the lattice at step %d\n",l);
            OffLattice = l;
            l = N;
        }
        else {
            XWalk[l] = x;
            YWalk[l] = y;
            l++;
        }
      } /* end of while loop */

      if ( OffLattice ) l = OffLattice;
      ShowWalk(XWalk,YWalk,l);
      printf("Hit return to continue");
      i = getchar();
      sample++;
    }
} /* end of main program */

#ifdef  __STDC__
void ShowWalk(
  int *x,
  int *y,
  int n)
#else
void ShowWalk(x, y, n)
  int *x;
  int *y;
  int n;
#endif
 {
    int i;
    float scale;

    scale = l_max;

    sgl_color_background(SGL_BLACK);
    for(i=0; i < n; i++) {
        if ( i > 0 ) {
            sgl_line((float) x[i-1]/scale, (float) y[i-1]/scale,
                     (float) x[i]/scale,   (float) y[i]/scale);
            }
    /*      sgl_rectarea((float) x[i], (float) y[i], .01,.01);  */
    }
    sgl_display();
}
