Take the 2-minute tour ×

Say I want to write a card game. I have a hand of cards and I want to be able to draw a smooth animation of a card moving from the hand to the table. I am looking for suggestions on how to elegantly represent the situation in data structures. Of course, I am not solely interested in cards, it seems to be a problem with more complex user interfaces in general.

The obvious representation of the hand is an array/list of cards. Given a rectangle in 2d space this hand is trivial to draw. When playing a card I can remove that card from the array and create a new structure that draws that card moving along any curve I like. The problem is then how the hand is drawn. In trivial implementation the hand in one instant shrinks in width by one card (as the array was replaced). Also, the selected card is now either above or bellow the hand (as it is drawn before or after drawing the hand), while a moment ago it was between the two cards next to it. These problems I'm not sure how to solve. They get even worse if trying to move several cards at once.

It would most likely work to make every card a separate body aware of it's position and movement in the plane (and possibly, the z axis to make overlaps work, as OpenGL allows this). It does seem like poor design to allow a system that almost always stays in a fixed shape too much flexibility. It also looks like a recipe for unexplainable bugs.

I would like to hear from someone who has done this, what is the best approach. To put it briefly, "specific and restrictive representation in data structures" versus "entirely free environment with some external limits".

Thanks a lot

share|improve this question
add comment

1 Answer

Separate the idea of viewing the cards, and handling the logic for the card game.

The view is 5 cards (say) lying face up (or down) on the table, slightly overlapping. The actual hand is, as you said, an list of card objects. The rules of the game operate on the list, because this is the problem domain for your program, the visuals work with the view.

When you then take a card out and place it on the table, the action is first checked to be legal by the domain code, then it makes the changes to the lists holding the cards, and give a description of what happened to the view. This description is as simple as "Three of spades" discarded, in whichever format works best for your language (object/enum/even string).

Now the view simply animates the visual representation of the card being thrown into the discard pile, or placed face up in a specific spot, depending on the cardgame itself. Because it now has a gap where the card used to be, it can now animate the cards sliding together, or any other thing you want. Once the animations has been completed it can update any changes from the domain as needed.

This allow you to focus on the games rules when working with the domain, as well as the artificial intelligence (if one exists) without considering animations. Then when you go to the view code you simply need to make animations for each of the actions. "Discard" would have one animation. "Draw new card" another. And so on.

This may not be the "best" example, but divide and conquer is a good strategy, reduce the problem into smaller problems and solve them one at a time.

share|improve this answer
What bothers me here is that this way view has to have additional data about the cards (positions, animations) not present in the model. Isn't that the kind of tight coupling that should be avoided? –  Karolis Juodelė Aug 23 '12 at 5:45
This is data about the cards that makes no sense in the domain code (position 5,12 vs 6,12 makes no difference to the game, the card is still in your hand), but its required for the view to do its job. So it belongs in the view. Views tend to be fairly tightly coupled, but also fairly minimal, they only have the data they need for displaying something, they don't know anything more than that nor are responsible for accepting/rejecting moves. Views have an implicit knowledge about the domain, such as you don't bother making an animation for something that can't happen (say ripping the card up). –  Daniel Carlsson Aug 24 '12 at 11:23
While view data makes no sense inside model, model data is already present inside view. It seems like a waste to have view and model as separate. With some magic I might even merge them elegantly... –  Karolis Juodelė Aug 24 '12 at 12:24
add comment

Your Answer


