#include "iostream"
#include <mpi.h>

//	process refereeRank is a referee
//	processes with odd ranks are starting runners in every team
//	processes with even ranks are last runners
//	every team has only 2 runners


int main(int argc, char ** argv)
{
	int myRank = 0, refereeRank = 0, size = 0, message = 0, startMessage = 0;
	double v = 0, S = 0, fullS = 1, dt = 0.1;
	int tag = 0;

	MPI_Init(&argc, &argv);

	MPI_Comm_size(MPI_COMM_WORLD, &size);
	MPI_Comm_rank(MPI_COMM_WORLD, &myRank);

	if (myRank == refereeRank) {
		MPI_Bcast(&startMessage, 1, MPI_INT, refereeRank, MPI_COMM_WORLD);	// referee sends starting message to all processes
	}
	else
	if  (myRank % 2 == 1)		//	first runners in every team (processes with odd ranks)
	{
		MPI_Bcast(&startMessage, 1, MPI_INT, refereeRank, MPI_COMM_WORLD);	// receives starting message
		while (S < fullS)
		{
			v = (double)(rand())/RAND_MAX;
			S = S + v * dt;
		} 
		MPI_Send(&message, 1, MPI_INT, myRank + 1, myRank, MPI_COMM_WORLD);	//	gives baton to next runner (to even process)
		std::cout << "Player" << myRank << " gave baton." << std::endl;
	}
	else
	if (myRank % 2 == 0)	//	second runners in every team (processes with even ranks)
	{
		MPI_Bcast(&startMessage, 1, MPI_INT, refereeRank, MPI_COMM_WORLD);	// ???																					cause Bcast must be called from ALL processes in communicator
		MPI_Recv(&message, 1, MPI_INT, myRank - 1, myRank - 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE);	//	receives baton from previous runner
		while (S < fullS)
		{
			v = (double)(rand())/RAND_MAX;
			S = S + v * dt;
		}
		std::cout << "Player" << myRank << " has finished!"<< std::endl;
	}

	MPI_Finalize();
	return 0;
}

