#include "player.h" // Definition of player task. #include #include // Defines strlen(). using namespace std; const int DONEWHEN = 1 + NUMPLAYERS * TIMESAROUND; // Number of message passes after which the game ends. //-------------------------------------------------------------------------------------------------------------------- // Starup and shutdown. //-------------------------------------------------------------------------------------------------------------------- Player::Player( Status SI[], int &newgameOver, Player * next, int whoami ) : StateInformation(SI), gameOver(newgameOver), nextPlayer(next), id(whoami) { StateInformation[id] = Active; // Not blocked to start with. } // Player::Player Player::~Player() { osacquire( cout ) << "Player " << id << " terminating" << endl; } // Player::~Player //-------------------------------------------------------------------------------------------------------------------- // Passes the message to the next task in the chain of tasks. //-------------------------------------------------------------------------------------------------------------------- void Player::SendMessage( char *m ) { message = m; gameOver += 1; // Message has gone to another player, so note it. StateInformation[id] = Active; // Player is no longer blocked. } // Player::SendMessage //-------------------------------------------------------------------------------------------------------------------- // Blocks itself waiting for messages until the game is over. //-------------------------------------------------------------------------------------------------------------------- void Player::main() { if ( nextPlayer == NULL ) { // First one in chain, so wait until get id of last one. StateInformation[id] = Blocked; _Accept( SetPlayer ); StateInformation[id] = Active; } // if for ( ; gameOver <= DONEWHEN ; ) { // Is the game over yet? StateInformation[id] = Blocked; _Accept( SendMessage ); // Receive and perturb the message. Pass it along if not done. if ( message != NULL && gameOver <= DONEWHEN ) { printInfo(); perturbMessage(); nextPlayer->SendMessage( message ); } // if } // for if ( id < NUMPLAYERS - 1 ) { nextPlayer->SendMessage( NULL ); } // if } // Player::main //-------------------------------------------------------------------------------------------------------------------- // Randomly perturbs the message. //-------------------------------------------------------------------------------------------------------------------- void Player::perturbMessage() { const char lowEndRange = ' '; // Low end of valid character range for message (ASCII 32). const char highEndRange = '~'; // High end of valid character range for message (ASCII 126). const char amountPerturb = highEndRange-lowEndRange; const int indexRange = strlen(message); // Number of characters in the string. int index; // Index of character to change. if ( indexRange > 0 ) { index = random() % indexRange; message[index] = (char) (lowEndRange + (random() % amountPerturb) + 1); } // if } // Player::perturbMessage //-------------------------------------------------------------------------------------------------------------------- // Print status of game and message at this point. //-------------------------------------------------------------------------------------------------------------------- void Player::printInfo() { osacquire acq( cout ); // lock cout during printing cout << gameOver << " ["; for ( int i = 0; i < NUMPLAYERS; i += 1 ) { if ( StateInformation[i] == Active ) { cout << 'A'; } else { cout << 'B'; } // if if ( i < NUMPLAYERS-1 ) cout << ", "; } // for cout << "] '" << message << "'" << endl; } // Player::printInfo