• About
  • Contact
  • What People Are Saying

Introduction to writing card games in Python

Mar19th
2012
2 Comments Written by Daniel Veazey

Queen of HeartsI want to make card games with Python, so I think about how to simulate a deck of cards. Some of the properties of a deck are such: It has 52 unique cards. Each card consists of a rank: 2 through 10 and Jack, Queen, King, Ace; and a suit: Clubs, Diamonds, Hearts or Spades. Cards move around from the deck to a player’s hand, to being “in play” on the table, or to the discard pile, or perhaps any number of places, depending on the rules of the game you are playing with them. For the sake of sanity, a card cannot be in more than one place at one time.

So creating a shuffled deck of cards is very simple. If you think of the values of Jack, Queen, King and Ace as 11, 12, 13, and 14, you can implement a deck with just a few lines of code in a function:

A deck of cards   
import random
 
def shuffled_deck():
    deck = []
    for suit in ['Clubs', 'Diamonds', 'Hearts', 'Spades']:
        for num in xrange(2, 15):
            deck.append([num, suit])
    random.shuffle(deck)
    return deck

Now you can do all kinds of operations on this list of cards you’ve created, and that’s where you start getting into the rules of whatever game you’re playing. I decided to start out with the simplest game I could think of: War. But before I get into that, I want to make the cards a little more user friendly. Right now the cards have a number and a suit. But say you get the 12 of Clubs. That’s not really a card. It should be called the Queen of Clubs. I wrote another little function that will return the proper name for a card when passed the value of its rank:

Proper card names   
def card_name(card):
    if card == 11:
        return 'Jack'
    elif card == 12:
        return 'Queen'
    elif card == 13:
        return 'King'
    elif card == 14:
        return 'Ace'
    else:
        return str(card)

Now I want to make the computer play War against itself. You might play War differently than this, but here are the rules I made it play by:

  1. The deck is shuffled and each player is dealt a hand of 26 cards.
  2. Each player plays the first card from their hand. Whichever card has a higher rank wins, and the player takes both cards and places them in his or her “won” pile.
  3. If the two cards in play are of the same rank, those remain on the table and each player reveals another card. Once a player wins a round, the tying cards from the previous round (or rounds) are all won by the winner of the most recent round.
  4. When all cards are depleted from a player’s hand, the cards in that player’s “won” pile are shuffled and then become the player’s new hand, and play continues.
  5. The game is won when one player has taken all the cards. If the final round is a tie, no one wins that round and the winner of the game is determined by who has the most cards.

So with that, here is the full code for War:

Code block   
import random
 
def shuffled_deck():
    deck = []
    for suit in ['Clubs', 'Diamonds', 'Hearts', 'Spades']:
        for num in xrange(2, 15):
            deck.append([num, suit])
    random.shuffle(deck)
    return deck
 
def card_name(card):
    if card == 11:
        return 'Jack'
    elif card == 12:
        return 'Queen'
    elif card == 13:
        return 'King'
    elif card == 14:
        return 'Ace'
    else:
        return str(card)
 
def deal_cards(deck):
    return deck[::2], deck[1::2]
 
def check_cards(player1, player2):
    if player1 > player2:
        return 'player1'
    elif player1 < player2:
        return 'player2'
    else:
        return 'tied'
 
def replenish(wonpile):
    random.shuffle(wonpile)
    return wonpile
 
deck = shuffled_deck()
hand1, hand2 = deal_cards(deck)
ontable = []
round = 0
hand1won = []
hand2won = []
 
while len(hand1) > 0 and len(hand2) > 0:
    round += 1
    print "Round %d" % round
    card1 = hand1.pop(0)
    card2 = hand2.pop(0)
    ontable.extend([card1, card2])
    print "Player One plays the %s of %s." % (card_name(card1[0]), card1[1])
    print "Player Two plays the %s of %s." % (card_name(card2[0]), card2[1])
    play_winner = check_cards(card1[0], card2[0])
    if play_winner == 'player1':
        print "Player One wins the round."
        hand1won.extend(ontable)
        ontable = []
    elif play_winner == 'player2':
        print "Player Two wins the round."
        hand2won.extend(ontable)
        ontable = []
    elif play_winner == 'tied':
        print "The players tie for this round and the cards remain on the table."
    print "The score is now Player One: %s, Player Two: %s" % (len(hand1won)+len(hand1), len(hand2won)+len(hand2))
    if len(hand1) == 0 and len(hand1won) > 0:
        print "Player One replenishes."
        hand1 = replenish(hand1won)
        hand1won = []
    if len(hand2) == 0 and len(hand2won) > 0:
        print "Player Two replenishes."
        hand2 = replenish(hand2won)
        hand2won = []
 
if len(hand1) > len(hand2):
    print "Player One wins the game!"
elif len(hand1) < len(hand2):
    print "Player Two wins the game!"

I think I will try a game of Go Fish next.

Be Sociable, Share!
  • Tweet

Related posts:

  1. Thinking about Go Fish with Python
  2. Python Sudoku solver
  3. Programming with Python
  4. Calculating and testing probability with Python
  5. Working on the bike problem with Python
Python
SHARE THIS Twitter Facebook Delicious StumbleUpon E-mail
← A PyPy experiment
Thinking about Go Fish with Python →

2 Comments

  1. Aliah's Gravatar Aliah
    November 29, 2012 at 7:58 pm | Permalink

    Could you please put do a game of Rummy?? I have been having trouble doing it and would very much appreciate any help!
    Aliah

  2. Daniel Veazey's Gravatar Daniel Veazey
    November 30, 2012 at 1:56 pm | Permalink

    The only card game I’ve written is War, which has an extremely simple set of rules. Something like Rummy would require many more lines of code, not to mention creating a strategy that a computerized opponent would need to follow. It would require an effort much greater than my motivation allows. But thanks for the question.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Why you should leave a comment

1. I read all the comments.
2. I reply and answer every question.
3. I always click through to see the sites of commentators.
4. Because you can.
5. You become a participant instead of just an observer.

EvoLve theme by Theme4Press  •  Powered by WordPress Daniel Veazey
Things I find interesting