Deck of Cards

Overview:  You will create a program that makes a deck of playing cards, and then keep adding, testing, and improving features until you run out of project time.

Project Grading Guidelines:

  • Programming – You need to be seen writing and testing code during class in order to provide evidence that you are the programmer. Ask questions about your code and discuss challenges that come up with your teacher during this project to provide more evidence that you are gaining programming proficiency.
  • Computational Artifact – how many interesting and unique features can you add to your code?

Create a python program that makes a list containing all 52 cards in a deck of cards. As you work through this assignment, you will also create some functions that work with your list of cards.

Start with a blank list named deck and use nested for loops to add cards to the list: one loop for the suits, and another loop for the possible card values.

Your deck list should contain string values of two characters each. This will make it easier to process the values in a consistent way.

The first character will be the value (A, 2, 3, K, Q, J, etc). Use ‘T’ to represent 10.

The second is the suit (‘S’ for spades, ‘H’ for hearts, ‘C’ for clubs, ‘D’ for diamonds).

Examples:
6 of Hearts is ‘6H’
Ace of Clubs is ‘AC’
Ten of Diamonds is ‘TD’
Jack of Spades is ‘JS’

You can test this by printing the deck at the end of your program. Does it contain all 52 cards?

Suits Dictionary

To make it easier to print the cards, setup a dictionary named suits to look up the names of the suits by their one letter codes.

When done properly, it should work like this for each suit:

print suits['H']

#OUTPUT:
Hearts

Card Values Dictionary

Create another dictionary named ranks that looks up the value of the card by its ranks. For the numbers 2 through 9, the rank can be the same as the lookup digit. For T, J, Q, K, A, you need to look up 10, Jack, Queen, King, Ace.

Card Description Function

Write a function named cardname that takes the two character format as its input parameter and returns a description of the card. It should work like this:

text = cardname('7S')
print(text)

#OUTPUT:
7 of Spades

If you prefer, you can use the symbols for the suits instead of the word names of the suits. You can print them as unicode symbols by using ‘\u’ followed by their 4 digit code, as part of a string literal. That’s a backslash, not a forward slash. Try printing any of these to see it work:

'\u2660'
'\u2663'
'\u2665'
'\u2666'

Now try printing one of those concatenated with other text:

text = 'Your card is the 3 of \u2664.'
print(text)

#OUTPUT:
Your card is the 3 of ♠.

Text Colors

You can print colored text in several different ways. Try using the Colorama module to make that work. Modify your card display functions to print the red suits in red text.

Text Art Card Images

Try creating a way to print cards in a text art format that looks more like a playing card. Make your code into a function so it will be reusable for any card.

Example Text Art:

+---+
|7♥ |
|   |
+---+

You can also get a little fancier than that if you use unicode characters to make cleaner looking borders.

Side by Side Cards

If you’re creative, you can figure out how to make each card into a list of lines of text. That makes it easier to print cards next to each other. Can you figure out how to make a function that does the following?

show_cards(['3D', 'KC', '9S'])

#OUTPUT:
+---+  +---+  +---+
|3♦ |  |K♣ |  |9♠ |
|   |  |   |  |   |
+---+  +---+  +---+

Dealing Cards

If you were to use this deck of cards in a very simple game, you’d want to be able to deal cards to players’ hands or piles on the table or something.

Create a few lists that can be used as hands or piles. Give them sensible names, like hand1 or faceup_pile1.

You could write a function that removes one card from the deck and then adds it to a pile:

def deal(destination):
    #destination is a list: could be a hand or pile
    #add the top card of the deck to the destination
    destination += [deck[0]]
    #delete that card from the deck
    del deck[0]

But actually, that’s working too hard. All lists already have a pop function that makes this faster.

The pop function removes an item from a list (you specify which item number) and returns that item. We add that return value to the hand or pile list.

Try something like this:

hand = []
hand += [deck.pop(0)]

#test to see if it worked:
print(hand)
print("Cards left in deck:", len(deck))

If that works, deal yourself a hand of seven cards.

Print those cards, but print them in a way that looks nice on the screen. (Use your cardname function.)

Now write some code that deals seven cards each to two different players, alternating players. Look at each hand to make sure the cards are alternating players – neither player should have a run of consecutive card ranks.

Shuffling

This would be more interesting if the hands were random.

Python has an easy way to randomize the order of a list. You need to import the random module at the beginning of your program for this to work. Use the random.shuffle function.

import random
deck = []
#write code to create the deck
random.shuffle(deck)

Shuffling Algorithms:

Even though Python can do this easily, you can also write your own shuffling algorithm. It’s a fun programming exercise. Here’s the basic idea:

  1. Pick two random numbers between 0 and the highest numbered item in your list.
  2. Save the first item number in a “temp” variable.
  3. Save the second item number over the first item  number in your list.
  4. Save the “temp” variable data into the first item number in your list.

That’s the algorithm for randomly switching the locations of two items in your list. Now repeat that process many times.

Another algorithm that works in Python:

  1. Pick an item number randomly.
  2. Add that item number to the end of your list.
  3. Delete the original item number.
  4. Repeat.

Card Game, Starting Simple

If you want to work toward a card game, start very simple.

Before you try to program anything related to a game, you should try to brainstorm for some reasonable goals.

What are the simplest card games you can think of?

What are some chunks that you can break those games into?

In general, here are some functions you can write that can represent a small component of a game program:

  • Deal the initial cards into the initial setup of hands or piles
  • Display the current state of the game: print each revealed card, and possibly one or more card backs to represent face-down cards or piles.
  • Given two cards as inputs, return which card has a greater rank or if they are equal in rank.
  • Ask the user what card they want to play or select, then check if that is a legal move. For example, check if that card is contained in the player’s hand.

Any time you add the slightest little feature, you should immediately test it to see if it works as expected. That might mean adding a bit of extra code that’s only used for your test.

Make up an even simpler game

Even the simplest games can be tricky to program. Why not invent something even simpler? As long as your player is making choices and the program responds according to those choices, you can loosely call your program a game. At first you don’t need to worry about things like scoring and winning. Focus on mechanics of displaying cards, dealing cards, choosing cards, etc.