BogoToBogo
  • Home
  • About
  • Big Data
  • Machine Learning
  • AngularJS
  • Python
  • C++
  • go
  • DevOps
  • Kubernetes
  • Algorithms
  • More...
    • Qt 5
    • Linux
    • FFmpeg
    • Matlab
    • Django 1.8
    • Ruby On Rails
    • HTML5 & CSS

QT 4.7 - Blackjack 2020

cplusplus_icon.png




Bookmark and Share





bogotobogo.com site search:




Blackjack QT



How it works

In this chapter, we have a very simple black jack game using Qt.


I made this version in Ubuntu and haven't ported to Windows yet. I should admit that the code design requires some more work and I haven't had time to refactor/review the code since I wrote it years ago. Sorry for the documentation, it's very poor. Well, however, it's kind of working. If I have a chance, I'll make it more elegant

Here is the file, Blackjack.zip. It includes the source files, resource, *.pro, Makefile, and image files for card deck.

Here is the snapshots of the game.

  1. When it is executed first time, it looks like this:

    Blackjack1

    We have three buttons, Start, Hit, and Stand. Only the start button enabled. In the list window, we have lables for the house and player. The bottom of the widnow will show the text for the hands and the result.

  2. Game starts at the click of Start button.

    Blackjack12

    It shows two cards while the first card of house is faced down. Bottom of the window also shows the text display of the cards with the sum of face values of the player's cards. Note that the other two buttons on the top window now enabled.

  3. Since the total is only 12, the player will click Hit button, and the house and the player will get addition card. But for the house, it would get additional card only when the total of the face value is less or equal to 16. Blackjack13

    After the additional card, the house busted and the player won. We have a message saying "You won!"

  4. At the click of OK button on the message window, we get the following: Blackjack14

    Note that the Hit and Stand buttons are again disabled, and we are ready to play another round.

  5. Of course, there are other cases such as player lost and draw (push).

    Blackjack _lost

    Blackjack _push


Sources

Here are sources, and I'll put more detail explanation soon.

b.h

#ifndef B_H
#define B_H 

#include <iostream>
#include <string>
#include <vector>


#include <QWidget>
#include <QListView>

const int MAXCARDS = 10;

class QLabel;
class QLineEdit;
class QTextEdit;
class QPushButton;
class QString;
class Player;
class Game;
class AbstractPlayer;

class Canvas : public QWidget
{
        Q_OBJECT

 public:

        Canvas(QWidget *parent = 0);
        void setHostStateLabel(QString &s;);
        void setPlayerStateLabel(QString &s;);
        void setResultLabel(QString &s;);
        void drawCards(AbstractPlayer&);
        void setupIcons();
        void clearIcons();
        void setEnableHitStandButtons(bool b);

 public slots:
        void startBtn();
        void hitBtn();
        void standBtn();

 private:
        QPushButton *startButton;
        QPushButton *hitButton;
        QPushButton *standButton;
        QLabel *hostState;
        QLabel *playerState;
        QLabel *result;
        Game *myGame;
	QListView *cardTable;
	QLabel *cardIconHouse[MAXCARDS];
	QLabel *cardIconPlayer[MAXCARDS];
};


using namespace std;


class Card
{
public:

	enum Rank {ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
               JACK, QUEEN, KING};           
        enum Suit {SPADES, HEARTS, DIAMONDS, CLUBS};

	//overloading << operator so can send Card object to standard output 
	friend ostream& operator<<(ostream& os, const Card& aCard);
    
	Card(Rank r = ACE, Suit s = CLUBS, bool ifu = true); 

	//returns the value of a card, 1 - 11
	int getValue() const;

	//flips a card; if face up, becomes face down and vice versa
	void flip();
 
   	string convert();
    
private:
	Rank rank;
	Suit suit;
	bool isFaceUp;
};

class Hand
{

public:
	Hand();
    
	virtual ~Hand();

	//adds a card to the hand
	void add(Card* pCard);
 
	//clears hand of all cards
	void clear();

	int getTotal() const;
protected:
	vector<Card*> cards;
};

class AbstractPlayer : public Hand 
{
	friend ostream& operator<<(ostream& os, const AbstractPlayer& aAbstractPlayer);

public:
	AbstractPlayer(const string& s = "");
	QString makeLabelString();
        virtual void makePixmaps(AbstractPlayer& ) ;
    
	virtual ~AbstractPlayer();

	//indicates whether or not generic player wants to keep hitting
	virtual bool isHitting() const = 0;

	//returns whether generic player has busted - has a total greater than 21
	bool isBusted() const;

	//announces that the generic player busts
	QString bust() const;

	QString& getLabelQStr() const;
	string getName() const;

protected:
	string name;
	Hand *hand;
	mutable QString labelQStr;
};

class Player : public AbstractPlayer
{
public:
	Player(const string& name = "");

	virtual ~Player();

        virtual void makePixmaps(AbstractPlayer& );

	//returns whether or not the player wants another hit       
	virtual bool isHitting() const;

	//announces that the player wins
	void win(Canvas &) const; 

	//announces that the player loses
	void lose(Canvas &) const;

	//announces that the player pushes
	void push(Canvas &) const;

	static void resetHitCount();
	static void setHitCount();
	static int getHitCount();

	void resultMessage(string& s) const;
	vector<QPixmap>& getPixmaps();

private:
	static int hitCount;
        vector<QPixmap> pixmaps;
};

