I 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:
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:
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:
- The deck is shuffled and each player is dealt a hand of 26 cards.
- 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.
- 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.
- 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.
- 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:
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), card1) print "Player Two plays the %s of %s." % (card_name(card2), card2) play_winner = check_cards(card1, card2) 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.