예제 #1
0
파일: dealer.c 프로젝트: jmr/acpc_dealer
/* run a match of numHands hands of the supplied game

   cards are dealt using rng, error conditions like timeouts
   are controlled and stored in errorInfo

   actions are read/sent to seat p on seatFD[ p ]

   if quiet is not zero, only print out errors, warnings, and final value

   if logFile is not NULL, print out a single line for each completed
   match with the final state and all player values.  The values are
   printed in player, not seat order.

   if transactionFile is not NULL, a transaction log of actions made
   is written to the file, and if there is any input left to read on
   the stream when gameLoop is called, it will be processed to
   initialise the state

   returns >=0 if the match finished correctly, -1 on error */
static int gameLoop( const Game *game, char *seatName[ MAX_PLAYERS ],
		     const uint32_t numHands, const int quiet,
		     const int fixedSeats, rng_state_t *rng,
		     ErrorInfo *errorInfo, const int seatFD[ MAX_PLAYERS ],
		     ReadBuf *readBuf[ MAX_PLAYERS ],
		     FILE *logFile, FILE *transactionFile )
{
  uint32_t handId;
  uint8_t seat, p, player0Seat, currentP, currentSeat;
  struct timeval t, sendTime, recvTime;
  Action action;
  MatchState state;
  double value[ MAX_PLAYERS ], totalValue[ MAX_PLAYERS ];

  /* check version string for each player */
  for( seat = 0; seat < game->numPlayers; ++seat ) {

    if( checkVersion( seat, readBuf[ seat ] ) < 0 ) {
      /* error messages already handled in function */

      return -1;
    }
  }

  gettimeofday( &sendTime, NULL );
  if( !quiet ) {
    fprintf( stderr, "STARTED at %zu.%06zu\n",
	     sendTime.tv_sec, sendTime.tv_usec );
  }

  /* start at the first hand */
  handId = 0;
  if( checkErrorNewHand( game, errorInfo ) < 0 ) {

    fprintf( stderr, "ERROR: unexpected game\n" );
    return -1;
  }
  initState( game, handId, &state.state );
  dealCards( game, rng, &state.state );
  for( seat = 0; seat < game->numPlayers; ++seat ) {
    totalValue[ seat ] = 0.0;
  }

  /* seat 0 is player 0 in first game */
  player0Seat = 0;

  /* process the transaction file */
  if( transactionFile != NULL ) {

    if( processTransactionFile( game, fixedSeats, &handId, &player0Seat,
				rng, errorInfo, totalValue,
				&state, transactionFile ) < 0 ) {
      /* error messages already handled in function */

      return -1;
    }
  }

  if( handId >= numHands ) {
    goto finishedGameLoop;
  }

  /* play all the (remaining) hands */
  while( 1 ) {

    /* play the hand */
    while( !stateFinished( &state.state ) ) {

      /* find the current player */
      currentP = currentPlayer( game, &state.state );

      /* send state to each player */
      for( seat = 0; seat < game->numPlayers; ++seat ) {

	state.viewingPlayer = seatToPlayer( game, player0Seat, seat );
	if( sendPlayerMessage( game, &state, quiet, seat,
			       seatFD[ seat ], &t ) < 0 ) {
	  /* error messages already handled in function */

	  return -1;
	}

	/* remember the seat and send time if player is acting */
	if( state.viewingPlayer == currentP ) {

	  sendTime = t;
	}
      }

      /* get action from current player */
      state.viewingPlayer = currentP;
      currentSeat = playerToSeat( game, player0Seat, currentP );
      if( readPlayerResponse( game, &state, quiet, currentSeat, &sendTime,
			      errorInfo, readBuf[ currentSeat ],
			      &action, &recvTime ) < 0 ) {
	/* error messages already handled in function */

	return -1;
      }

      /* log the transaction */
      if( transactionFile != NULL ) {

	if( logTransaction( game, &state.state, &action,
			    &sendTime, &recvTime, transactionFile ) < 0 ) {
	  /* error messages already handled in function */

	  return -1;
	}
      }

      /* do the action */
      doAction( game, &action, &state.state );
    }

    /* get values */
    for( p = 0; p < game->numPlayers; ++p ) {

      value[ p ] = valueOfState( game, &state.state, p );
      totalValue[ playerToSeat( game, player0Seat, p ) ] += value[ p ];
    }

    /* add the game to the log */
    if( logFile != NULL ) {

      if( addToLogFile( game, &state.state, value, player0Seat,
			seatName, logFile ) < 0 ) {
	/* error messages already handled in function */

	return -1;
      }
    }

    /* send final state to each player */
    for( seat = 0; seat < game->numPlayers; ++seat ) {

      state.viewingPlayer = seatToPlayer( game, player0Seat, seat );
      if( sendPlayerMessage( game, &state, quiet, seat,
			     seatFD[ seat ], &t ) < 0 ) {
	/* error messages already handled in function */

	return -1;
      }
    }

    if ( !quiet ) {
      if ( handId % 100 == 0) {
	for( seat = 0; seat < game->numPlayers; ++seat ) {
	  fprintf(stderr, "Seconds cumulatively spent in match for seat %i: "
		  "%i\n", seat,
		  (int)(errorInfo->usedMatchMicros[ seat ] / 1000000));
	}
      }
    }

    /* start a new hand */
    if( setUpNewHand( game, fixedSeats, &handId, &player0Seat,
		      rng, errorInfo, &state.state ) < 0 ) {
      /* error messages already handled in function */

      return -1;
    }
    if( handId >= numHands ) {
      break;
    }
  }

 finishedGameLoop:
  /* print out the final values */
  if( !quiet ) {
    gettimeofday( &t, NULL );
    fprintf( stderr, "FINISHED at %zu.%06zu\n",
	     sendTime.tv_sec, sendTime.tv_usec );
  }
  if( printFinalMessage( game, seatName, totalValue, logFile ) < 0 ) {
    /* error messages already handled in function */

    return -1;
  }

  return 0;
}
예제 #2
0
int main(void)
{
	// variable declaration
	int fd;
	pid_t pidRED, pidGRN, pidBLU, pidRead;

	// Create the named pipe
	mknod(PIPE_NAME, S_IFIFO | 0666, 0);

	// Opens the named pipe for both reading and writing
	fd = open(PIPE_NAME, O_RDWR | O_NDELAY );

	// Child process that writes 'RED' to the pipe
	pidRED = fork();
	if (pidRED == 0)
	{
		printf("Pid %d (red) started\n", getpid());
		writeColours(fd, "RED"); // Write to the pipe
		exit(1); // ends the child process
	}

	// Child process that writes 'GRN' to the pipe
	pidGRN = fork();
	if (pidGRN == 0)
	{
		printf("Pid %d (green) started\n", getpid());
		writeColours(fd, "GRN"); // Writes to the pipe
		exit(1); // ends the child process
	}

	// Child process that writes 'BLU' to the pipe
	pidBLU = fork();	
	if (pidBLU == 0)
	{
		printf("Pid %d (blue) started\n", getpid());
		writeColours(fd, "BLU"); // Writes to the pipe
		exit(1); // ends the child process
	}

	// Child process that reads the data from the pipe
	// and tallies up the totals
	pidRead = fork();
	if (pidRead == 0)
	{
		// Variables to keep track of totals written by each process
		int nbrOfRed = 0, nbrOfGreen = 0, nbrOfBlue = 0;

		// Variable to hold the data read in from the pipe
		char data[4];

		// Calculate the system time 5 seconds from now
		time_t endTime = time(0) + 5;

		// Runs loop for 5 seconds
		while(time(0) < endTime)
		{
			// Reads in the data from the pipe
			read(fd, &data, 4);

			// Determines which process wrote to the pipe
			// Increments the variable that's tallying the total
			if (!strcmp(data, "RED"))
			{
				nbrOfRed++;
			}
			else if (!strcmp(data, "GRN"))
			{
				nbrOfGreen++;
			}
			else if (!strcmp(data, "BLU")) 
			{
				nbrOfBlue++;
			}

			// Determine how many seconds the process has left to run
			double oldDiff = difftime(endTime, time(0));
			double newDiff;

			// The difference in how many seconds the process has left
			// Will change every 1 second
			// This is used as a measure to know when to print
			// Out the progress of the race
			while( newDiff != oldDiff && oldDiff != 0)
			{				
				printProgress(nbrOfRed, nbrOfGreen, nbrOfBlue);
				newDiff = difftime(endTime, time(0));
				break;
			} 

		}

		// Close the pipe
		close(fd);

		// Print the final messages for each process
		printf("\n"); // line break
		printFinalMessage("red", nbrOfRed);
		printFinalMessage("green", nbrOfGreen);
		printFinalMessage("blue", nbrOfBlue);
	} 

	return 0;
}