class House : public AbstractPlayer
{
public:
	House(const string& name = "House");

	virtual ~House();

        virtual void makePixmaps(AbstractPlayer& ) ;

	//indicates whether house is hitting - will always hit on 16 or less
	virtual bool isHitting() const;
  
	//flips over first card
	void flipFirstCard(bool b);

	vector<QPixmap>& getPixmaps();
private:
        vector<QPixmap> pixmaps;
};

class Deck : public Hand
{
public:
	Deck();
    
	virtual ~Deck();

	//create a standard deck of 52 cards
	void populate();

	//shuffle cards
	void shuffle();

	//deal one card to a hand
	void deal(Hand& aHand);

	//give additional cards to an abstract player 
	QString additionalCards(AbstractPlayer& aAbstractPlayer);
};

class Game
{
public:
	Game(const vector<string>& names, Canvas *cnv);
    
	~Game();
    
	//plays the game of blackjack    
	void gameStarted();
	void hitSelected();
	void standSelected();
	bool getStand();
	void setStand(bool b);

private:
	Deck deck;
	House house;
	vector<Player> player;  
	Canvas *canvas;
	bool stand;
};
#endif


c.cpp

#include <QtGui>
#include <iostream>
#include <string>
#include <typeinfo>
#include "b.h"

class Game;

Canvas::Canvas(QWidget *parent) : QWidget(parent)
 {
	startButton = new QPushButton(tr("&Start;"));
	hitButton = new QPushButton(tr("&Hit;"));
	standButton = new QPushButton(tr("&Stand;"));

	connect(startButton, SIGNAL(clicked()), this, SLOT(startBtn()));
	connect(hitButton, SIGNAL(clicked()), this, SLOT(hitBtn()));
	connect(standButton, SIGNAL(clicked()), this, SLOT(standBtn()));

	QHBoxLayout *buttonLayout = new QHBoxLayout;
	buttonLayout->addWidget(startButton);
	buttonLayout->addWidget(hitButton);
	buttonLayout->addWidget(standButton);

	buttonLayout->addStretch();

	cardTable = new QListView;
	QLabel *houseLabel = new QLabel(cardTable);
	QLabel *playerLabel = new QLabel(cardTable);
   	houseLabel->setText("House");
   	playerLabel->setText("Player");
	houseLabel->move(10,20);
	playerLabel->move(10,150);

	QVBoxLayout *verticalLayout = new QVBoxLayout;
	verticalLayout->addLayout(buttonLayout);
	verticalLayout->addWidget(cardTable);
	hostState = new QLabel("host");
	playerState = new QLabel("player");
	result = new QLabel("result");
	verticalLayout->addWidget(hostState);
	verticalLayout->addWidget(playerState);
	verticalLayout->addWidget(result);

	QGridLayout *mainLayout = new QGridLayout;

	mainLayout->addLayout(verticalLayout, 0,0,1,1);

	setLayout(mainLayout);

	setWindowTitle(tr("Blackjack "));
	resize(500,400);

	// Disable Hit/Stand buttons initially
 	setEnableHitStandButtons(false);

	setupIcons();
}

void Canvas::setEnableHitStandButtons(bool b)
{
	hitButton->setEnabled(b);
	standButton->setEnabled(b);
}

void Canvas::setupIcons()
{
	QPixmap qpx ;
	string str;
	
       	for (int i = 0; i < MAXCARDS; i++) {
		cardIconHouse[i] = new QLabel(cardTable);
		str = ":/images/blank.png";
		qpx = QPixmap(str.c_str());
		cardIconHouse[i]->setPixmap(qpx);
		cardIconHouse[i]->move(80+60*i,20);
	} 

       	for (int i = 0; i < MAXCARDS; i++) {
		cardIconPlayer[i] = new QLabel(cardTable);
	 	qpx = QPixmap(":/images/blank.png");
		cardIconPlayer[i]->setPixmap(qpx);
		cardIconPlayer[i]->move(80+60*i,150);
	} 
}

void Canvas::clearIcons()
{
	QPixmap qpx = QPixmap(":/images/blank.png");
       	for (int i = 0; i < MAXCARDS; i++) {
		cardIconHouse[i]->setPixmap(qpx);
	} 

       	for (int i = 0; i < MAXCARDS; i++) {
		cardIconPlayer[i]->setPixmap(qpx);
	} 
}

void Canvas::startBtn()
{
    	vector<string> names;
    	string name = "You";
    	names.push_back(name);

    	//the game 
    	myGame = new Game(names,this);

    	// initial table setup
    	myGame->gameStarted();
	setEnableHitStandButtons(true);
}

void Canvas::hitBtn()
{
	myGame->hitSelected();
}

void Canvas::standBtn()
{
	myGame->standSelected();

}

void Canvas::setHostStateLabel(QString &s;)
{
	hostState->setText(s);
}

void Canvas::setPlayerStateLabel(QString &s;)
{
	playerState->setText(s);
}

void Canvas::setResultLabel(QString &s;)
{
	result->setText(s);
}

void Canvas::drawCards(AbstractPlayer &ap;)
{
	QPixmap qpx ;
	string str;

	if(typeid(ap) == typeid(Player)) {
        	Player *ptr = dynamic_cast<Player *> (&ap;);
 		int size = (ptr->getPixmaps()).size();
		for(int i = 0; i < size ; i++) {
        		qpx = (ptr->getPixmaps())[i];
			cardIconPlayer[i]->setPixmap(qpx);
		}
	}
	else if(typeid(ap) == typeid(House)) {
        	House *ptr = dynamic_cast<House *> (&ap;);
 		int size = (ptr->getPixmaps()).size();
		for(int i = 0; i < size ; i++) {
        		qpx = (ptr->getPixmaps())[i];
			cardIconHouse[i]->setPixmap(qpx);
		}
	}
}


