Share My Creation Card Game Shell for programmers

The attached file is a shell for writing card games. It contains the standard 52 card faces plus a variety of card backs and Jokers, along with the code for manipulating and showing them.

Routines include the following:

ShuffleCards - mixes up the cards and "deals them" to four hands (puts them into four sorted arrays).

ShowHand - displays the user's hand at the bottom of the screen.

Card_Click - either raises the user's selected card above the rest or plays the card by moving it to the center of the table and realigning the remaining cards.

AllowSuit - when a user must play from a specific suit, the cards in the others suits are darkened and disabled.

It should be fairly easy to adjust the code for different numbers of hands, card display location, etc.

I couldn't get automatic adjustment in the code to work for different screen dimensions and densities, so three layouts are included in landscape orientation: 800x480x160, 800x480x240, and 480x320x160. If you have a device on which none of these looks right and can fix it, I would appreciate getting the layout to include. Or if you can do it all programmatically, that would be good too.

Any other general purpose card handling routines are welcomed as well. Thanks to "dlfallen" who provided the card faces and some other help, as well as others on the forum who helped.

This is public domain, so do whatever you want with it. I'm working on converting my old CardShark Hearts and CardShark Spades games, so don't do those games!! :)
 

Attachments

  • CardGameShell.zip
    176.7 KB · Views: 3,592
Last edited:

dlfallen

Active Member
Licensed User
Longtime User
I am looking at your ShuffleCards sub and have two comments.

First, in your loop (For i = 0 to 51) you have k = Rnd(1,52). This should be Rnd(0,52). Not allowing the first card to swap when i = 0 introduces an unneeded bias.

Second, and more importantly this sub could be greatly improved. I used the same logic as yours in my previous card programs and thought it to be adequate. It seemed obvious to me that one pass would result in a random order, so I initially did not understand your stating a need for multiple passes. After a little reflection, it bacame obvious to me that your (and my) logic did not result in a completely unbiased sort. However, rather than repeating a defective sort 10 times, I simply googled "card shuffle algorithm" and quickly found the Fisher-Yates shuffle. It is a very simple method to generate a random (unbiased) permutation in only one pass. In the "for what it's worth" department, that one pass is faster than the defective one you and I were previously using.

To implement the Fisher-Yates shuffle, only a small change is made to your code: k = Rnd(i,52). That is, cards are only swapped with other cards farther down in the order. E.g., Card(0) can be swapped with any card, Card(1) can be swapped with cards 1-51, Card(23) can be swapped with cards 23-51, etc.

Interesting stuff . . .
 

nfordbscndrd

Well-Known Member
Licensed User
Longtime User
Regarding the sort routine -- being a card player/shuffler all my life, it would have never crossed my mind that an algorithm like Fisher-Yates could sufficiently "mix" a sorted list of 52 numbers in one pass-through. The first card you swap never gets swapped again, while those further down the list get swapped multiple times. Just seems anti-intuitive to me.

I did a little Googling on it myself. The funny thing is that back when I wrote CardShark Hearts and CardShark Spades, which is what I'm porting over, I had Knuth's book that they say has the FY algorithm in it, but never noticed it for some reason.

An odd thing about the algorithm is that everywhere I saw it, people had it looping down from the last index number in the array instead of looping up from 0. I can't see that it makes any difference which way you go. Is there some theoretical advantage to looping down?

Anyway, I have uploaded a revised edition to the original post.

Thanks.
 
Last edited:

dlfallen

Active Member
Licensed User
Longtime User
Regarding the sort routine -- being a card player/shuffler all my life, it would have never crossed my mind that an algorithm like Fisher-Yates could sufficiently "mix" a sorted list of 52 numbers in one pass-through. The first card you swap never gets swapped again, while those further down the list get swapped multiple times. Just seems anti-intuitive to me.
It seemed counter intuitive to me also. I guess that is what makes great statisticians like Fisher and Yates so special -- they see things ordinary people do not.

Notice that in the loop, there are N! possible swaps, meaning there are N! possible results. Also note that for N cards, there are exactly N! different permutations. This is not accident - the Fisher Yates Shuffle randomly generates one of the possible permutations. Each permutation is equally likely. Thus, one pass through this shuffle is as random as possible - further shuffling would be pointless. For grins, I ran through a 3-card deck and a 4-card deck manually and, of course, I obtained each possible permutation one time.

An odd thing about the algorithm is that everywhere I saw it, people had it looping down from the last index number in the array instead of looping up from 0. I can't see that it makes any difference which way you go. Is there some theoretical advantage to looping down?
I too noticed this and I agree that it should not make any difference. The 3 and 4 card manual illustrations (mentioned above) were done without looping down and, as I said, I got perfect results.
 

ibra939

Active Member
Licensed User
Longtime User
wonderful
 
Top