0

I am making an application for a card game, with a standard 52-deck playing card. For now, I am writing a solitaire game with for learning purposes. I've had some experience making platformers and arcade games, but none with card and turn-based games.

I am trying to implement some sort of MVC pattern, separating the game logic from the actual GUI. I intend to have a drag-and-drop interface for cards, but I don't know where to handle the card's position. I have a Card class that contains the rank and the suit, and other card-related methods. Should the Card class handle it's own position? Wouldn't that mean that my model is not decoupled properly? If the View should handle the card's position, wouldn't that create excessive objects and references? Any idea and argument is greatly appreciated.

1

2 Answers 2

3

Add a Table class that holds several Stacks.

Then each Stack is a list of cards where you can take the top one off and put a card on given some constraints.

Moving a card will then be (destination and source are Stacks):

if(destination.canPut(source.top())){
    destination.put(source.take());
}

The view will know where and how to render each Stack and what the cards look like etc.

Then end result is that Card is just a dumb immutable object that is contained in a Stack.

Each stack can have different constraints using polymorphism, for example the pot cannot take any cards, the result can only take cards of the same suit and 1 higher and so on.

2
  • Thanks! But how to handle when the player drags a card? For example when the player moves a card from one stack to another?
    – userx01
    Commented Dec 12, 2014 at 15:31
  • 1
    @userx01 the cursor can have a Stack that holds at most 1 card it gets the card from the Stack under the cursor when mouse down and tries to put down the card on mouse up, resetting if it fails. Commented Dec 12, 2014 at 15:38
1

Should the Card class handle it's own position?

No. As you said, a card is defined purely by its rank and suite. The 10 of Spades remains the 10 of Spades regardless of where it is. In fact I would argue cards have no relevant methods other than getting the rank and suit. (It's convenient to define equals and hashCode as methods, but if you have access to the rank and suit you can compare cards without access to their private fields. It's just simpler not to have to pass Comparators or whatnot when sorting, etc. If you make cards enums, you get this for free.)

As a side note, there's two separate concepts of position here. There's the abstract logical position relevant to the game logic (e.g. the 10 of Spades is on top of the 4th stack from the left) and then there's the presentation position (e.g. the 4th stack from the left is drawn at screen coordinates 58, 160). The abstract position of the stacks belongs in the model; the presentation position in the view.

Wouldn't that mean that my model is not decoupled properly?

Yes, if you introduce the screen position into the Card class, you've introduced coupling from the model to the view. (Coupling in the other direction - from view to model - is normal.) For example, if you wanted to make the game look fancier by having 3D cards moved around a 3D table, you'd have to change the Card class to contain 3D points instead of 2D points. You don't just want to make it so you can change view implementations by swapping one class for another - you also want to isolate the model from being impacted by changes to the view's design.

If the View should handle the card's position, wouldn't that create excessive objects and references?

I don't see how moving the card's position from one layer of the program to another changes the amount of data you have to keep track of. Even if it did, it probably won't change the asymptotic time or space usage of the program. Even if it did, it's too early to worry about optimizing if you don't have clearly-defined performance goals and an implementation you can benchmark. It's doubtful a game with such little data to keep track of will have a performance issue unless you're doing something very, very wrong.

2
  • Thanks! That makes it clear. Btw, I gotta rephrase "excessive objects and references". What I mean by that is, do I need to have a Card object, and a separate presentation object? Well, I guess it depends on how much interactivity I want to achieve.
    – userx01
    Commented Dec 12, 2014 at 17:47
  • @userx01 You'll need to keep track of the presentation position somewhere. It may or may not be an object. Since in Solitaire there's only ever 1 of each card in play you could just as well store the info in a map.
    – Doval
    Commented Dec 12, 2014 at 18:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.