C++ Poker, Looking for guidance... a push in the right direction even.

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 883 Views - Last Post: 06 October 2012 - 06:54 PM Rate Topic: -----

#1 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

C++ Poker, Looking for guidance... a push in the right direction even.

Posted 05 October 2012 - 11:17 PM

Hi everyone. First off, I love your site. It has helped me a great deal so now I will seek my own help for the first time. I am a Game Programming student in need of a push in the right direction. For my current class project, I need to come up with a simple game with the only requirements being that I must use four unique STL data structures. I have chosen to do a simple poker game and I have implemented a stack, vector, and list. For the fourth, I'm thinking maybe the map container to display the winning hands... Royal Flush, Full House, etc. I'm not really sure where to start in even evaluating the hands though. My code:

DeckOfCards.h:

struct Card{
	string value;
	char suit;
};  // end Card structure

class DeckOfCards
{
public:
	static const int CARD_COUNT = 52;
	static const int VALUE_COUNT = 13;
	static const int SUIT_COUNT = 4;

	DeckOfCards();
	void Shuffle();
	Card Deal();

	friend ostream & operator<< (ostream &os, const Card &myCard);

private:
	vector<Card> newDeck;
	stack<Card> shuffledDeck;

	void StoreInStack();

};  // end DeckOfCards class



DeckOfCards.cpp

DeckOfCards::DeckOfCards()
	: newDeck(CARD_COUNT)
{
	static char suit[SUIT_COUNT] = { 3, 4, 5, 6 };  // ASCII codes for card suits 
	static string value[VALUE_COUNT] = { "A", "2", "3", "4", "5", "6", "7", 
										 "8", "9", "10", "J", "Q", "K" };  // string to get the 10

	// create a deck
	for (int i = 0; i < CARD_COUNT; i++)
	{
		newDeck[i].value = value[i % VALUE_COUNT];
		newDeck[i].suit = suit[i / VALUE_COUNT];
	}

	srand((int)time(0));

}  // end constructor

void DeckOfCards::Shuffle()
{
	// shuffle the vector from <algorithm>
	random_shuffle(newDeck.begin(), newDeck.end());
	// just as the name implies
	StoreInStack();

}  // end shuffle

Card DeckOfCards::Deal()
{
	// top card
	Card card;
	card = shuffledDeck.top();
	// remove from the stack and return
	shuffledDeck.pop();
	return card;

}  // end deal

void DeckOfCards::StoreInStack()
{
	for (int i = 0; i < CARD_COUNT; i++)
	{
		shuffledDeck.push(newDeck[i]);
	}

}  // end StoreInStack

ostream& operator<< (ostream& os, const Card &aCard)
{
	os << (aCard.value + aCard.suit);
	return os;

}



PokerHand.h

class PokerHand
{
public:
	PokerHand();
	void AddCard(const Card &dealtCard);
	void DisplayDealtHand();
	
private:
	list<Card> dealtHand;

};  // end PokerHand class



PokerHand.cpp

PokerHand::PokerHand()
{
}

void PokerHand::AddCard(const Card &dealtCard)
{
	list<Card>::iterator pos = dealtHand.begin();
	dealtHand.insert(pos, dealtCard);

}  // end AddCard

void PokerHand::DisplayDealtHand()
{
	if (!dealtHand.empty())
	{
		int count = 1;
		list<Card>::iterator pos = dealtHand.begin();

		while (pos != dealtHand.end() && (count < 8))
		{
			cout << setw(4) << (*pos);
			pos++;
			count++;
		}  // end while
	}  // end if

}  // end DisplayDealtHand



main.cpp