b.cpp

//Blackjack 
//Plays a simple version of blackjack; for 1 player

#include <iostream>
#include <typeinfo>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
#include <sstream>
#include <QMessageBox>

#include "b.h"

class QLabel;
class QString;

using namespace std;

Card::Card(Rank r, Suit s, bool isFace):  rank(r), suit(s), isFaceUp(isFace)
{} 

int Card::getValue() const
{
	//if a cards is face down, its value is 0
	int value = 0;
	if (isFaceUp)
	{
		//value is number showing on card
		value = rank;
		// value is 10 for face cards
		if (value > 10)
            		value = 10;
    	}
    	return value;
}

void Card::flip()
{
    	isFaceUp = !isFaceUp;
}

string Card::convert()                               
{
	ostringstream oss;
 	string str;
    	const string RANKS[] = {"0", "14", "02", "03", "04", "05", "06", "07", 
			"08", "09","10", "11", "12", "13"};
    	const string SUITS[] = {"1", "2", "3", "4"};

    	if (isFaceUp)
        	oss << ":images/" << SUITS[suit] << RANKS[rank] << ".gif";
    	else
        	oss << ":images/" << "xx" << ".gif";

    	str = oss.str();
    	return str;
}

Hand::Hand()
{
	cards.reserve(5);
}

Hand::~Hand()  
{
	clear();
}

void Hand::add(Card* pCard) 
{
	cards.push_back(pCard);
}
 
void Hand::clear()
{
	//iterate through vector, freeing all memory on the heap
	vector<Card*>::iterator iter = cards.begin();
	for (iter = cards.begin(); iter != cards.end(); ++iter)
	{
		delete *iter;
        	*iter = 0;
    	}
    	//clear vector of pointers
    	cards.clear();
}

int Hand::getTotal() const
{
    	// if no cards in hand, return 0
    	if ( cards.empty())
        	return 0;
  
    	// if a first card has value of 0, then card is face down; return 0
    	if (cards[0]->getValue() == 0)
        	return 0;
    
    	//add up card values, treat each Ace as 1
    	int total = 0;
    	vector<Card*>::const_iterator iter;
    	for (iter = cards.begin(); iter != cards.end(); ++iter)
        	total += (*iter)->getValue();
                  
    	//determine if hand contains an Ace
    	bool containsAce = false;
    	for (iter = cards.begin(); iter != cards.end(); ++iter)
        	if ((*iter)->getValue() == Card::ACE)
	containsAce = true;
          
    	// if hand contains Ace and total is low enough, treat Ace as 11
    	if (containsAce && total <= 11)
        //add only 10 since we've already added 1 for the Ace
        	total += 10;   
            
    	return total;
}

AbstractPlayer::AbstractPlayer(const string& s): name(s)
{ }

AbstractPlayer::~AbstractPlayer()  
{ }

string AbstractPlayer::getName() const
{ 
    	return name;
}

QString& AbstractPlayer::getLabelQStr()  const
{ 
    	return labelQStr;
}

bool AbstractPlayer::isBusted() const
{ 
    	return (getTotal() > 21);
}

QString AbstractPlayer::bust() const
{
    	string str = "";
    	ostringstream oss ;
    	oss << "";
    	oss << name << " bust! ";
    	str = oss.str();
    	return str.c_str();
}

int Player::hitCount = 0;

Player::Player(const string& name):  AbstractPlayer(name)
{ } 

Player::~Player()
{ }
    
int Player::getHitCount() 
{
 	return hitCount;
}
   
void Player::resetHitCount() 
{
 	hitCount = 0;
}


void Player::setHitCount() 
{
 	hitCount++;
}

bool Player::isHitting() const
{
    	return getHitCount();
}

void Player::win(Canvas &cnvs;) const
{
    	string s = "";
    	s.append(name);
    	s.append(" won!");   
    	resultMessage(s);
	cnvs.setEnableHitStandButtons(false);
}

void Player::lose(Canvas &cnvs;) const
{
    	string s = "";
    	s.append(name);
    	s.append(" lost!");   
    	resultMessage(s);
	cnvs.setEnableHitStandButtons(false);
}

void Player::push(Canvas &cnvs;) const
{
    	string s = "";
    	s.append("Push!");   
    	resultMessage(s);
	cnvs.setEnableHitStandButtons(false);
}

void Player::resultMessage(string& s) const
{
    	QMessageBox msgBox;
	msgBox.setWindowTitle("Results ...");
    	msgBox.setText(s.c_str());
    	msgBox.exec();
}

House::House(const string& name) :  AbstractPlayer(name)
{ }

House::~House()
{ }

bool House::isHitting() const
{
	bool b = (getTotal() <= 16);
	return b;
}   

void House::flipFirstCard(bool b)
{
    	if (!(cards.empty()))  {
       		if(b) cards[0]->flip();
    	}
}

Deck::Deck()
{ 
    	cards.reserve(52);
    	populate();
}

Deck::~Deck()
{ }

