/***************************************************************************
 * FILE: ser_pi_calc.c
 * DESCRIPTION:  
 *   Serial pi Calculation - C Version
 *   This program calculates pi using a "dartboard" algorithm.  See
 *   Fox et al.(1988) Solving Problems on Concurrent Processors, vol.1
 *   page 207.  
 * AUTHOR: unknown
 * REVISED: 02/23/12 Blaise Barney
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>

//void srandom (unsigned seed);  
double dboard (int darts);

#pragma CIVL $output double __pi;

#define DARTS 1   	/* number of throws at dartboard */
#define ROUNDS 1    	/* number of times "darts" is iterated */

int main(int argc, char *argv[])
{
double pi;          	/* average of pi after "darts" is thrown */
double avepi;       	/* average pi value for all iterations */
int i, n;

printf("Starting serial version of pi calculation using dartboard algorithm...\n");
srandom (5);            /* seed the random number generator */
avepi = 0;
for (i = 0; i < ROUNDS; i++) {
   /* Perform pi calculation on serial processor */
   pi = dboard(DARTS);
   avepi = ((avepi * i) + pi)/(i + 1); 
   printf("   After %3d throws, average value of pi = %10.8f\n",
         (DARTS * (i + 1)),avepi);
   }
#pragma CIVL __pi = avepi;    
printf("\nReal value of PI: 3.1415926535897 \n");
}


/*****************************************************************************
 * dboard
 *****************************************************************************/
#define sqr(x)	((x)*(x))
long random(void);

double dboard(int darts)
{
   double x_coord,       /* x coordinate, between -1 and 1  */
          y_coord,       /* y coordinate, between -1 and 1  */
          pi,            /* pi  */
          r;             /* random number scaled between 0 and 1  */
   int score,            /* number of darts that hit circle */
       n;
   unsigned int cconst;  /* must be 4-bytes in size */
/*************************************************************************
 * The cconst variable must be 4 bytes. We check this and bail if it is
 * not the right size
 ************************************************************************/
   /*if (sizeof(cconst) != 4) {
      printf("Wrong data size for cconst variable in dboard routine!\n");
      printf("See comments in source file. Quitting.\n");
      exit(1);
      }*/
   /* 2 bit shifted to MAX_RAND later used to scale random number between 0 and 1 */
   cconst = 9;
   score = 0;

/***********************************************************************
 * Throw darts at board.  Done by generating random numbers
 * between 0 and 1 and converting them to values for x and y
 * coordinates and then testing to see if they "land" in
 * the circle."  If so, score is incremented.  After throwing the
 * specified number of darts, pi is calculated.  The computed value
 * of pi is returned as the value of this function, dboard.
 ************************************************************************/

   for (n = 1; n <= darts; n++) {
      /* generate random numbers for x and y coordinates */
      r = (double)random()/cconst;
      x_coord = (2.0 * r) - 1.0;
      r = (double)random()/cconst;
      y_coord = (2.0 * r) - 1.0;

      /* if dart lands in circle, increment score */
      if ((sqr(x_coord) + sqr(y_coord)) <= 1.0)
         score++;
      }

   /* calculate pi */
   pi = 4.0 * (double)score/(double)darts;
   return(pi);
} 