int main()
{
	const int MAX_HAND = 7;

	DeckOfCards theDeck;
	PokerHand player1;
	PokerHand player2;

	theDeck.Shuffle();

	for (int i = 0; i < MAX_HAND; i++)
	{
		player1.AddCard(theDeck.Deal());
		player2.AddCard(theDeck.Deal());
	}

	cout << "Player 1's dealt hand:";
	player1.DisplayDealtHand();
	cout << "\nPlayer 2's dealt hand:";
	player2.DisplayDealtHand();

	cout << "\n\nChoosing best hand for each player";
		for (int i = 0; i < 5; i++)
		{
			cout << " .";
			Sleep(1000);
		}
		cout << endl;

	cout << "\n\nPlayer 1 discards:" << endl;
	cout << "\t\t\tPlayer 1 plays:" << endl;

	cout << "\n\nPlayer 2 discards:" << endl;
	cout << "\t\t\tPlayer 2 plays:" << endl;

	cout << endl << endl;
	system("pause");

}  // end main



Again, I'm just looking for suggestions/guidance towards evaluating a hand and implementing a fourth data structure with what I have so far.

Thanks in advance.

Is This A Good Question/Topic? 0
  • +

Replies To: C++ Poker, Looking for guidance... a push in the right direction even.

#2 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,993
  • Joined: 05-May 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 12:40 AM

Ummm, why can't a Card simply use the std::pair<> or std::tuple<> and you have your fourth STL data structure? Or does it have to be a container type STL data structure?
Was This Post Helpful? 0
  • +
  • -

#3 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 01:18 AM

View PostSkydiver, on 06 October 2012 - 12:40 AM, said:

Ummm, why can't a Card simply use the std::pair<> or std::tuple<> and you have your fourth STL data structure? Or does it have to be a container type STL data structure?


Sorry, I didn't make that too clear. It would be the latter and they need to be four different containers. I have a vector creating and shuffling, a stack of shuffled cards to deal from, and a list to deal the cards in to. I figured a map would be good to hold the names of each of the winning hands. However, I'm open for any other suggestions because this particular class won't go into maps. I was just feeling ambitious and wanted to learn something not covered in the course. I can't even grasp evaluating the hands right now though which is why I'm just looking for any guidance/hints to get my mind in the right direction.
Was This Post Helpful? 0
  • +
  • -

#4 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,636
  • Joined: 16-October 07

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 01:36 AM

"four unique STL data structures" sounds rather arbitrary. I'd think string is a gimme, which pushes you over to four. Do the structures need to be class level members? Because stack and vector in Deck is messy, but you could use vector in a method. You could use std::array in the shuffle, which actually does make sense.

Code comments. Get the srand out of Deck. Call it once, and only once, in main. Get rid of friend, you don't need it.
Was This Post Helpful? 1
  • +
  • -

#5 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 02:08 AM

View Postbaavgai, on 06 October 2012 - 01:36 AM, said:

"four unique STL data structures" sounds rather arbitrary.

Tell me about it. This entire class has been that way.

View Postbaavgai, on 06 October 2012 - 01:36 AM, said:

Because stack and vector in Deck is messy...

Care to enlighten me as to why?


Originally, this was an assignment: "Create a simplified 7 card poker game (cards are dealt once, no replacement). Use a vector to store the 52 cards. "Shuffle" the vector and output into a stack. Deal 7 cards to each player from the stack alternating 1 player then the other. Store each player's hand in a list."
And then we were given another: "Create a completely functional game that includes the following: 4 distinct data structures. You can add things like “move history” if necessary to reach this goal..." So I'm basically taking the first assignment to do the second because 3 of the 4 were already there. If I have to, for the sake of making things easier on myself, I'll take your suggestions and implement them. I take it you don't like my idea of the map use?

Thank you for the code comments. Those are always appreciated and welcomed.
Was This Post Helpful? 0
  • +
  • -

#6 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,636
  • Joined: 16-October 07

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 04:55 AM

View Postlithium462, on 06 October 2012 - 05:08 AM, said:

Care to enlighten me as to why?


Hmm... right. Why have a class at all? A class stores data and methods that leverage that data. More, a class, or rather an instance of a class, represents state. In C++, if a method doesn't change state, well call it const. It's that important.