void Deck::populate()
{
    	clear();
    	// create standard deck
    	for (int s = Card::SPADES; s <= Card::CLUBS; ++s)
        	for (int r = Card::ACE; r <= Card::KING; ++r)
                	add(new Card(static_cast<Card::Rank>(r), static_cast<Card::Suit>(s)));
}

void Deck::shuffle()
{
    	random_shuffle(cards.begin(), cards.end());
}

void Deck::deal(Hand& aHand)
{
	// cards : inherited from Hand class
    	if (!cards.empty()) {
        	aHand.add(cards.back());
        	cards.pop_back();
    	}
    	else {
        	cout << "Out of cards. Unable to deal.";
    	}
}

QString Deck::additionalCards(AbstractPlayer& aAbstractPlayer)
{
    	// continue to deal a card as long as generic player isn't busted and
    	// wants another hit
	if(aAbstractPlayer.isHitting() && !aAbstractPlayer.isBusted()) 
        	deal(aAbstractPlayer);
        return aAbstractPlayer.makeLabelString();
} 

Game::Game(const vector<string>& names, Canvas *cnv):canvas(cnv)
{
    	// create a vector of players from a vector of names       
    	vector<string>::const_iterator pName;
    	for (pName = names.begin(); pName != names.end(); ++pName)      
        	player.push_back(Player(*pName));

    	srand(time(0));    //seed the random number generator
    	deck.populate();
    	deck.shuffle();
}

Game::~Game()
{ }

void Game::gameStarted()
{          
        string pixStr = "";
    	QString qstr = " ";

    	//remove everyone's cards
	vector<Player>::iterator iterPlayer;
      	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) 
		iterPlayer->clear();
    	house.clear();

	Player::resetHitCount();

	canvas->clearIcons();
    	canvas->setResultLabel(qstr);
    	// by default, stand=false until user hit Stand button.
    	setStand(true);

    	// deal initial 2 cards to everyone
    	for (int i = 0; i < 2; ++i) {
        	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {     
        		deck.deal(*iterPlayer);
		}
        	deck.deal(house);

    	}
    
    	// hide house's first card
   	if(!Player::getHitCount())house.flipFirstCard(true);    
    
    	// display everyone's hand
    	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {      
        	qstr = iterPlayer->makeLabelString();
        	canvas->setPlayerStateLabel(qstr);
        	iterPlayer->makePixmaps(*iterPlayer);
		canvas->drawCards(*iterPlayer);
    	}
    	qstr = house.makeLabelString();
    	canvas->setHostStateLabel(qstr);
    	house.makePixmaps(house);
	canvas->drawCards(house);
}

void Game::hitSelected()
{         

	QString qstr;
	vector<Player>::iterator iterPlayer;
	// reveal house's first card which has been hidden
    	if(!Player::getHitCount()) house.flipFirstCard(true);    

        //deal additional cards to players
        for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {
      		iterPlayer->setHitCount();  
                qstr = deck.additionalCards(*iterPlayer);
                canvas->setPlayerStateLabel(qstr);
        	iterPlayer->makePixmaps(*iterPlayer);
		canvas->drawCards(*iterPlayer);
        }

	
    	//deal additional cards to house
    	qstr = deck.additionalCards(house);
        house.makeLabelString();
        canvas->setHostStateLabel(qstr);
    	house.makePixmaps(house);
	canvas->drawCards(house);

      	if(house.isBusted()) {
            	qstr =  house.bust();
            	canvas->setResultLabel(qstr);
        	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {
        		if (!iterPlayer->isBusted()) {
				iterPlayer-> win(*canvas);
			}
			// both busted
			else {
				iterPlayer->lose(*canvas);
			}
    		}
	}
	else {
        	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {
			// player is still in, not busted
        		if (!(iterPlayer->isBusted())) {
				// player still hitting
				if(iterPlayer->isHitting()) 
					break; 
				// player stand
				else {
					while(house.isHitting()) {
    					//deal additional cards to house
    						qstr = deck.additionalCards(house);
        					house.makeLabelString();
    						house.makePixmaps(house);
						canvas->drawCards(house);
					}
				}
				
				if(iterPlayer-> getTotal() > house.getTotal()) {
						iterPlayer->win(*canvas);
				}
				else if(iterPlayer->getTotal() < house.getTotal())
						iterPlayer->lose(*canvas);
				else
						iterPlayer->push(*canvas);
			}
			// player busted
              		else {
				iterPlayer->lose(*canvas);
            			qstr = iterPlayer->bust();
            			canvas->setResultLabel(qstr);
			}
    		}
	}
}

// Player opted to stand, House will hit if total <= 16 
void Game::standSelected()
{         
	vector<Player>::iterator iterPlayer;
        QString qstr;

	if(Player::getHitCount())  {
    	  	house.flipFirstCard(false);    
		Player::setHitCount();
	}
	else {
    	  	house.flipFirstCard(true);    
		Player::setHitCount();
	}

    	//deal additional cards to house
    	qstr = deck.additionalCards(house);
        house.makeLabelString();
        canvas->setHostStateLabel(qstr);
    	house.makePixmaps(house);
	canvas->drawCards(house);

      	if(house.isBusted()) {
            	qstr = house.bust();
            	canvas->setResultLabel(qstr);
        	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {
        		if (!iterPlayer->isBusted()) {
				iterPlayer-> win(*canvas);
			}
    		}
	}
	else {
        	for (iterPlayer = player.begin(); iterPlayer != player.end(); ++iterPlayer) {
			if(!house.isHitting()) {
				if(iterPlayer-> getTotal() > house.getTotal())
					iterPlayer->win(*canvas);
				else if(iterPlayer->getTotal() < house.getTotal())
					iterPlayer->lose(*canvas);
				else
					iterPlayer->push(*canvas);
			}
		}
	}
}

