//-------------------------------------------------------------
// file: players.cc
// (part of NIM - an OMNeT++ demo simulation)
//-------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "omnetpp.h"
#include "players.h"
// register player module types with the Player interface
Define_Module_Like( SmartPlayer, Player )
Define_Module_Like( SimplePlayer, Player )
Define_Module_Like( InteractivePlayer, Player )
// Operation of Player:
// A Player first introduces himself by sendings its namestr to the Game
// module. Then it enters an infinite loop; with each iteration, it receives
// a message from Game with the number of sticks left, calculates its move
// and sends back a message containing the move.
void Player::activity ()
{
// initialisation phase: send module type to Game module
cMessage *msg = new cMessage( playerName() ); // create a message
send (msg, "out"); // send it to Game
// infinite loop to process moves; simulation will be terminated by Game
for (;;)
{
// messages have several fields; here, we'll use the message kind
// member to store the number of sticks
cMessage *msgin = receive(); // receive message from Game
int num_sticks = msgin->kind(); // extract message kind (an int)
// this hold the number of sticks
// still on the stack
delete msgin; // dispose of the message
// call virtual function (implemented in cSmartPlayer etc.)
// to calculate the number of sticks to take.
int move = calculateMove( num_sticks );
ev << playerName() << " is taking " << move <<
" out of " << num_sticks << " sticks.\n";
// send answer back to the Game module
char msgname[32];
sprintf(msgname,"Taking %d", move);
cMessage *msgout = new cMessage(msgname); // create message
msgout->setKind( move );
send( msgout, "out"); // send the message to Game
}
}
char *SimplePlayer::playerName()
{
return "SimplePlayer";
}
int SimplePlayer::calculateMove( int num_sticks )
{
// random choice, at least 1, at most 4
return 1 + intrand( num_sticks<4 ? num_sticks : 4 );
}
char *SmartPlayer::playerName()
{
return "SmartPlayer";
}
int SmartPlayer::calculateMove( int num_sticks )
{
// calculate move
int move = (num_sticks + 4) % 5;
// if it comes out to be zero, it needs to be adjusted to one;
// this means that the other player is in the winning position
if (move == 0) move = 1;
return move;
}
char *InteractivePlayer::playerName()
{
return "InteractivePlayer";
}
int InteractivePlayer::calculateMove( int num_sticks )
{
// ask the user interactively
int move;
int max_sticks = num_sticks<4 ? num_sticks : 4;
char prompt[64];
sprintf(prompt,"%d sticks left. How many do you take (1..%d)?", num_sticks,max_sticks);
ev.setPrompt(prompt);
ev >> move;
while (move<1 || move>max_sticks)
{
ev.printfmsg("Please enter a number in range 1..%d", max_sticks);
ev >> move;
}
return move;
}
syntax highlighted by Code2HTML, v. 0.9.1