Card Games - Regarding rules, actions, and turns, design question:

Started by
3 comments, last by kerilynne 16 years, 2 months ago
A: Rules, in all card game's there is a set of rules, these limit the players possible actions. A1: The actions are combinations of simple game mechanics, see the protected items in Card_Game A2: The turn is the only actual verb function here, where the player performs actions according to the ruleset, this is also why I think that the player should hold the turn function, or perhaps a turn object. This way we leave the acting part to the player, but the thinking part to the game engine. In all card games a turn may not be played the same way, but the idea of a turn remains the same. So this leaves us with two undefined, or virtual objects/functions (not sure how to implement these): The actions a player can perform, and the ruleset. This is what I need some help on. Right now the way I have it setup, the turn is always changing depending on what card game we're playing, I disagree as that all player turns technically are just implementations of possible actions checked by a ruleset. That is one fat concept to grasp, even for myself. Are there any suggestions to get me started? For the rules, one concept I read about in the past comes to mind, Functors. [Edited by - kerilynne on February 13, 2008 4:38:25 PM]
Advertisement
if (m_rHands.get_resource(player_id).px->at(m_rPlayers.get_resource(player_id).px->m_active_hand)->get_size() == 2){	//if we have two cards, make sure they are the same value	if(m_rHands.get_resource(player_id).px->at(m_rPlayers.get_resource(player_id).px->m_active_hand)->get_card(0) ==		m_rHands.get_resource(player_id).px->at(m_rPlayers.get_resource(player_id).px->m_active_hand)->get_card(1) )


Oh my god.

First, don't keep repeating all of that to get at the current hand.

Hand* hand = m_rHands.get_resource(player_id).px->at(m_rPlayers.get_resource(player_id).px->m_active_hand);if (hand->get_size() == 2) {	//if we have two cards, make sure they are the same value	if (hand->get_card(0) == hand->get_card(1) 


But why do you have to do that much work just to get a Hand? What is a Resource_Manager<T>, and what does its .get_resource() return? (It appears, in turn, that the .px member of the returned thing is a T?)

I think a lot of this complexity comes from trying to shove all the games together into a class instance that somehow represents "the concept of a game of cards", rather than having it represent "an instance of the playing of a game of cards", and making a separate instance for each game. Are you expecting to have a game where decks are shared between games? No? Then just make each game have a deck of cards as a data member directly, and make several games. Even if you need multiple "decks of cards" per game, just store a vector of decks (not pointer-to-deck! Or what, exactly, is going to be polymorphic about a deck of cards?).

Further, your abstraction is broken. The terms "split_hand" and "check_hand_value" make sense for very few games other than Blackjack, and even for example "place_bet" is far from universal. The name "give_player_hand" is incredibly awkward; how about "deal_to(const std::string& player_id)"?

Finally, don't write init() and cleanup() functions. That's what RAII is for. Do init work in a constructor, and cleanup work in a destructor. (You will need to make the destructor of the base class 'virtual' anyway, if you want to be able to use the class polymorphically in all the expected ways.)
Thanks for completely picking apart the class and ignoring the question.
Jeeze I might as well just remove the code because it's just a distraction to the original question.


Edit:

Quote:
Are you expecting to have a game where decks are shared between games?

The question is, do you want to make a game that has that feature?
Need multiple decks of cards? We got that too!


Quote:
The terms "split_hand" and "check_hand_value" make sense for very few games other than Blackjack

Again, the question is, do you want to make a game that has that feature?
Quote:
what is going to be polymorphic about a deck of cards?


Note: don't limit yourself to a 52 card deck, or actual standard playing cards

Quote:
The name "give_player_hand" is incredibly awkward; how about "deal_to(const std::string& player_id)"?

/agreed
Quote:
First, don't keep repeating all of that to get at the current hand.

/agreed

Quote:
and even for example "place_bet" is far from universal.

depends on the system backing it up.

Quote:
Finally, don't write init() and cleanup() functions

Legacy code, thanks.

BTW did you actually read the text in my post?

Now that I've answered his questions, will anyone answer mine?

[Edited by - kerilynne on February 13, 2008 4:28:06 PM]
Quote:Original post by kerilynne
A: Rules, in all card game's there is a set of rules, these limit the players possible actions.

This is too vague and obvious to qualify as design.
Quote:A1: The actions are combinations of simple game mechanics, see the protected items in Card_Game

We don't see them, because you pulled away the code example after Zahlman's mild constructive criticism.
Quote:A2: The turn is the only actual verb function here, where the player performs actions according to the ruleset, this is also why I think that the player should hold the turn function, or perhaps a turn object.

Please explain; at least the difference between a turn and an action.
In any case, why should Player objects own or define anything related to turns? Aren't they a part of a game in progress?
Quote:This way we leave the acting part to the player, but the thinking part to the game engine.

As words are used normally, the contrary is true: the player or an equivalent AI module "thinks" and gives commands, while the game engine acts on the representation of the game in progress and enforces game rules.
Quote:In all card games a turn may not be played the same way, but the idea of a turn remains the same.

Zahlman already touched this point but you didn't answer: are you speaking of what the rules of a particular game allow in a turn, of an abstraction over different turn-based game rulesets, or of a particular game played with a particular ruleset?
Quote:So this leaves us with two undefined, or virtual objects/functions (not sure how to implement these): The actions a player can perform, and the ruleset. This is what I need some help on.

Some help? You simply pushed all the complexity of a game into two vaguely defined and deeply interdependent boxes, which again doesn't qualify as design.

Trying to design a generic universal card game engine isn't a reasonable objective; implement a specific game, which is hard enough, and generalize it with additional specific games, for example reusing draw poker to implement Texas hold'em or extracting commonality between Blackjack and other similar casino games.

Omae Wa Mou Shindeiru

Quote:Please explain; at least the difference between a turn and an action.


Quote:
Turn:78. that which is done by each of a number of persons acting in rotation or succession.

Sounds right to me.
Quote:
Action:10. the mechanism by which something is operated, as that of a gun or a piano.

or perhaps a turn in a card game?

Quote:
In any case, why should Player objects own or define anything related to turns? Aren't they a part of a game in progress?


They don't own or define any of that.
But they are aware of the definition of their specific turn, which is governed by an evaluation of their hand, or rules.

Quote:
the player or an equivalent AI module "thinks" and gives commands, while the game engine acts on the representation of the game in progress and enforces game rules.

You mean the same way the player has to think about what they can do in a turn?

Quote:
of an abstraction over different turn-based game rulesets

That one!




This topic is closed to new replies.

Advertisement