MFE C++ - Assignment 4 v2
Correction
A couple of corrections have been made in red below to B.a. When we describe left/right players and how to store them in an array, we expect players to the left to go in increasing order in the array. So, player[1] is to the left of player[0].
The Left-Center-Right Game
In this assignment, we are going to explore variants of the game Left-Center-Right (LCR). LCR is a dice game. Traditionally, players roll three dice and distribute chips based on the outcome of the roll. We will specify the chip distribution in the form of a table:
Die Roll |
Result |
1 |
Hold |
2 |
Hold |
3 |
Hold |
4 |
Pass 1 Chip to the Right |
5 |
Place 1 Chip in the Center |
6 |
Pass 1 Chip to the Left |
A sample chip distribution table
The game is played until only one player still holds chips (or, in our case, until a certain number of rounds has been played if more than one player holds chips). If there is a winner (only 1 player left with chips), that player collects all the chips in the center.
Each player starts with a certain number of chips. This is an input parameter. The starting player is chosen randomly and then play continues to the left as with many card games.
A player rolls a maximum of 3 dice. If the player has 3 or fewer chips, the player rolls that many dice. If the player has no chips, she sits out the round. In our simulation, the player is passed three dice values and must decide how many values to use.
Once the dice are rolled, the player follows the distribution table, which is also an input parameter.
For example, assume a player has 10 chips and is using the distribution table above. She rolls 3 dice with values of 2, 4, 5. She then passes one chip to the player to her right (because of the 4) and places on chip in the center (because of the 5). She does nothing for her 2 roll because that is a ‘hold’.
Part 1 – Creating Classes
Create a class called ‘Player’ which will handle the play of a single player. It is ok to make all the methods in Player
Create a constructor for Player which takes the following parameters:
Player(const int* chipDistribution)
Where chipDistribution is an array that represents the distribution rules. The 0th offset of the array represents a die roll of 1, 1st offset represents 2, etc.
The values in the chipDistribution have the following meaning: 0: hold
1: pass left
2: put in center 3: pass right
chipDistribution should be stored in a property.
Create a method called setLeftPlayer(Player* p) which will be used to set the player to the object’s left. You should store this value in a class property. You should also create a method Player* getLeftPlayer()which returns the value of this property.
Create a method called setRightPlayer(Player* p) which will be used to set
the player to the object’s right You should store this value in a class property. You should also create a method Player* getRightPlayer()which returns the value of this property.
Create a getter and a setter for the number of chips the player holds: int getNumChips(), void setNumChips(int nc) numChips should be stored in a
Create a method called int addChips(int nc)which adds nc chips to the player’s
stack. nc may be negative. Hint: you may want to do something like:
this->setNumChips(this->getNumChips() + nc);
addChips() should return the number of chips the player holds after the addition.
Create a method called: int play(int d1, int d2, int d3) which plays a round of the game for the player. d1, d2 and d3 represent dice rolls. It is up to the player to decide how many of the dice to use (based on the number of chips the player holds) and how to interpret the dice values (based on the player’s distribution table). It is also up to the player to remove chips from her own stack when distributing them to other players or to the To give chips to a player, the method should call the addChips() method of the left or right player, depending on which player the distribution is going to.
play() should return the number of chips placed in the center during the player’s
round
Note: you may find it useful to create a method that handles a single die roll and then call it up to 3 times from play()
Create a class called ‘Game’ which will manage game play. It is ok to make all the methods in Game
create a constructor for Game:
Game(int numPlayers, const int* chipDistribution, long seed)
The constructor should create a property which is a dynamically allocated array of
pointers to Player objects of size numPlayers.
The constructor should populate the array by creating new Player objects and use chipDistribution as the distribution table (each Player gets passed the same chipDistribution value).
Once the array is populated, the constructor should loop through the array of Players and call setLeftPlayer() and setRightPlayer() for each array entry. If off represents the index of the player in the array, then the left player will be the player at index off-1 off+1 and the right player will be the player at index off+1 off-1.
BE CAREFUL TO HANDLE off==0 and off==numPlayers-1 propertly. If off==0, then the left right player will be at index numPlayers-1. If off==numPlayers-1, then the right left player will be at index 0. The modulo operator (%) can help with this index arithmetic.
The seed parameter should be used to create a Mersenne Twister that is a property of the class and will be used to select the first player and to roll dice.
Create a destructor for Game that loops through and deletes each player and then
delete[]’s the player array.
Create a method int countPlayersWithChips() which returns the number of players that hold chips. The game is over when only one player holds
Create a method int playRound(int startingPlayer) that loops through the players, in order with the starting point defined defined by the startingPlayer parameter, and rolls dice and then calls the Player’s play() You will need to create 3 random rolls of a die (values in [1,6]) using the Mersenne Twister you created in the Game’s constructor.
playRound() should return the number of chips that were placed in the center during the round (that is, it should sum the values returned by Player’s play() method for the round).
example, if there are 10 players and startingPlayer is 4, then the round will start with the Player at index 4 in the Player array. Assume you’ve named your Player array
players, then you’ll call players[4]->play(d1, d2, d3) then play() of players[5], players[6], players[7], players[8], players[9], players[0], players[1], players[2], players[3].
Remember the modulo operator (%) can help you with this:
for (int i = 0; i < numPlayers; i++) {
int index = (i + startingPlayer) % numPlayers;
// do stuff with index…
}
Create a method const int* playGame(const int* startingChips, int maxRounds) that plays the game until it is completed or the maximum number of rounds has been
Before play begins, the starting player should be chosen randomly (using the object’s
Mersenne Twister). The same starting player should be used throughout the game.
Also before play begins, treat startingChips as an array and call each Player’s setNumChips() method to set the initial number of chips each player holds (these may not be the same).
For up to maxRounds iterations, call the playRound() method and keep track of the number of chips in the center. If there is only one player with chips after the round, the game is concluded.
When the game is concluded (only one player has chips or maxRounds has been reached), then populate and return an array with the number of chips each player holds.
If only one player holds chips, then give that player the chips in the
If the maximum number of rounds has been reached, then ignore the chips in the center.
Note: you should create the chip count array in the class constructor and delete[] it in the destructor. We are going to call playGame repeatedly and want to reuse the same chip count array.
DescriptionIn this final assignment, the students will demonstrate their ability to apply two ma
Path finding involves finding a path from A to B. Typically we want the path to have certain properties,such as being the shortest or to avoid going t
Develop a program to emulate a purchase transaction at a retail store. Thisprogram will have two classes, a LineItem class and a Transaction class. Th
1 Project 1 Introduction - the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of
1 Project 2 Introduction - the SeaPort Project series For this set of projects for the course, we wish to simulate some of the aspects of a number of