// mpi.cpp : definisce il punto di ingresso dell'applicazione console.
//

#include "stdafx.h"


int main(int argc, char* argv[])
{
	
	int my_id, numprocs,length;
	 int sendb,receiveb, dest,readb,getb;
	 int in=0,out=0,MAXEVENTS;
	char name[BUFSIZ];
	MPI_Comm com;
	MPI_Win pwin,gwin;
	MPI_Init(&argc, &argv) ;                    // Chiamata obbligatoria di inizializzazione	
	MPI_Comm_rank(MPI_COMM_WORLD, &my_id) ;     // Ottiene l'identificativo del processo
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs) ;  // Ottiene quanti processi sono attivi
	MPI_Get_processor_name(name, &length);      // Il nome del nodo dove il processo è in esecuzione
if(my_id==0)
	cin >> MAXEVENTS;
MPI_Bcast(&MAXEVENTS,1,MPI_INT,0,MPI_COMM_WORLD);
if (my_id==0)
{ float ran[2];
srand(time(NULL));
for (int i=1;i<MAXEVENTS;i++) {
	int req;
	MPI_Status status;
ran[1]=(float)rand()/(float)RAND_MAX;
ran[0]=(float)rand()/(float)RAND_MAX;
MPI_Recv(&req,1,MPI_INT,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&status);
//cout<<req<<endl;
MPI_Send(&ran[0],2,MPI_FLOAT,status.MPI_SOURCE,0,MPI_COMM_WORLD);
}
ran[1]=99;
ran[0]=99;
for (int i=1;i<numprocs;i++) {
	int req;
	MPI_Status status;
	MPI_Recv(&req,1,MPI_INT,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&status);
MPI_Send(&ran[0],2,MPI_FLOAT,status.MPI_SOURCE,0,MPI_COMM_WORLD);
}
} else {
	float ran[2];
	
	MPI_Status status;
	do{
		MPI_Send(&my_id,1,MPI_INT,0,0,MPI_COMM_WORLD);
	MPI_Recv(&ran[0],2,MPI_FLOAT,0,0,MPI_COMM_WORLD,&status);
	if((ran[0]*ran[0]+ran[1]*ran[1])<1) in++;
	out++;
	}while(ran[0]<10&&ran[1]<10);
	
}// if my_id==0
int pi;
MPI_Reduce(&in,&pi,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
if (my_id==0)
cout << (float)pi*4/(float)MAXEVENTS << "  " << my_id ;
	MPI_Finalize();                             // Chiusura di MPI.
/*
Esercizio:
Modificate il programma in modo da farlo eseguire da un numero PARI di processi. 
I processi pari comunicano con quelli dispari e viceversa (0 <--> 1; 2 <--> 3.... ecc.)

*/	

	return 0;
}

