Hello,<br><br>Just my .02€ to this thread:<br><br><br><br><div><span class="gmail_quote">2008/2/5, Andreas Pakulat <<a href="mailto:apaku@gmx.de">apaku@gmx.de</a>>:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Currently this is a QFlags thingie, i.e. an enum with values 2, 4, 8,<br>... However this is limiting us to 32 elements, and 18 are already<br>taken by a 52 card deck.</blockquote><div><br>I don't think that using QFlags here is a good idea, because it wastes so many bits for invalid combinations. E.g., it doesn't make sense to specify a card like "Spades | Diamonds | Queen", or "Hearts | Queen | Jack".<br>
The suit of a card can be specified in 2 bits (instead of 4 with QFlags), that prevents invalid combinations for free, and the value of a 52 cards deck with wildcards can be specified in 4 bits. <br>One could use the old technique of just combining bits using "|", and use enums like<br>
<br>enum Suit {Diamonds = 0x0, Hearts = 0x1, Spades = 0x2, Clubs = 0x3};<br>enum Value {Joker = 0x0, Ace = 0x4, Two = 0x8, Three = 0xC, Four = 0x10, Five = 0x14, Six = 0x18, Seven = 0x1C, Eight = 0x20, Nine = 0x24, Ten = 0x28, Jack = 0x2C, Queen = 0x30, King = 0x34};<br>
<br>Then you can specify a card like "Nine | Diamond" (or "Nine + Diamond"). The advantage is that the cards are sorted automatically (of course not addressing the problem that the ace is at the same time lower than 2 and higher than king).<br>
</div><br>If you want to prevent expressions like "Ace | Jack" or "Three | Diamonds | Spades", and at the same time get the type safety similar to that of QFlags, a class for creating a card could be used; something like<br>
<br>class Card<br>{<br> public:<br> Card (Suit s, Value v) {card = s|v;} // create a card like "Card (Diamonds, Ace)"<br> Card (Value v, Suit s) {card = s|v;} // create a card like "Card (Ace, Diamonds)"<br>
<br> operator int () const {return card;} // return the combined card value as an int<br><br> Value value () const {return card & 0x3C;} // return the value of the card (Joker, Ace, ...)<br> Suit suit () const {return card & 0x03;} // return the suit of the card (Diamonds, Hearts, ...)<br>
<br> private:<br> int card;<br>};<br><br>Using this class as a parameter type, a card instance can only be created with exactly one suit and exactly one value. Trying to create a card other than that results in a compiler error. You could of course add further methods like "setValue", "setSuit", "operator==", "operator!=", "operator<", etc.<br>
<br>If you also want to keep "Diamonds | Ace" valid, you can define the operators<br><br>Card operator| (Suit s, Value v) {return Card (s, v);}<br>Card operator| (Value v, Suit s) {return Card (s, v);}<br><br>And this is just the beginning. Thinking of other cards like, e.g., tarrot cards, one could think of additional enums and additional constructors of "Card". Or maybe a subclass of "Card" that provides support for other card types. You just have to keep the value of the internal "card" attribute unique. This reminds me of unicode: Every type of card deck has a specific range. The "traditional" card deck of 52 cards plus wildcards occupy the numbers "0" (Diamonds | Joker) to "55" (Clubs | King). Tarrot cards may occupy "54" to "82" (I have no idea how many different cards tarrot has). One could even think of some "Memory" like game to have its own range within the Card class.<br>
Maybe also a method that returns some kind of class ID could be usefull, to check whether an svg card deck matches the cards that can be contained within a Card instance.<br><br>Maybe I haven't seen one or the other drawback or pitfall in the approach I described, but I leave the "work" to you. :-)<br>
<br>Burkhard<br><br></div>