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

double real_random(int done);

double energy(int *p_grid, int dim,  
              double e_11, double e_22, double e_12);

void print_grid(int *p_grid, int dim);

void grow_polymer( int *p_grid, int dim, int ix, int iy, int len);

void make_solvent( int *p_grid, int dim);

main()
{
#define DIM 6
#define TRUE 1
#define FALSE 0
int grid[DIM][DIM];
int len=4;
int iii, irow, icol, ix, iy, ixnew, iynew, id;
int istep, nsteps=100000;
int look, peek=10000, accept, naccept;

double ddd, e_11, e_22, e_12, etot_last, etot, eav;
double p, R, T, RT, deltaE;

R=8.314; T=300; RT= R*T;

printf("T=%8.3f K, RT=%8.3f J/mol\n", T, RT);

e_11= -1.0; e_22= 1.0; e_12= 2;

/* seed random numbers */
ddd = real_random(0);

printf("Hello, Grid DIM = %d\n", DIM);

/*** Convention is that 0 is solvent, 1 is polymer ***/
eav=0.0;
look=peek;
naccept=0;
for (istep=0; istep < nsteps; istep++)
  {

/*** Make everything solvent ***/
     make_solvent(&grid[0][0], DIM); 

/*printf("Filled with solvent:\n"); */
/*print_grid(&grid[0][0], DIM);     */

/*** Choose start point for polymer ***/
    ix=DIM*real_random(1);
    iy=DIM*real_random(1);
    grid[ix][iy]=1;

/*** grow polymer chain ***/
    grow_polymer(&grid[0][0], DIM, ix, iy, len); 

/**** work out energy ****/
    etot= energy(&grid[0][0], DIM, e_11, e_22, e_12);
    if (istep==0) etot_last=etot;

/**** Use Metropolis acceptance criterion ****/    
    deltaE=etot-etot_last;
    
    accept=FALSE;
    if (deltaE <= 0) accept=TRUE;
    else
      {
        p = exp( -1000*deltaE/RT );
        if (real_random(1) < p) accept=TRUE;
/*        printf("deltaE=%6.3f kJ/mol, RT=%6.3f J/mol p=%6.3f\n", deltaE, RT, p); */
      }

    if (accept)
      {
         etot_last=etot;
         eav+=etot;
         naccept++;
      }

/**** print current grid if required ***/
    if (look == 0)
      {
        printf("Polymer conformation step %d:\n", istep);
        print_grid(&grid[0][0], DIM);
        look=peek;
        printf("Total energy for conformation : %10.6f\n", etot);
      }
    look--;
 }
eav = eav/(double) naccept;
printf("\nAverage energy = %10.6f\n", eav);

}
