Concept to Code Part 2 - Beginner's Python Card Game
Today, we’re taking a turn-based RPG and leveling it up into a strategic card game: Elemental Showdown. This game is available in two versions on the GitHub repo. We'll concentrate on the modular approach here, but you can also explore the single-file version to see the differences.
Single-file - All components in one file for simplicity.
Modular - Code split into separate files easy to upscale and expand.
While different in gameplay, both projects share core object-oriented programming principles. "Elemental Showdown" pits players against a computer opponent using elemental cards, emphasizing strategy and resource management.
Let’s define the game concept
Here's our game in a nutshell.
Theme - Elemental warfare (Fire, Water, Earth, & Air)
Mechanics - Turn-based card game
Objective - Reduce your opponent's health to zero using elemental cards
Now, let’s make sure your dev environment is as ready
Here’s your checklist:
Python version 3.6 or higher is installed (python.org is your friend).
Favorite code editor (VSCode, PyCharm, or even good ol' Notepad).
Directory Setup called
elemental_showdownand inside it, create these files:
elemental_showdown/
├── card.py
├── player.py
├── deck.py
└── game.pyWith everything set up, we’re ready to start coding.
Let’s start laying down some code
First up is the `Card` class which initializes each card with an element and a power level and provides a readable string representation for debugging. Nothing too crazy here.
class Card:
def __init__(self, element, power):
self.element = element # Store the card's elemental type
self.power = power # Store the card's power level
def __repr__(self):
# Provide a string representation of the card for debugging
return f"{self.element} Card with Power {self.power}"Next, we got the `Player` class which initializes each player with a name and health and where players draw and play cards.
class Player:
def __init__(self, name, health):
self.name = name # Store the player's name
self.health = health # Store the player's health
self.hand = [] # Initialize an empty hand to hold cards
def draw_card(self, deck):
# Add a card from the deck to the player's hand
self.hand.append(deck.draw())
def play_card(self, index):
# Remove and return a card from the player's hand at the given index
return self.hand.pop(index)
def show_hand(self):
# Display all cards in the player's hand
for index, card in enumerate(self.hand):
print(f"{index}: {card}")And now, let’s deal with the `Deck` class which is basically the card dealer. It shuffles and serves up cards.
import random
from card import Card
class Deck:
def __init__(self):
elements = ['Fire', 'Water', 'Earth', 'Air']
# Create a deck with 5 cards of each element, power levels 1-10
self.cards = [Card(element, random.randint(1, 10)) for element in elements for _ in range(5)]
def shuffle(self):
# Randomly reorder the cards in the deck
random.shuffle(self.cards)
def draw(self):
# Remove and return the top card from the deck
return self.cards.pop()Time to assemble these pieces
Here’s the basic flow of our game, starting with an introduction.
def introduction():
# Provide context and set the narrative for the game
print("Welcome to Elemental Showdown!")
print("In a world torn by elemental forces, two beings emerge as leaders of their factions.")
print("One, a Hero seeking to bring peace. The other, a Villain, driven by the chaos of power.")
print("Choose your side and battle using the elemental cards to either save or dominate the world.\n")Pick a side hero or villain and let’s slap some cards down. Here’s how damage works.
def apply_damage(player, opponent, player_card, opponent_card):
# Calculate and apply damage based on the played cards
player_damage = player_card.power
opponent_damage = opponent_card.power
# Reduce health based on the damage dealt
opponent.health -= player_damage
player.health -= opponent_damage
# Display the results of the card play
print(f"{player.name} deals {player_damage} damage to {opponent.name}.")
print(f"{opponent.name} deals {opponent_damage} damage to {player.name}.")Your card hits, their card hits, and somebody’s health bar is crying.
Wrapping it all up the main game loop. You’ll get a character, shuffle a deck, draw some cards, and keep playing until one of you hits zero health.
from player import Player
from deck import Deck
def main():
introduction()
deck = Deck()
deck.shuffle() # Randomize the order of cards in the deck
# Allow player to choose their character
print("Choose your character:")
print("1. Hero")
print("2. Villain")
choice = input("Select your character (1-2): ")
# Create player and opponent based on the choice
if choice == '1':
player = Player("Hero", 50)
opponent = Player("Villain", 50)
else:
player = Player("Villain", 50)
opponent = Player("Hero", 50)
print(f"\n{player.name} faces off against {opponent.name}!")
print("Both start with 50 health.")
# Draw initial hands for both player and opponent
for _ in range(5):
player.draw_card(deck)
opponent.draw_card(deck)
# Main game loop
while player.health > 0 and opponent.health > 0:
# Display current health status
print(f"\n{player.name} Health: {player.health}, {opponent.name} Health: {opponent.health}")
player.show_hand()
player_choice = input("Choose a card to play (type index or 'q' to quit): ")
if player_choice.lower() == 'q':
print("Thanks for playing!")
break
try:
# Play cards and apply damage
player_card = player.play_card(int(player_choice))
opponent_card = opponent.play_card(0) # Opponent plays first card
print(f"{opponent.name} plays {opponent_card}")
apply_damage(player, opponent, player_card, opponent_card)
# Check for win/lose conditions
if opponent.health <= 0:
print(f"{opponent.name} has been defeated!")
break
if player.health <= 0:
print(f"{player.name} has fallen in battle.")
break
except ValueError:
print("Please enter a valid number.")
if __name__ == "__main__":
main()And voila! You've just created "Elemental Showdown". To play, open your terminal, navigate to the elemental_showdown directory, and type:
python game.pyTest and make sure all the pieces are in place
This a beginner-friendly approach to a turn-based RPG. After fixing any pesky bugs, try adding some features to enrich the game.
💖 Keep experimenting, learning, and honing your skills. Happy coding! 💻