In your DeckOfCards you have two public methods, Shuffle and Deal. Both of these methods change stack. That vector is dead weight. You only need it for shuffle. Your object should on contain what's needed for it's state. If there are variables that can be moved into methods, they should be.

To give an idea, this is how I'd do you two classes:
class Card {
public:
	static const int FACE_COUNT = 13;
	static const int SUIT_COUNT = 4;
	static const int MAX_VALUE = 53;
	static const int INVALID_VALUE = -1;
	Card() : value(INVALID_VALUE) {}
	Card(int v) : value((v<0||v>MAX_VALUE)?INVALID_VALUE:v) {}
	bool isValid() const { return value!=INVALID_VALUE; }
	int getFace() const { return value % FACE_COUNT; }
	int getSuit() const { return value / FACE_COUNT; }
	int getValue() const { return value; }
	
	char getSuitChar() const { return isValid() ? getSuit() + 3 : 'X'; }
	const char *getFaceShortName() const { 
		static const char *name[FACE_COUNT] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
		static const char *bad = "X";
		return isValid() ? name[getFace()] : bad;
	}
	void print(ostream &out) const { out << getFaceShortName() << getSuitChar(); }
private:
	int value;
};

ostream & operator<< (ostream &out, const Card &card) { card.print(out); return out; }


class DeckOfCards {
public:
	static const int CARD_COUNT = 52;
	DeckOfCards();
	void shuffle();
	Card deal();
	void reset();
	bool empty() const;

private:
	std::stack<Card> cards;
};



DeckOfCards::DeckOfCards() { reset(); }

void DeckOfCards::reset() {
	while(!cards.empty()) { cards.pop(); }
	for(int i=CARD_COUNT-1; i>=0; i--) { cards.push(Card(i)); }
}

void DeckOfCards::shuffle() {
	vector<Card> remaining;
	while(!cards.empty()) {
		remaining.push_back(cards.top());
		cards.pop();
	}
	random_shuffle(remaining.begin(), remaining.end());
	for(vector<Card>::iterator it = remaining.begin(); it!=remaining.end(); ++it) {
		cards.push(*it);
	}
}

Card DeckOfCards::deal() {
	if (!empty()) {
		Card card = cards.top();
		cards.pop();
		return card;
	}
	return Card();

}

bool DeckOfCards::empty() const { return cards.empty(); }


Was This Post Helpful? 1
  • +
  • -

#7 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 08:52 AM

View Postbaavgai, on 06 October 2012 - 04:55 AM, said:

Your object should only contain what's needed for it's state. If there are variables that can be moved into methods, they should be.


This is why I come here for answers. I completely understand what you are saying and appreciate your time and response. And thank you for your code example. It always helps to see a more advanced coders perspective on what I've done.


Other than what you have already noted, is my version not really set up well enough to begin implementing a hand evaluator? This could be why I keep running into walls.
Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,993
  • Joined: 05-May 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 09:13 AM

As an aside, random_shuffle() is part of the C++ standard library.

As for hand evaluation, do you just need to be able to tell one hand beats another hand? Or do you need some kind of metric that computes the probability of there being a winning hand given the known cards?

This post has been edited by Skydiver: 06 October 2012 - 09:14 AM

Was This Post Helpful? 0
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,636
  • Joined: 16-October 07

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 09:30 AM

As long as you can examine each card in a hand, then you can write an evaluater.

You could simply have something like:
int PokerHand::compare(const PokerHand &other) { /* your code here */ }



Though, logically, you might consider:
enum HandType { StraightFlush, FourOfAKind, FullHouse, Flush, Straight, ThreeOfAKind, TwoPair, OnePair, HighCard };
void eval(HandType &, Card &highCard);



Now address each of those types. There is, obviously, some fall through on evaluation.
Was This Post Helpful? 1
  • +
  • -

#10 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 09:32 AM

View PostSkydiver, on 06 October 2012 - 09:13 AM, said:

