Group 42's final project.
###A Boardgame Over view In this project, you are asked to program a game that is played on a game board (a grid of squares). The players take turns. At each turn, the players will have the opportunity to move their player on the board from the current square to adjacent squares. A square has a maximum of four neighbours (up, down, left, right). When a player arrives on a square, the player has the ability to perform an action. Different squares allow different actions involving trading goods. The goal of the game is to acquire rubies.
###GameBoard
Create a parameterized class (template) for the game board having a grid builder giving the number of
rows and columns required. The squares of the grid are of type T. In addition, each square can hold one or
more players of type J; there are N players. The squares are identified by row and column number (just as
in chess). Players are identified by name. In the following we will refer to the squares on the gameboard
as tiles. The GameBoard class requires the following functions:
void add(const T& tile, int row, int col);const T& getTile(int row, int col) const;void getCoordinate(const T &tile, int *row, int *col) const;- public
void setPlayer(J player); - public
J getPlayer(const std::string& playerName); const T& getTile(const std::string& playerName) const;- public
std::vector<J> getPlayers(const T& tile) const; - public
const T& move(Enum Move move, const std::string& playerName );
If applicable, these methods should return an exception of type std::out_of_range.
####setPLayer
###Tile
Create a base class Tile which will let players execute actions. The function of action should only
permit players to execute an action if this action is possible.
bool operator==(const Tile &t);virtual bool action( Player& player );virtual Tile* clone();ostream& operator<<
####action Performs the action of this tile on the player. It is contained within a loop that verifies the player. Double check that the player has the right amount of stuff to do the action. Send exception if it doesn't work.
###Player
Create a Player class that will hold all the items a player has in his/her possession. The player
is carrying these items in a cart with limited capacity. You will need the class variables:
-
gold: Holds the number of pieces of gold. -
ruby: The number of ruby gemstones. -
Spice: The number of sacks of spices. -
fabric: The number of rolls of fabric. -
jewel: The number of pieces of jewellry. -
cart: The capacity of the cart. -
food: The number of food items` -
bool canAct() const; // returns true if food > 0 -
bool pay( Player& player, unsigned int amount ); -
void eat(); // reduces food count by 1 if food > 0
###The Game Rules
Each player starts with 5 pieces of gold, no ruby, 1 sack of spices, 1 roll of fabric, 1 jewel, and 10 food
items. The cart has an initial capacity of 9, which is the maximum number of goods (spice's, fabric's,
jewelry(jewels) and ruby(rubies) ) that a player can have at one time. When a player moves to a tile, the player can choose to perform an action corresponding to the type of the tile. Each action costs a player a food item.
Without food items the player can still move but the player cannot perform actions. When other players
are on the tile that the player lands on, the player must pay a piece of gold to all these other players but
only when performing an action.
###Tile derivatives
Besides the base class Tile, different derived classes are to be implemented to define possible actions. The
Tile base class itself implements the functionality of desert.
-
Desert:No action is possible on this tile. This is the base class behaviour. -
Restaurant: The number offooditems of aplayeris replenished and will be set to 10. This is the initial position of allplayers. -
Spice merchant:For 2 pieces ofgold, aplayercan purchase 3 sacks ofspices (less if theplayerdoes not have a capacity in his/her cart). -
Fabric Manufactures: For 2 pieces ofgold, theplayergets three rolls offabrics tissues (less if theplayerdoes not have a capacity in his/her cart) -
Jeweler:For 2 pieces ofgold, theplayergets 3 pieces of jewelry(jewels) (less if theplayerdoes not have a capacity in his cart). -
Cart Manufacturer:For 7 pieces ofgold, the capacity of thecartis increased by 3. -
Small market:Aplayercan sell 1 roll offabric, 1jeweland 1 sack ofspicesfor 8 pieces ofgold. -
Spice market:Aplayercan sell 3 sacks ofspices for 6 pieces ofgold. -
Jewelry market:Aplayercan sell 3 pieces of jewelry (jewels) for 6 pieces ofgold. -
Fabric market:Aplayercan sell 3 rolls offabrics for 6 pieces ofgold. -
Black market:For 1 piece ofgold, aplayercan get between 0 and 5 goods at random (less if theplayerdoes not have a capacity in his/her cart). -
Casino:For 1 piece ofgold, theplayerhas 2 in 5 chance to loose, i.e., win 0 pieces ofgold, a 3 out of 10 chance to get 2 pieces ofgold, a 2 out of 10 chance to get 3 pieces ofgoldand a 1 in 10 chance to win 10 pieces ofgold. -
Gem Merchant:A player can buy a ruby. The first ruby costs 12 gold coins, the second ruby to be purchased costs 13, the third 14, etc. -
Palace:A player can get a ruby in exchange for 5 rolls of fabrics, 5 pieces of jewelry and 5 sacks of spices. The first player to acquire 5 rubies wins.
To build the game board, create a class TileFactory that creates all the above types of tiles in random
order. The board is to be filled with these tiles. The total number of tiles for a game is input to the get
function as _nTiles. TileFactory will generate �1/14� of _nTiles of each type of tile and the rest are
desert tiles. There can only be one instance of a factory class in your program. You must ensure that no
copies of the TileFactory can be made.
The class needs at least the following functions:
static TileFactory *get(int _nTiles) {
static TileFactory tf(_nTiles);
return &tf;
}Tile* next(); // return new tileIn addition to the actual game play, your implementation must also support pausing the game by saving it to file and reloading it. This is to be accomplished with insertion operators for saving and extraction operator for loading. This is to say that
ostream& operator<<(ostream&, constBoardGame&)will save the current game status to file (or show it on the console) by calling the corresponding operators
for Players and Tiles. And reading it back in must work
istream& operator>>(istream&, BoardGame&)The simplified pseudo-code of the main loop follows.
if game is paused
resume
else
Setup: Input the names of all players and the size of the board. Initialize a board game for N players
While no Player has won
Check for Pause
For each Player
Display Player status
while move is not valid
Input move (up/down/right or left)
Move Player to Tile
if Player has food items
Display Tile Action
if Player chooses Action and Action is valid
if Tile occupied
Player pays other Player
Perform Action
Display Player status
if Player has 5 Rubies player has won
The turn routine in approximate and incomplete C++ code follows next. The code does not show the logic for pause and resume or displaying the game status.
template <cons int N>
bool takeTurn( BoardGame<Tile,Player,N,N>&bg,conststd::string&pName )
{
try
{
Move m;
cin.exceptions(std::istream::failbit);
cin>> m;
const Tile t = bg.move( m, pName );
Player p = bg.getPlayer( pName );
if (p.canAct())
{
bool makeAction;
cin>>makeAction;
if ( makeAction ) std::vector<Player> opL = bg.getPlayers( t );
if (p.getGold()>= opL.size())
{
p.eat();
for ( auto op : opL )
{
p.pay( op, 1 );
bg.setPlayer( op );
}
t.action( p );
bg.setPlayer( p );
}
}
retrun true;
}
catch ( std::istream::failure e )
{
cout<< “Incorrect key pressed”; cin.clear(); }
}
catch ( std::out_of_range e )
{
cout<< e.what();
}
return false;
}The initialization with the tile works as follows.
BoardGame<Tile,Player,6,6> bg( noPlayers );
TileFactory *tf= TileFactory.get(6*6);
for (int i=0;i<6; i++)
for (int j=0; j<6; j++)
bg.add(tf->next(),i,j);The main loop in approximate and incomplete C++ code follows next. The code does not show the logic for pause and resume or displaying the game status.
for ( auto pName : playerNames ) {
do {
cout<<getPlayer(pName);
} while (!takeTurn(bg,pName));
if ( bg.win(pName) ) break;
}The game is inspired by Oliver Dorn’s Istanbul.