void Game::setStand(bool b)
{         
	stand = b;
}


bool Game::getStand()
{         
	return stand;
}

// overloads << operator so Card object can be sent to cout
ostream& operator<<(ostream& os, const Card& aCard)
{
    	const string RANKS[] = {"0", "A", "2", "3", "4", "5", "6", "7", "8", "9", 
                            "10", "J", "Q", "K"};
    	const string SUITS[] = {"s", "h", "d", "c"};

    	if (aCard.isFaceUp)
        	os << RANKS[aCard.rank] << SUITS[aCard.suit];
    	else
        	os << "XX";

    	return os;
}

//overloads << operator so a AbstractPlayer object can be sent to cout
ostream& operator<<(ostream& os, const AbstractPlayer& aAbstractPlayer)
{
    	string str = "";
    	ostringstream oss;
    	oss << "" ;
    	oss << aAbstractPlayer.name << ":   ";
    
    	vector<Card*>::const_iterator pCard;
    	if (!aAbstractPlayer.cards.empty()) {
        	for (pCard = aAbstractPlayer.cards.begin(); 
             		pCard != aAbstractPlayer.cards.end(); ++pCard) {
            	oss << *(*pCard) << "   ";
        	}
        	if (aAbstractPlayer.getTotal() != 0) {
            		oss << "(" << aAbstractPlayer.getTotal() << ")";
        	}
    	}
    	else {
        	oss << "<empty>";
    	}
        
    	str = oss.str();
    	aAbstractPlayer.labelQStr = str.c_str();
    	return os;
}

void AbstractPlayer::makePixmaps(AbstractPlayer &ap;) 
{ }

vector<QPixmap>& Player::getPixmaps() 
{
	return pixmaps;
}

vector<QPixmap>& House::getPixmaps() 
{
	return pixmaps;
}

void Player::makePixmaps(AbstractPlayer &ab;) 
{
       	string str;
    	vector<Card*>::const_iterator pCard;
    	if (!cards.empty()) {
		
                Player *ptr = dynamic_cast<Player *> (&ab;);

		ptr->pixmaps.clear();
        	for (pCard = cards.begin(); 
             		pCard != cards.end(); ++pCard) {
			str = (*pCard)->convert();
		  	pixmaps.push_back(QPixmap(str.c_str()));
			
        	}
        	if (getTotal() != 0) {
            	//	oss << "(" << getTotal() << ")";
        	}
    	}
}

void House::makePixmaps(AbstractPlayer &ab;) 
{
       	string str;
    	vector<Card*>::const_iterator pCard;
    	if (!cards.empty()) {
		
                House *ptr = dynamic_cast<House *> (&ab;);

		ptr->pixmaps.clear();
        	for (pCard = cards.begin(); 
             		pCard != cards.end(); ++pCard) {
			str = (*pCard)->convert();
		  	pixmaps.push_back(QPixmap(str.c_str()));
			
        	}
        	if (getTotal() != 0) {
            	//	oss << "(" << getTotal() << ")";
        	}
    	}
}

QString AbstractPlayer::makeLabelString()
{
    	string str = "";
    	ostringstream oss;
    	oss << "" ;
    	oss << name << ":   ";
    
    	vector<Card*>::const_iterator pCard;
    	if (!cards.empty()) {
        	for (pCard = cards.begin(); 
             		pCard != cards.end(); ++pCard) {
            		oss << *(*pCard) << "   ";
        	}
        	if (getTotal() != 0) {
            		oss << "(" << getTotal() << ")";
        	}
    	}
    	else {
        	oss << "<empty>";
    	}
        
    	str = oss.str();
    	return str.c_str();
}


main.cpp

#include <QtGui>
#include "b.h"

void startGame();

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);

	Canvas canvas;
	canvas.show();

	return app.exec();
}


c.pro

HEADERS = b.h
SOURCES = c.cpp \
	b.cpp \
	 main.cpp
RESOURCES = cards.qrc
TARGET = c
CONFIG += qt debug


cards.qrc

<!DOCTYPE RCC><RCC version="1.0">
 <qresource prefix="">
    <file>images/102.gif</file>
    <file>images/103.gif</file>
    <file>images/104.gif</file>
    <file>images/105.gif</file>
    <file>images/106.gif</file>
    <file>images/107.gif</file>
    <file>images/108.gif</file>
    <file>images/109.gif</file>
    <file>images/110.gif</file>
    <file>images/111.gif</file>
    <file>images/112.gif</file>
    <file>images/113.gif</file>
    <file>images/114.gif</file>
    <file>images/202.gif</file>
    <file>images/203.gif</file>
    <file>images/204.gif</file>
    <file>images/205.gif</file>
    <file>images/206.gif</file>
    <file>images/207.gif</file>
    <file>images/208.gif</file>
    <file>images/209.gif</file>
    <file>images/210.gif</file>
    <file>images/211.gif</file>
    <file>images/212.gif</file>
    <file>images/213.gif</file>
    <file>images/214.gif</file>
    <file>images/302.gif</file>
    <file>images/303.gif</file>
    <file>images/304.gif</file>
    <file>images/305.gif</file>
    <file>images/306.gif</file>
    <file>images/307.gif</file>
    <file>images/308.gif</file>
    <file>images/309.gif</file>
    <file>images/310.gif</file>
    <file>images/311.gif</file>
    <file>images/312.gif</file>
    <file>images/313.gif</file>
    <file>images/314.gif</file>
    <file>images/402.gif</file>
    <file>images/403.gif</file>
    <file>images/404.gif</file>
    <file>images/405.gif</file>
    <file>images/406.gif</file>
    <file>images/407.gif</file>
    <file>images/408.gif</file>
    <file>images/409.gif</file>
    <file>images/410.gif</file>
    <file>images/411.gif</file>
    <file>images/412.gif</file>
    <file>images/413.gif</file>
    <file>images/414.gif</file>
    <file>images/blank.gif</file>
    <file>images/blank.png</file>
    <file>images/xx.png</file>
    <file>images/xx.gif</file>
 </qresource>
 </RCC>


