Question

2 A Game of UNO You are to develop an interactive game of UNO between a...

2 A Game of UNO

You are to develop an interactive game of UNO between a number of players. The gameplay for UNO is described

at https://www.unorules.com/. Your program should operate as follows.

2.1 Setup

1. UNO cards are represented as variables of the following type:

typedef struct card_s {

char suit[7];

int value;

char action[15];

struct card_s *pt;

} card;

You are allowed to add attributes to this definition, but not to remove any. You can represent colors

by using card suits. Red: hearts; Yellow: diamonds; Green: clubs; Blue: spades. The action field is

used to denote the function of action cards.

2. The game is played using the following deck of cards1.

Figure 1: The deck of UNO cards.

The following action cards are included:

_ Reverse { If going clockwise, switch to counterclockwise or vice versa.

_ Skip { When a player places this card, the next player has to skip their turn. If turned up at the

beginning, the _rst player loses his/her turn.

_ Draw Two { When a person places this card, the next player will have to pick up two cards and

forfeit his/her turn.

1by Dmitry Fomin https://commons.wikimedia.org/w/index.php?curid=29517498.

2

_ Wild { This card represents all four colors, and can be placed on any card. The player has to

state which color it will represent for the next player. It can be played regardless of whether

another card is available.

_ Wild Draw Four { This acts just like the wild card except that the next player also has to draw

four cards as well as forfeit his/her turn. With this card, you must have no other alternative cards

to play that matches the color of the card previously played. If you play this card illegally, you

may be challenged by the other player to show your hand to him/her. If guilty, you need to draw

4 cards. If not, the challenger needs to draw 6 cards instead.

3. At the beginning, the user can choose to shu_e the deck or load a prede_ned sequence of cards from

a _le (for testing).

4. The deck is implemented by a dynamic list of cards. The cards drawn from the deck are deleted from

the list.

5. Each player's hand is implemented by a dynamic list of cards. The list is initially populated with the

cards dealt to each player. The card drawn (played) by each player is added to (deleted from) the

respective list.

6. The discard pile is implemented by a dynamic list. The discard pile is shu_ed if the draw pile is

exhausted and the game has not ended. Only the top _ve cards of the discard pile are shown on screen.

2.2 GamePlay

The gameplay and scoring process are described at https://www.unorules.com/

1. Automate one of the players. Modify your code to implement one of the players automatically.

2. Players 2{10. Allow the game to be played by any number of players from 2{10.

3. Game Variations. Implement the following game variations.

(a) Progressive Uno. If a draw card is played, and the following player has the same card, they

can play that card and \stack" the penalty, which adds to the current penalty and passes it to

the following player.

(b) Seven-O.: When a certain card is played, the player is able to trade hands with another player

or with all players. For example, the person who played the 7 card is able to switch all of their

cards with another player; the player who played the 0 card is able to make every player exchange

all their cards to the next player.

4. Graphics. Add graphics to your game. You can print cards using ascii art.

2.4 Sample Execution

Let's Play a Game of UNO

Press 1 to shuffle the UNO deck or 2 to load a deck from a file: 1

The deck is shuffled. Press any key to deal cards

Discard pile: 5|

Player's one hand: 6|, 3|, wild, draw two, 9V, 2; 7

3

Press 1-7 to play any card from your hand, or press zero to draw a card from the deck:5

The 9V cannot be placed on top of 5|

Press 1-7 to play any card from your hand, or press zero to draw a card from the deck:1

Discard pile: 6|, 5|

Player's two hand: 3|, 5V, 2W, reverse, 6V, 2|; 7

...

Player's one hand: 9V

Player one has UNO

Press 1 to play the card from your hand, or press zero to draw a card from the deck:1

Discard pile: 9V, 4V, 6V, wild, 2W.

Player 1 wins

Would you like to play again (y/n)? n

Bye bye

-------------------------------------------------------------------------------------------------------------------------

Use Stdio.h

Make sure the game cab be played between 2-10 players

Also, create an automatic player and ask the user if he want to play with him or not

Please Add comments explaining your code

0 0
Add a comment Improve this question Transcribed image text
Answer #1

#ifndef Card_h
#define Card_h
#include <string>
#include <ctime>
#include <sstream>
#include <vector>
using namespace std;
class Card {
private:
string m_value;
string m_type;
int m_score;
int m_dealerScore;
bool m_inHand;
public:
Card(string value, string type, int score, int dealerScore);
~Card();
string getValue();
string getType();
int getScore();
int getDealerScore();
void setValue(string username);
void setType(string password);
void setScore(int score);
void setDealerScore(int dealerScore);
void setInHand(bool isInHand);
bool getInHand();
};
#endif Card_h

#include "Card.h"
#include <iostream> // using IO functions
#include <string> // using string
using namespace std;
Card::Card(string value, string type, int score, int dealerScore) {
m_value = value;
m_type = type;
m_score = score;
m_dealerScore = dealerScore;
m_inHand = false;
}
string Card::getValue() { // Member function (Getter)
return m_value;
}
string Card::getType() { // Member function (Getter)
return m_type;
}
int Card::getScore(){
return m_score;
}
int Card::getDealerScore(){
return m_dealerScore;
}
void Card::setValue(string value){
m_value = value;
}
void Card::setType(string type){
m_type = type;
}
void Card::setScore(int score){
m_score = score;
}
void Card::setDealerScore(int dealerScore){
m_dealerScore = dealerScore;
};
void Card::setInHand(bool isInHand){
m_inHand = isInHand;
}
bool Card::getInHand(){
return m_inHand;
}
// need to end the class declaration with a semi-colon


#ifndef Game_h
#define Game_h
#include "Player.h"
#include "Card.h"
#include <iostream>
using namespace std;
class Game{
private:
vector<Player*> m_gamePlayers;
vector<Card*> m_discardPile;
vector<Card*> m_drawPile;
public:
Game();
~Game();
void addCardFromDrawPile(Card* card);
void discardCardToDiscardPile(Card* card);
void shuffleCards();
Player* getPlayer(int playerIndex);
void displayPlayerHand();
void displayTopCardInDiscardPile();
void displayTopCardInDrawPile();
void processLoadCards();
void setupPlayers();
void processMenu();
void processGamePlay();
};
#endif Game_h
Game.cpp

#include "Game.h"
#include "Player.h"
#include "Card.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>  
#include <vector>
using namespace std;
void processLoadCards();
void processGamePlay();
void setupPlayers();
void processMenu();
string displayPlayerHand();
vector<Card*> cards;
vector<Card*> drawPile;
string value;
string type;
int score;
int dealerScore;
vector<Player*> players;
Game::Game(){
}
Game::~Game(){
}
void Game::shuffleCards(){
}
void Game::addCardFromDrawPile(Card* card){
m_discardPile.push_back(card);
}
void Game::discardCardToDiscardPile(Card* card){
m_drawPile.push_back(card);
}
Player* Game::getPlayer(int playerIndex){
if (playerIndex >= 0 && playerIndex < m_gamePlayers.size()){
return m_gamePlayers[playerIndex];
}
else{
return nullptr;
}
}
void Game::displayPlayerHand(){
for (auto it = m_gamePlayers.begin(); it != m_gamePlayers.end(); ++it){
Player* player = *it;
//cout << player->displayPlayerHand() << endl; //deference the pointer address to grab the function
}
}
void Game::displayTopCardInDiscardPile(){
while (m_discardPile.back() != 0)
{
m_discardPile.push_back(m_discardPile.back() - 1);
}
cout << "Top Card in Discard Pile:";
for (unsigned i = 0; i < m_discardPile.size(); i++){
cout << ' ' << m_discardPile[0];
}
}
void Game::displayTopCardInDrawPile(){
while (m_drawPile.back() != 0)
{
m_drawPile.push_back(m_drawPile.back() - 1);
}
cout << "Top Card in Draw Pile:";
for (unsigned i = 0; i < m_drawPile.size(); i++){
cout << ' ' << m_drawPile[0];
}
}
void Game::processLoadCards(){
ifstream file("UnoDeck.txt");
cout << "\n-- LET'S PLAY UNO --" << endl << "\n";
if (file.is_open()){
string line;
while (getline(file, line)){
file >> ws;
stringstream ss;
ss << line;
Card* card = nullptr;
ss >> value;
ss >> type;
ss >> score;
ss >> dealerScore;
srand(time(NULL));
// Make the new card and put it in the cards vector
card = new Card(value, type, score, dealerScore);
cards.push_back(card);
}
// Scramble the vector
random_shuffle(cards.begin(), cards.end());
}
setupPlayers();
}
void Game::setupPlayers() {
int numPlayers = 4;
Player* player1 = new Player("Mary", "password", 0);
Player* player2 = new Player("John", "passwordForJohn", 0);
Player* player3 = new Player("Ben", "ben", 0);
Player* player4 = new Player("Junior", "junior", 0);
players.push_back(player1);
players.push_back(player2);
players.push_back(player3);
players.push_back(player4);
int playerIndex = 0;
for (int i = 1; i <= 7 * numPlayers; ++i){
// If the number we look at is divisible by 7, then it means we just hit the first 7 items
if (i < cards.size()) {
// Put first element into the cards pile
players[playerIndex]->addCardFromDrawPile(cards[i - 1]);
/* Say that the card is in a hand (so when you go to draw a new card from the pile, you'll interate through till you find a card
that has getInHand() == false and then you set it to true because it gets put in the user's hand. When you want to put a card back
in the pile, you would search for the card in the cards vector and then when you find that card go cards[i]->setInHand(false)
because it is no longer in someone's hand */
cards[i]->setInHand(true);
}
if (i % 7 == 0){
// Move to putting cards in the hand of the next player
playerIndex++;
}
Card* remainingCards = cards[cards.size() - (player1->m_playerHand.size() * 4)];
drawPile.push_back(remainingCards);
}
string displayPlayer1Cards = player1->displayPlayerHand();
string displayPlayer2Cards = player2->displayPlayerHand();
string displayPlayer3Cards = player3->displayPlayerHand();
string displayPlayer4Cards = player4->displayPlayerHand();
for (int i = 0; i < 2; --i){
cout << displayPlayer4Cards << endl;
player4->playGame();
cout << displayPlayer1Cards << endl;
player1->computerPlayerGame();
cout << displayPlayer2Cards << endl;
player2->computerPlayerGame();
cout << displayPlayer3Cards << endl;
player3->computerPlayerGame();
}
}
void Game::processMenu(){
// Declare other variables
int nMenuChoice = 0;
cout << "--- Welcome to the UNO Game! ---\n\n";
// Keep the program running until they choose to exit
while (nMenuChoice != 4) {
cout << "---Main Menu---\n";
cout << "1. Start Game\n";
cout << "2. Tutorial\n";
cout << "3. View Leadership Board\n";
cout << "4. Quit\n";
cout << "\nPick a choice: ";
cin >> nMenuChoice;
// Switch based on user input
switch (nMenuChoice) {
// Case of starting the game play
case 1:
processLoadCards();
break;
// Case of UNO Tutorial
case 2:
cout << "--- HOW TO PLAY UNO ---" << endl;
cout << "Rules:" << endl
<< "1. Play a card by entering the number on the left of the card." << endl
<< "2. A card can only be played if the colour or the title of the card is same " << endl
<< " as the card on the pile." << endl
<< "3. Draw a card if you cannot play any card, or you want to have more cards just" << endl
<< " for fun." << endl
<< "4. The last card in your hand can be a power card." << endl
<< "5. Draw Two and Draw Four will cause the next user to be skipped." << endl
<< "6. Wild card can be played at any time without restriction, but for Draw Four," << endl
<< " the computer players might challenge you. Draw Four can only be played when" << endl
<< " you have no same colour/ title card in your hand. If you are found guilty," << endl
<< " you will draw 4 cards as punishment, but you still can choose your colour." << endl
<< " If challenge failed, the challenger will draw 6 cards instead of 4." << endl
<< "7. A game will end, when one of the player had finished all the cards in his " << endl
<< " hand, or when the cards had ran out of stock." << endl << endl;
break;
// Case of Displaying Leadership Board  
case 3:
//processLeadershipBoard();
break;
// Quit condition
case 4:
break;
// Invalid selection   
default:
cout << "Invalid Menu Choice!\n";
break;
}
}
};


#ifndef Player_h
#define Player_h
#include "Card.h"
#include <string>
#include <ctime>
#include <sstream>
#include <vector>
using namespace std;
class Player{
private:
string m_username;
string m_password;
int m_score;
vector<Card*> m_drawPile;
void discardCardToDiscardPile(Card* playerCard);
public:
Player(string username, string password, int score);
~Player();
string getUsername();
string getPassword();
int getScore();
void setUsername(string username);
void setPassword(string password);
void setScore(int score);
string displayPlayerHand();
void addCardFromDrawPile(Card* playerCard);
void retrieveCardsFromDrawPile(Card* playerCard);
void playGame();
void computerPlayerGame();
vector<Card*> m_playerHand;
};
#endif Player_h
Player.cpp

#include "Player.h"
#include "Card.h"
#include "Game.h"
#include <iostream> // using IO functions
#include <string> // using string
#include <algorithm>
using namespace std;
// Declare other variables
int nUserNum = 0;
int numToDelete = 0;
Player::Player(string username, string password, int score) {
m_username = username;
m_password = password;
m_score = score;
}
string Player::getUsername() { // Member function (Getter)
return m_username;
}
string Player::getPassword() { // Member function (Getter)
return m_password;
}
int Player::getScore(){
return m_score;
}
void Player::setUsername(string username){
m_username = username;
}
void Player::setPassword(string password){
m_password = password;
}
void Player::setScore(int score){
m_score = score;
}
void Player::addCardFromDrawPile(Card* card){
m_playerHand.push_back(card);
}
void Player::retrieveCardsFromDrawPile(Card* card){
m_drawPile.push_back(card);
}
void Player::discardCardToDiscardPile(Card* card){
vector<Card*>::iterator found = find(m_playerHand.begin(), m_playerHand.end(), card);
if (found != m_playerHand.end()){
m_playerHand.erase(found);
}
}
string Player::displayPlayerHand(){
stringstream sPlayerHand;
sPlayerHand << "Player's " << m_username << endl;
for (int i = 0; i < m_playerHand.size(); i++){
sPlayerHand << i + 1 << ". " << m_playerHand[i]->getValue() << " - " << m_playerHand[i]->getType() << endl;
m_playerHand[i]->setInHand(false);
}
return sPlayerHand.str();
}
void Player::playGame(){
stringstream sPlayerHand;
sPlayerHand << "Player's " << m_username << endl;
int option = 0;
for (int i = 0; i < m_playerHand.size(); i++){
m_playerHand[i]->setInHand(false);
sPlayerHand << option << ". " << m_playerHand[i]->getValue() << " - " << m_playerHand[i]->getType() << endl;
}
cout << "Enter a choice for " << m_username << ": " ;
cin >> option;
cout << "You have selected the card: (" << m_playerHand[option-1]->getValue() << " - " << m_playerHand[option-1]->getType() << ").\n\n";
//if value and type matches with top card, then remove, else, return error message
clock_t start;
int pause = 1000;
for (int i = 0; i < 1; i++){
cout << "Loading next player's hands..." << flush << "\n\n";
start = clock();
while (clock() < start + pause);
}
}
void Player::computerPlayerGame(){
Card* card = m_playerHand[rand() % m_playerHand.size()];
stringstream sPlayerHand;
sPlayerHand << "Player " << m_username << "\n\n";
int option = 0;
for (int i = 0; i < m_playerHand.size(); i++){
sPlayerHand << option << ". " << m_playerHand[i]->getValue() << " - " << m_playerHand[i]->getType() << endl;
}
cout << m_username << " have selected the card: (" << card->getValue() << " - " << card->getType() << ").\n\n";
clock_t start;
int pause = 2000;
for (int i = 0; i < 1; i++){
cout << "Loading next player's hands..." << flush << "\n\n";
start = clock();
while (clock() < start + pause);
}
//if only pick rand card with value and type matches with top card, then remove, else, return error message
};

#include "Game.h"
#include "Player.h"
#include "Card.h"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>  
#include <vector>
using namespace std;
int main(){
//create instances of files we've created
Game* unoGame = new Game;
unoGame->processMenu();
delete unoGame;
system("pause");
return 0;
}

Add a comment
Know the answer?
Add Answer to:
2 A Game of UNO You are to develop an interactive game of UNO between a...
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT