/*
   guess.c - Distributed number guessing game with MPI

   compile: mpicc -Wall -O -o guess guess.c
   run:     mpirun -np num_procs guess
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <mpi.h>


void thinker()
{
  int number, guess;
  char reply;
  MPI_Status status;

  srand((unsigned int)time(NULL));

  reply = 'x';
  number = rand() % 100 + 1;
  printf("0: (I'm thinking of %d)\n",number);
  while (reply != 'c') {
    MPI_Recv(&guess, 1, MPI_INT, 1, 0, MPI_COMM_WORLD, &status);
    if (guess == number)
      reply = 'c';
    else if (guess > number)
      reply = 'h';
    else
      reply = 'l';
    printf("0: 1 guessed %2d; I'm responding %c\n", guess, reply);
    MPI_Send(&reply, 1, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
  }
}


void guesser()
{
  int guess, high, low;
  char reply;
  MPI_Status status;

  sleep(1); srand((unsigned int)time(NULL));

  low = 1;
  high = 100;
  guess = rand() % 100 + 1;
  printf("1: I'm guessing %2d\n", guess);
  while (1) {
    MPI_Send(&guess, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
    MPI_Recv(&reply, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);
    switch (reply) {
      case 'c': printf("1: 0 replied %c\n", reply); return;
      case 'h': high = guess; break;
      case 'l': low = guess; break;
    }
    guess = (high + low) / 2;
    printf("1: 0 replied %c; I'm guessing %2d\n", reply, guess);
  }
}


int main(int argc, char ** argv)
{
  int p, id;

  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &p);
  MPI_Comm_rank(MPI_COMM_WORLD, &id);

  if (id == 0)
    thinker();
  else
    guesser();

  MPI_Finalize();
  return 0;
}