This make file is made by qmake

qmake -o Makefile c.pro

Makefile

#############################################################################
# Makefile for building: c
# Generated by qmake (2.01a) (Qt 4.7.0) on: Sat Mar 12 09:40:09 2011
# Project:  c.pro
# Template: app
# Command: /home/kihyuck/qtsdk-2010.05/qt/bin/qmake -o Makefile c.pro
#############################################################################

####### Compiler, tools and options

CC            = gcc
CXX           = g++
DEFINES       = -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS        = -pipe -g -D_REENTRANT -Wall -W $(DEFINES)
CXXFLAGS      = -pipe -g -D_REENTRANT -Wall -W $(DEFINES)
INCPATH       = -I../../qtsdk-2010.05/qt/mkspecs/linux-g++ -I. -I../../qtsdk-2010.05/qt/include/QtCore -I../../qtsdk-2010.05/qt/include/QtGui -I../../qtsdk-2010.05/qt/include -I.
LINK          = g++
LFLAGS        = -Wl,-rpath,/home/kihyuck/qtsdk-2010.05/qt/lib
LIBS          = $(SUBLIBS)  -L/home/kihyuck/qtsdk-2010.05/qt/lib -lQtGui -L/home/kihyuck/qtsdk-2010.05/qt/lib -L/usr/X11R6/lib -lQtCore -lpthread 
AR            = ar cqs
RANLIB        = 
QMAKE         = /home/kihyuck/qtsdk-2010.05/qt/bin/qmake
TAR           = tar -cf
COMPRESS      = gzip -9f
COPY          = cp -f
SED           = sed
COPY_FILE     = $(COPY)
COPY_DIR      = $(COPY) -r
STRIP         = strip
INSTALL_FILE  = install -m 644 -p
INSTALL_DIR   = $(COPY_DIR)
INSTALL_PROGRAM = install -m 755 -p
DEL_FILE      = rm -f
SYMLINK       = ln -f -s
DEL_DIR       = rmdir
MOVE          = mv -f
CHK_DIR_EXISTS= test -d
MKDIR         = mkdir -p

####### Output directory

OBJECTS_DIR   = ./

####### Files

SOURCES       = c.cpp \
		b.cpp \
		main.cpp moc_b.cpp \
		qrc_cards.cpp
OBJECTS       = c.o \
		b.o \
		main.o \
		moc_b.o \
		qrc_cards.o
DIST          = ../../qtsdk-2010.05/qt/mkspecs/common/g++.conf \
		../../qtsdk-2010.05/qt/mkspecs/common/unix.conf \
		../../qtsdk-2010.05/qt/mkspecs/common/linux.conf \
		../../qtsdk-2010.05/qt/mkspecs/qconfig.pri \
		../../qtsdk-2010.05/qt/mkspecs/modules/qt_webkit_version.pri \
		../../qtsdk-2010.05/qt/mkspecs/features/qt_functions.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/qt_config.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/exclusive_builds.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/default_pre.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/debug.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/default_post.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/qt.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/unix/thread.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/moc.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/warn_on.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/resources.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/uic.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/yacc.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/lex.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/include_source_dir.prf \
		c.pro
QMAKE_TARGET  = c
DESTDIR       = 
TARGET        = c

first: all
####### Implicit rules

.SUFFIXES: .o .c .cpp .cc .cxx .C

.cpp.o:
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.cc.o:
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.cxx.o:
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.C.o:
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o "$@" "$<"

.c.o:
	$(CC) -c $(CFLAGS) $(INCPATH) -o "$@" "$<"

####### Build rules

all: Makefile $(TARGET)

$(TARGET):  $(OBJECTS)  
	$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)

Makefile: c.pro  ../../qtsdk-2010.05/qt/mkspecs/linux-g++/qmake.conf ../../qtsdk-2010.05/qt/mkspecs/common/g++.conf \
		../../qtsdk-2010.05/qt/mkspecs/common/unix.conf \
		../../qtsdk-2010.05/qt/mkspecs/common/linux.conf \
		../../qtsdk-2010.05/qt/mkspecs/qconfig.pri \
		../../qtsdk-2010.05/qt/mkspecs/modules/qt_webkit_version.pri \
		../../qtsdk-2010.05/qt/mkspecs/features/qt_functions.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/qt_config.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/exclusive_builds.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/default_pre.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/debug.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/default_post.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/qt.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/unix/thread.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/moc.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/warn_on.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/resources.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/uic.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/yacc.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/lex.prf \
		../../qtsdk-2010.05/qt/mkspecs/features/include_source_dir.prf \
		/home/kihyuck/qtsdk-2010.05/qt/lib/libQtGui.prl \
		/home/kihyuck/qtsdk-2010.05/qt/lib/libQtCore.prl
	$(QMAKE) -o Makefile c.pro
../../qtsdk-2010.05/qt/mkspecs/common/g++.conf:
../../qtsdk-2010.05/qt/mkspecs/common/unix.conf:
../../qtsdk-2010.05/qt/mkspecs/common/linux.conf:
../../qtsdk-2010.05/qt/mkspecs/qconfig.pri:
../../qtsdk-2010.05/qt/mkspecs/modules/qt_webkit_version.pri:
../../qtsdk-2010.05/qt/mkspecs/features/qt_functions.prf:
../../qtsdk-2010.05/qt/mkspecs/features/qt_config.prf:
../../qtsdk-2010.05/qt/mkspecs/features/exclusive_builds.prf:
../../qtsdk-2010.05/qt/mkspecs/features/default_pre.prf:
../../qtsdk-2010.05/qt/mkspecs/features/debug.prf:
../../qtsdk-2010.05/qt/mkspecs/features/default_post.prf:
../../qtsdk-2010.05/qt/mkspecs/features/qt.prf:
../../qtsdk-2010.05/qt/mkspecs/features/unix/thread.prf:
../../qtsdk-2010.05/qt/mkspecs/features/moc.prf:
../../qtsdk-2010.05/qt/mkspecs/features/warn_on.prf:
../../qtsdk-2010.05/qt/mkspecs/features/resources.prf:
../../qtsdk-2010.05/qt/mkspecs/features/uic.prf:
../../qtsdk-2010.05/qt/mkspecs/features/yacc.prf:
../../qtsdk-2010.05/qt/mkspecs/features/lex.prf:
../../qtsdk-2010.05/qt/mkspecs/features/include_source_dir.prf:
/home/kihyuck/qtsdk-2010.05/qt/lib/libQtGui.prl:
/home/kihyuck/qtsdk-2010.05/qt/lib/libQtCore.prl:
qmake:  FORCE
	@$(QMAKE) -o Makefile c.pro

dist: 
	@$(CHK_DIR_EXISTS) .tmp/c1.0.0 || $(MKDIR) .tmp/c1.0.0 
	$(COPY_FILE) --parents $(SOURCES) $(DIST) .tmp/c1.0.0/ && $(COPY_FILE) --parents b.h .tmp/c1.0.0/ && $(COPY_FILE) --parents cards.qrc .tmp/c1.0.0/ && $(COPY_FILE) --parents c.cpp b.cpp main.cpp .tmp/c1.0.0/ && (cd `dirname .tmp/c1.0.0` && $(TAR) c1.0.0.tar c1.0.0 && $(COMPRESS) c1.0.0.tar) && $(MOVE) `dirname .tmp/c1.0.0`/c1.0.0.tar.gz . && $(DEL_FILE) -r .tmp/c1.0.0


clean:compiler_clean 
	-$(DEL_FILE) $(OBJECTS)
	-$(DEL_FILE) *~ core *.core


####### Sub-libraries

distclean: clean
	-$(DEL_FILE) $(TARGET) 
	-$(DEL_FILE) Makefile


check: first

mocclean: compiler_moc_header_clean compiler_moc_source_clean

mocables: compiler_moc_header_make_all compiler_moc_source_make_all

compiler_moc_header_make_all: moc_b.cpp
compiler_moc_header_clean:
	-$(DEL_FILE) moc_b.cpp
moc_b.cpp: b.h
	/home/kihyuck/qtsdk-2010.05/qt/bin/moc $(DEFINES) $(INCPATH) b.h -o moc_b.cpp

compiler_rcc_make_all: qrc_cards.cpp
compiler_rcc_clean:
	-$(DEL_FILE) qrc_cards.cpp
qrc_cards.cpp: cards.qrc \
		images/206.gif \
		images/312.gif \
		images/305.gif \
		images/411.gif \
		images/108.gif \
		images/214.gif \
		images/404.gif \
		images/207.gif \
		images/313.gif \
		images/102.gif \
		images/306.gif \
		images/412.gif \
		images/109.gif \
		images/405.gif \
		images/110.gif \
		images/208.gif \
		images/314.gif \
		images/103.gif \
		images/307.gif \
		images/413.gif \
		images/202.gif \
		images/xx.png \
		images/406.gif \
		images/111.gif \
		images/209.gif \
		images/104.gif \
		images/210.gif \
		images/308.gif \
		images/414.gif \
		images/203.gif \
		images/blank.gif \
		images/407.gif \
		images/112.gif \
		images/blank.png \
		images/302.gif \
		images/105.gif \
		images/211.gif \
		images/309.gif \
		images/204.gif \
		images/310.gif \
		images/408.gif \
		images/113.gif \
		images/303.gif \
		images/106.gif \
		images/212.gif \
		images/xx.gif \
		images/402.gif \
		images/205.gif \
		images/311.gif \
		images/409.gif \
		images/114.gif \
		images/304.gif \
		images/410.gif \
		images/107.gif \
		images/213.gif \
		images/403.gif
	/home/kihyuck/qtsdk-2010.05/qt/bin/rcc -name cards cards.qrc -o qrc_cards.cpp