As for hand evaluation, do just need to be able to tell one hand beats another hand? Or do you need some kind of metric that computes the probability of there being a winning hand given the known cards?

Neither. :) I just want to check a dealt hand for a straight, full house, flush, etc. Winning hands are pretty similar. I suppose I just write a function that will check for like values which should find pairs, three of a kind, and four of a kind. But a full house is a "paired" pair and three of a kind. Hmmm.. I think I'm having an "Ah-ha" moment. The more I write about this, the more my brain wants to actually start working.

And I understand random_shuffle is part of the library. I wasn't very clear in my initial post... I need four containers. But that's really not as much of an issue as finding a winning hand within a dealt hand.
Was This Post Helpful? 0
  • +
  • -

#11 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 09:41 AM

View Postbaavgai, on 06 October 2012 - 09:30 AM, said:

As long as you can examine each card in a hand, then you can write an evaluater.

You could simply have something like:
int PokerHand::compare(const PokerHand &other) { /* your code here */ }



Though, logically, you might consider:
enum HandType { StraightFlush, FourOfAKind, FullHouse, Flush, Straight, ThreeOfAKind, TwoPair, OnePair, HighCard };
void eval(HandType &, Card &highCard);



Now address each of those types. There is, obviously, some fall through on evaluation.


Cool. Thank you! I'll run with this along with the "Ah-ha" moment I just had while replying to Skydiver.
Was This Post Helpful? 0
  • +
  • -

#12 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,993
  • Joined: 05-May 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 10:01 AM

View Postlithium462, on 06 October 2012 - 09:32 AM, said:

And I understand random_shuffle is part of the library. I wasn't very clear in my initial post... I need four containers. But that's really not as much of an issue as finding a winning hand within a dealt hand.


I only mentioned it as an aside because I noticed both you and baavgai implemented your own shuffle when you can use a the standard library implementation instead. I wasn't trying to imply that the algorithm was another container.

As for containers, you have lots of choices: http://en.cppreferen...w/cpp/container
Was This Post Helpful? 1
  • +
  • -

#13 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 10:41 AM

View PostSkydiver, on 06 October 2012 - 10:01 AM, said:

I only mentioned it as an aside because I noticed both you and baavgai implemented your own shuffle when you can use a the standard library implementation instead. I wasn't trying to imply that the algorithm was another container.

As for containers, you have lots of choices: http://en.cppreferen...w/cpp/container



Gotcha. After I get the evaluating done (which I think I have a handle on now :) ), I think I'm just going to implement a queue to store the winners during the session. BOOM! There's the fourth. Just keeping it simple at this point as this is due tomorrow and I procrastinated on it. Thanks again baavgai and Skydiver for your time.
Was This Post Helpful? 0
  • +
  • -

#14 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5800
  • View blog
  • Posts: 12,636
  • Joined: 16-October 07

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 01:34 PM

View PostSkydiver, on 06 October 2012 - 01:01 PM, said:

I only mentioned it as an aside because I noticed both you and baavgai implemented your own shuffle


I used #include <algorithm> and the very function you pointed to. I assumed the OP did the same. I also assumed, given just "string" that "using namespace std;" was in affect. So, um, huh?
Was This Post Helpful? 0
  • +
  • -

#15 lithium462  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 05-October 12

Re: C++ Poker, Looking for guidance... a push in the right direction even.

Posted 06 October 2012 - 02:38 PM

View Postbaavgai, on 06 October 2012 - 01:34 PM, said:

I assumed the OP did the same. I also assumed...


You have assumed.... wisely. I have been coding for less than two years now and I've learned a lot from this site. One thing was to use std::string, std::stack, etc. instead of using namespace std;. But this assignment has been a pain (mostly due to my hectic schedule lately) and I'm just trying to do get it over with. Why I even stressed over it enough to write the forums, I don't know. I guess I just needed to chat with someone, other than myself, to get through the cloud left by my brain fart.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2