4
\$\begingroup\$

After finishing up finals, I wasn't really working on coding for a while. I decided to write a card game to get back into the programming scene. I'm just wondering if there's anything that I missed or could be improved upon.

import random

suit_choices = ("Diamonds", "Hearts", "Clubs", "Spades")
suit_picked = random.choice(suit_choices)

number_picked = random.randint(2,9)

while True:
    print suit_choices
    user_card = raw_input('\nEnter a suit to pick from. Your choices are listed above. ').title()

    if user_card == suit_picked:
        print '\nYou guessed the suit type correct!'
        user_number = input('\nNow pick a number card (2-9) ')
        if user_number == number_picked:
            print '\n You guessed the card number correct!'
            break
        else:
            print '\nShucks. Try again.'
            continue
    else:
        print '\nOH NO'
        continue
\$\endgroup\$
  • 1
    \$\begingroup\$ correct -> correctly \$\endgroup\$ – Ray Jun 7 '14 at 5:26
2
\$\begingroup\$

There are a couple of things I'd say you're currently missing:

  1. A way to quit;
  2. Input validation; and
  3. Scoring.

At the moment, your while True will run forever. It is not unreasonable to think that a user might eventually get bored! Therefore you could add something like:

if raw_input("Play again (y/n)? ").lower() == "n":
    break

To the end of the main loop.


Your game will fall over if the user enters something for the "card number" that can't be evaluated. Also, they can enter something that isn't a suit. As @otus points out, you shouldn't use input; I would suggest you add more validation. This SO community wiki will be useful to you, you should end up with something like

user_card = get_str_input('\nEnter a suit to pick from. Your choices are listed above. ',
                          suit_choices)
...
user_number = get_int_input('\nNow pick a number card (2-9) ', 2, 9)

Where those functions only ever return valid input and catch any associated errors.


You're making a game; why not tell the player how they're doing? The simplest way would be something like:

right = wrong = 0

then += 1 to the appropriate value each time through the loop. After they quit, show something like:

print "You got {0} right and {0} wrong".format(right, wrong)
if right > wrong + 2:
    print "Well done!"
elif right > wrong - 2:
    print "Not bad"
else:
    print "Bad luck"

Also, card games lend themselves very well to OOP; you could have Card, Deck and Game classes, for example:

class Game(object):

    def __init__(self, suits=None, faces=None):
        if suits is None:
            suits = ("Diamonds", "Hearts", "Clubs", "Spades")
        if faces is None:
            faces = range(2, 10)
        self.suits, self.faces = suits, faces
        self.deck = Deck(self.suits, self.faces)
        self.deck.shuffle()
        self.score = {'right': 0, 'wrong': 0}

    def main_menu():
        ...

    def _input_suit(self):
        ...

    def _input_face(self):
        ...

    ...
\$\endgroup\$
  • \$\begingroup\$ Re: OOP, I think it's also important to know when not to use OOP. If the idea here is to learn/refresh Python/programming knowledge, then sure, a class for cards is fine. If this was a practical application, though, OOP would be sort of overkill when the only operations needed are an initializer and equals. \$\endgroup\$ – otus Jun 7 '14 at 17:27
  • 1
    \$\begingroup\$ @otus I agree, I was going from the OP's comment on trying "to get back into the programming scene". This particular game is easily achieved without OOP, but OOP could help abstract to a whole pack (sorry) of card games. \$\endgroup\$ – jonrsharpe Jun 7 '14 at 17:55
5
\$\begingroup\$
        continue

Both your continue statements fall back to the end of the loop anyway, so they are redundant.


    user_number = input('\nNow pick a number card (2-9) ')

In the other place you correctly used raw_input. The difference is that input executes the given string as an expression, which is seldom what you want (and usually unsafe).


Nothing else really. The \ns at the start of all your strings are a bit ugly, and some people prefer using empty print statements to indicate extra empty lines.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.