compiler_image_collection_make_all: qmake_image_collection.cpp
compiler_image_collection_clean:
	-$(DEL_FILE) qmake_image_collection.cpp
compiler_moc_source_make_all:
compiler_moc_source_clean:
compiler_uic_make_all:
compiler_uic_clean:
compiler_yacc_decl_make_all:
compiler_yacc_decl_clean:
compiler_yacc_impl_make_all:
compiler_yacc_impl_clean:
compiler_lex_make_all:
compiler_lex_clean:
compiler_clean: compiler_moc_header_clean compiler_rcc_clean 

####### Compile

c.o: c.cpp b.h
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o c.o c.cpp

b.o: b.cpp b.h
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o b.o b.cpp

main.o: main.cpp b.h
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o main.o main.cpp

moc_b.o: moc_b.cpp 
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o moc_b.o moc_b.cpp

qrc_cards.o: qrc_cards.cpp 
	$(CXX) -c $(CXXFLAGS) $(INCPATH) -o qrc_cards.o qrc_cards.cpp

####### Install

install:   FORCE

uninstall:   FORCE

FORCE:





Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization

YouTubeMy YouTube channel

Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






Sponsor Open Source development activities and free contents for everyone.

Thank you.

- K Hong






C++ Tutorials

C++ Home

Algorithms & Data Structures in C++ ...

Application (UI) - using Windows Forms (Visual Studio 2013/2012)

auto_ptr

Binary Tree Example Code

Blackjack with Qt

Boost - shared_ptr, weak_ptr, mpl, lambda, etc.

Boost.Asio (Socket Programming - Asynchronous TCP/IP)...

Classes and Structs

Constructor

C++11(C++0x): rvalue references, move constructor, and lambda, etc.

C++ API Testing

C++ Keywords - const, volatile, etc.

Debugging Crash & Memory Leak

Design Patterns in C++ ...

Dynamic Cast Operator

Eclipse CDT / JNI (Java Native Interface) / MinGW

Embedded Systems Programming I - Introduction

Embedded Systems Programming II - gcc ARM Toolchain and Simple Code on Ubuntu and Fedora

Embedded Systems Programming III - Eclipse CDT Plugin for gcc ARM Toolchain

Exceptions

Friend Functions and Friend Classes

fstream: input & output

Function Overloading

Functors (Function Objects) I - Introduction

Functors (Function Objects) II - Converting function to functor

Functors (Function Objects) - General



Git and GitHub Express...

GTest (Google Unit Test) with Visual Studio 2012

Inheritance & Virtual Inheritance (multiple inheritance)

Libraries - Static, Shared (Dynamic)

Linked List Basics

Linked List Examples

make & CMake

make (gnu)

Memory Allocation

Multi-Threaded Programming - Terminology - Semaphore, Mutex, Priority Inversion etc.

Multi-Threaded Programming II - Native Thread for Win32 (A)

Multi-Threaded Programming II - Native Thread for Win32 (B)

Multi-Threaded Programming II - Native Thread for Win32 (C)

Multi-Threaded Programming II - C++ Thread for Win32

Multi-Threaded Programming III - C/C++ Class Thread for Pthreads

MultiThreading/Parallel Programming - IPC

Multi-Threaded Programming with C++11 Part A (start, join(), detach(), and ownership)

Multi-Threaded Programming with C++11 Part B (Sharing Data - mutex, and race conditions, and deadlock)

Multithread Debugging

Object Returning

Object Slicing and Virtual Table

OpenCV with C++

Operator Overloading I

Operator Overloading II - self assignment

Pass by Value vs. Pass by Reference

Pointers

Pointers II - void pointers & arrays

Pointers III - pointer to function & multi-dimensional arrays

Preprocessor - Macro

Private Inheritance

Python & C++ with SIP

(Pseudo)-random numbers in C++

References for Built-in Types

Socket - Server & Client

Socket - Server & Client 2

Socket - Server & Client 3

Socket - Server & Client with Qt (Asynchronous / Multithreading / ThreadPool etc.)

Stack Unwinding

Standard Template Library (STL) I - Vector & List

Standard Template Library (STL) II - Maps

Standard Template Library (STL) II - unordered_map

Standard Template Library (STL) II - Sets

Standard Template Library (STL) III - Iterators

Standard Template Library (STL) IV - Algorithms

Standard Template Library (STL) V - Function Objects

Static Variables and Static Class Members

String

String II - sstream etc.

Taste of Assembly

Templates

Template Specialization

Template Specialization - Traits

Template Implementation & Compiler (.h or .cpp?)

The this Pointer

Type Cast Operators

Upcasting and Downcasting

Virtual Destructor & boost::shared_ptr

Virtual Functions



Programming Questions and Solutions ↓

Strings and Arrays

Linked List

Recursion

Bit Manipulation

Small Programs (string, memory functions etc.)

Math & Probability

Multithreading

140 Questions by Google



Qt 5 EXPRESS...

Win32 DLL ...

Articles On C++

What's new in C++11...

C++11 Threads EXPRESS...

Go Tutorial

OpenCV...








Contact

BogoToBogo
contactus@bogotobogo.com

Follow Bogotobogo

About Us

contactus@bogotobogo.com

YouTubeMy YouTube channel
Pacific Ave, San Francisco, CA 94115

Pacific Ave, San Francisco, CA 94115

Copyright © 2024, bogotobogo
Design: Web Master