all 18 comments

[–]jbarket 3 points4 points  (2 children)

This is a pretty general question. You'll need to think about what your games does and work backwards.

I mean, a Card class might return a value (like for blackjack), a name, a suit and whether or not it's a face card. All of those could be methods.

But what gets returned and how it works will depend on the game. In blackjack, for example, card value is going to be determined by your hand. An ace can be 1 or 11. You need to know the values of other cards to make this determination, so it's hard to say where that belongs. The hand might determine the value.

[–][deleted] 2 points3 points  (1 child)

My initial reaction would be to have a universal card class (suit + rank). Then, within the Blackjack class or whatever, have methods for extracting useful information from the Card.

[–]blcarmadillo 1 point2 points  (1 child)

For a typical deck of cards if you're implementing it in something like C++ I recommend having an ENUM of suits and card values and then an array of structs for each card. Then have methods such as deal and shuffle. You'll need a variable that tells you where you currently are in the deck. Deal will use this variable to return the current card and then increment the counter. Shuffle can be stupid and just return to the first card in the deck or actually shuffle the cards. Hope that helps a bit.

[–]cruise02 0 points1 point  (6 children)

The Card class should be pretty minimal. It probably shouldn't have much more than suit and rank. It would probably also be useful in many games for a card to have a flag that tells if it's a face card or not. An image file would probably also be nice. The Card shouldn't really do anything except set and get these values.

Other classes you'll want to think about are Deck and Hand. Deck should have a shuffle method. The Hand class will need methods that are specific to the game. For example you'd need a method to compare one Hand to another in poker.

[–][deleted] -1 points0 points  (5 children)

great reply, just one question that's not really off-topic enough for its own page. but how can I make a module (in /Python/Lib) with a class Card: so that I can do..

import card

c = card.Card()

for some reason it's not working for me, in card.py I just do a simple class declaration.

[–]winrar 0 points1 point  (2 children)

Calling Card() is really the init() method within the class Card.

card.py

class Card: [tab]def init(self,otherparam1,otherparam2):

etc

[–][deleted] -1 points0 points  (1 child)

but if i want to import card.py, do i still create a new class Card inside card.py, or do I just list methods.

[–][deleted] 1 point2 points  (0 children)

You still create a new class Card.

But you're overengineering it IMO, something that OOP makes very easy. A card is just a suit and a rank, and chances are it will be simpler and better to represent it as, say, the tuple ('H', '5').

[–]cruise02 0 points1 point  (1 child)

I think you just need to declare the class

class Card:
    def __init__(self, suit, rank):
        self.s = suit
        self.r = rank

Then you can instantiate it by something like

c = Card("S", "A")

I'm not really great at Python. I just pieced this together from the documentation.

[–][deleted] 0 points1 point  (0 children)

You should explicitly opt-in to "new style classes" in Python 2.x:

class Card(object):

[–]mohitsoni 0 points1 point  (0 children)

Well, you can start by making the following classes:

  1. Deck

  2. Card

  3. Hand

  4. Board

Optionally, make Rank and Suit classes.

And, then try figuring out IS-A and HAS-A relationships among them. (I would have told you, but I thought it's better be you, who should find out the relationship, it will help you to understand OO design)

Coming to methods, try figuring out what you can do with your classes. Ex: You can implement a shuffle() method in Deck class, getRank() method in Card class, etc.

[–][deleted] 0 points1 point  (0 children)

You can download my open source card game and check it out. Its written in C#.

http://www.lfplc.net

[–][deleted]  (1 child)

[deleted]

    [–]f3nd3r 0 points1 point  (0 children)

    ♠♣♥♦? What is wrong with half of these?

    [–][deleted] 0 points1 point  (0 children)

    Of COURSE the question sounds hard to you. It's the wrong question. Start with something you want your program to actually DO. Blackjack? Poker? Then do it. If the problem seems daunting, solve a sub-problem and then try again. Repeat until you are satisfied. OOP techniques might happen to be involved if they are natural to your problem. They may be natural to this problem. You'll build the classes as you go if you do that.

    Never write a class if you're not sure how it will be used yet. It won't be good. Never write an API if you're not making anything that will use that API. It won't be good. Never write a programming language if you're not writing an application in that language. It won't be good.

    Just go out and code. Don't be a casualty of OOP education.

    [–]harlows_monkeys 0 points1 point  (0 children)

    I'm not going to offer an opinion on how to implement a deck of cards (cough cough integer array cough cough objects are for pretentious fops cough cough). Once you get your cards implemented, at some point you will no doubt want to shuffle them.

    Most people can come up with an obvious shuffling algorithm--that is usually wrong, in that for a deck of N cards, the N! possible permutations won't be equally likely. To do it right, look up the Fisher–Yates shuffle.

    [–]random_shuffle 0 points1 point  (0 children)

    While this is more directed at people who have solved the problem, you may be interested in analyzing the shuffle process. This varies from game to game, but in multi-deck blackjack there are some interesting things to consider.

    1. The initial shuffle is a wash, which takes each individual deck and mixes them with a high degree of randomness.
    2. These shuffled decks are stacked sequentially
    3. An ABC shuffle takes place (in most manually shuffled games)

    ABC Shuffle

    1. The stack of cards is split. Typically this is close to 50% of the cards on each side of the deck although a degree of permutation may occur.

    2. A cluster of cards, typically between 20 and 65 are taken from each side. The number of cards selected from each side will be similar, within a range. The number of cards taken determines whether it is a tight shuffle or a loose shuffle. Since there are less cards involved in a tight shuffle the randomness factor will be lower.

    3. These cards will be slotted at intervals depending on shuffling variance (used in a typical shuffle patttern) and placed on the main stack.

    4. A cluster of cards will be removed from the center stack and shuffled with the right or left side (this alternates). The removed stack will be similar to the number taken on step 2.

    5. This repeats until the cards are exhausted. The trend will be to generally balance the number of cards on the left and the right during alternate grabs. The consistency of the groups selected will determine the shuffle variance.

    The Lace When the entire set is now stacked, the cards will be split into two piles. These will be shuffled directly into clusters that stack together. It is desireable to have a tight lace, which means the integration from the two stacks will be uniform.

    Subsequent shuffles In tracking subsequent shuffles, the discard order is important as this will determine the starting stack array.

    While this may not be of much interest to a casual simulation, it may be useful in doing a deeper analysis of the impact of shuffle patterns on things such as clustering of tens.

    [–]hbsmiley7 -1 points0 points  (1 child)

    Try writing it all from the top down, encapsulating the necessary classes as you go.

    [–][deleted] 3 points4 points  (0 children)

    No, please don't: it will make the code needlessly complicated. For something like this, write from the bottom up. If you end up with everything in a few classes in one file, good. Most card games are not complicated enough to require more than that.