Editor

Higher or Lower Card Game in Python

Beginner · Games · about 40 minutes to build · 92 lines

A card is turned over from a shuffled deck, and you guess whether the next one is higher or lower to build the longest streak you can.

The program

Press Run and answer its questions in the box that appears under the code.

higher_or_lower.py
"""Higher or lower: guess whether the next card is higher or lower and build a streak."""
import random
# Ranks from lowest to highest: aces are high.
RANKS = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
SUITS = ["spades", "hearts", "diamonds", "clubs"]
def new_deck():
"""Return a shuffled deck of 52 cards as (rank, suit) pairs."""
deck = [(rank, suit) for suit in SUITS for rank in RANKS]
random.shuffle(deck)
return deck
def card_name(card):
"""Turn ("Q", "hearts") into "Q of hearts"."""
rank, suit = card
return f"{rank} of {suit}"
def card_value(card):
"""Return a number for comparing cards: 2 is lowest, the ace highest."""
return RANKS.index(card[0])
def ask_guess(card):
"""Ask until the player types h or l, and return it."""
while True:
answer = input(f"Higher or lower than {card_name(card)}? (h/l): ").strip().lower()
if answer in ("h", "higher", "l", "lower"):
return answer[0]
print(" Please type h for higher or l for lower.")
def play_round():
"""Play until a wrong guess or the end of the deck, and return the streak."""
deck = new_deck()
current = deck.pop()
streak = 0
print(f"The first card is {card_name(current)}.")
while deck:
guess = ask_guess(current)
drawn = deck.pop()
print(f" Next card: {card_name(drawn)}.", end=" ")
if card_value(drawn) == card_value(current):
print("Same rank, so it doesn't count either way.")
elif (card_value(drawn) > card_value(current)) == (guess == "h"):
streak += 1
print(f"Right. Streak: {streak}")
else:
print(f"Wrong. Your streak ends at {streak}.")
return streak
current = drawn
print(f"You reached the end of the deck. Final streak: {streak}")
return streak
def ask_yes_no(prompt):
"""Ask a yes/no question and return True for yes."""
while True:
answer = input(prompt).strip().lower()
if answer in ("y", "yes"):
return True
if answer in ("n", "no"):
return False
print(" Please type y or n.")
def main():
"""Play rounds until the player stops, keeping the best streak."""
print("=== Higher or Lower ===")
print("Aces are high. Every right guess adds one to your streak.\n")
best = 0
while True:
streak = play_round()
if streak > best:
best = streak
print(f"That's your best streak so far: {best}")
print()
if not ask_yes_no("Play again? (y/n) "):
break
print()
print(f"Your best streak was {best}. Thanks for playing.")
if __name__ == "__main__":
main()

Open it in the full editor to save it, share it and keep building.

Sample run

What the program printed, and what was typed (in yellow).

=== Higher or Lower ===
Aces are high. Every right guess adds one to your streak.

The first card is 9 of hearts.
Higher or lower than 9 of hearts? (h/l): h
  Next card: J of spades. Right. Streak: 1
Higher or lower than J of spades? (h/l): x
  Please type h for higher or l for lower.
Higher or lower than J of spades? (h/l): h
  Next card: A of hearts. Right. Streak: 2
Higher or lower than A of hearts? (h/l): l
  Next card: 4 of clubs. Right. Streak: 3
Higher or lower than 4 of clubs? (h/l): h
  Next card: 5 of spades. Right. Streak: 4
Higher or lower than 5 of spades? (h/l): higher
  Next card: 6 of spades. Right. Streak: 5
Higher or lower than 6 of spades? (h/l): h
  Next card: 10 of diamonds. Right. Streak: 6
Higher or lower than 10 of diamonds? (h/l): l
  Next card: 8 of spades. Right. Streak: 7
Higher or lower than 8 of spades? (h/l): l
  Next card: Q of hearts. Wrong. Your streak ends at 7.
That's your best streak so far: 7

Play again? (y/n) n
Your best streak was 7. Thanks for playing.

How it is built

1. Ranks in order

The ranks are listed from lowest to highest, so a card's position in RANKS is its value. Moving "A" to the front would make aces low.

RANKS = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]
SUITS = ["spades", "hearts", "diamonds", "clubs"]

2. Building and shuffling the deck

A list comprehension makes all 52 (rank, suit) pairs and random.shuffle mixes them in place. deck.pop() then turns over the next card.

def new_deck():
    """Return a shuffled deck of 52 cards as (rank, suit) pairs."""
    deck = [(rank, suit) for suit in SUITS for rank in RANKS]
    random.shuffle(deck)
    return deck

3. Comparing two cards

RANKS.index(card[0]) gives 0 for a 2 and 12 for an ace. Suits do not matter in this game, so two cards of the same rank are equal.

def card_value(card):
    """Return a number for comparing cards: 2 is lowest, the ace highest."""
    return RANKS.index(card[0])

4. One round

The line (card_value(drawn) > card_value(current)) == (guess == "h") compares two booleans: the guess is right when both are True or both are False. A card of the same rank neither adds to the streak nor ends it.

def play_round():
    """Play until a wrong guess or the end of the deck, and return the streak."""
    deck = new_deck()
    current = deck.pop()
    streak = 0
    print(f"The first card is {card_name(current)}.")

    while deck:
        guess = ask_guess(current)
        drawn = deck.pop()
        print(f"  Next card: {card_name(drawn)}.", end=" ")

        if card_value(drawn) == card_value(current):
            print("Same rank, so it doesn't count either way.")
        elif (card_value(drawn) > card_value(current)) == (guess == "h"):
            streak += 1
            print(f"Right. Streak: {streak}")
        else:
            print(f"Wrong. Your streak ends at {streak}.")
            return streak
        current = drawn

    print(f"You reached the end of the deck. Final streak: {streak}")
    return streak

5. The best streak

main() keeps the longest streak in best and reports it when the player stops.

def main():
    """Play rounds until the player stops, keeping the best streak."""
    print("=== Higher or Lower ===")
    print("Aces are high. Every right guess adds one to your streak.\n")
    best = 0
    while True:
        streak = play_round()
        if streak > best:
            best = streak
            print(f"That's your best streak so far: {best}")
        print()
        if not ask_yes_no("Play again? (y/n) "):
            break
        print()
    print(f"Your best streak was {best}. Thanks for playing.")

Make it bigger

  • Show how many higher and lower cards are left in the deck, so the player can play the odds.
  • Give the player three lives instead of ending the round on the first wrong guess.
  • Add points: double them on every right guess and let the player stop and keep them at any time.
  • Save the best streak to a file so it carries over to the next time you play.

What it practises