Euchre Card Game Implementation

CS Fundamentals

A fully functional C++ simulation of the traditional card game Euchre, supporting both human and AI players. Designed with modular object-oriented principles, the project showcases strong software architecture, game logic implementation, and rule enforcement.

Sep 2022 - Oct 2022
Ann Arbor, MI
Lead Developer
Personal Project
1 person

Objective

To develop a scalable and testable simulation of Euchre that adheres to official rules, allows for AI-controlled players, and includes full deck management, trick handling, and scoring.

Key Achievements

  • Implemented core components: `Card`, `Pack`, `Player`, `Euchre` with encapsulated logic
  • Designed polymorphic `Player` interface to support both `Simple` and `Human` types
  • Correctly handles trump suit, left/right bower logic, and suit-following rules
  • Integrated dealer, trick resolution, and round rotation systems
  • Built-in unit-testable components for deterministic AI behaviors

Technologies Used

C++Object-Oriented ProgrammingInheritancePolymorphismOperator OverloadingVirtual FunctionsGame DevelopmentAlgorithm DesignSTLCommand-line Argument Parsing

Theory & Approach

Euchre is a trick-taking game played with a subset of cards (9 through Ace) and 4 players in two teams. The program models: - **Deck Shuffling & Dealing** - **Trump Selection and Ordering Up** - **Card Comparison and Trick Taking** - **Score Keeping and Win Conditions** Formally, determining trick winners uses comparison logic based on: - `EffectiveSuit(card, trump)`: - Right bower = Jack of trump - Left bower = Jack of same-color suit - Otherwise follow-suit rules - Winner = card with highest precedence in effective suit

Technical Deep Dive

- `Card.cpp`: Defines suit, rank, and comparison logic with special rules for left/right bower - `Pack.cpp`: Manages shuffled/unshuffled deck and card distribution - `Player.cpp`: Abstract class for polymorphism with `make_trump`, `add_card`, `play_card`, etc. - `euchre.cpp`: Main game driver handling game loop, trick rotation, score, I/O

Challenges & Solutions

## Challenge: Handling Left Bower Suit Exception The left bower acts as trump despite being in a different suit (same color). - ✅ **Solution**: Introduced `get_effective_suit()` to dynamically map suit based on rank and trump. Challenge: Ensuring Suit Following Players must follow suit if possible. Violations break game logic. - ✅ **Solution**: Added a filter in `play_card()` logic that checks valid moves from hand. ### ⚠ Challenge: Strategy for AI Trump Selection Determining whether AI should “order up” or pass. - ✅ **Solution**: Implemented `SimplePlayer` with static rule-based logic (e.g., if has ≥ 2 trump cards)..

Review

This project demonstrates object-oriented design, complex rule enforcement, and interactive command-line play. It was particularly valuable in strengthening my understanding of inheritance, encapsulation, and testing strategy in C++.

Future Improvements

- Add graphical user interface (GUI) or web frontend - Add multiplayer networking support - Improve AI player using reinforcement learning or heuristics - Add logging and statistics analysis of games

Code Snippets

bool Card_less(const Card &a, const Card &b, Suit trump) {
    Suit eff_a = get_effective_suit(a, trump);
    Suit eff_b = get_effective_suit(b, trump);
    if (eff_a != eff_b) return eff_a < eff_b;
    return a < b;
}

bool SimplePlayer::make_trump(const Card &upcard, bool is_dealer,
                               int round, Suit &order_up_suit) {
    int count = std::count_if(hand.begin(), hand.end(), 
                              [&](const Card &c) {
        return c.is_trump(upcard.get_suit());
    });
    if (count >= 2) {
        order_up_suit = upcard.get_suit();
        return true;
    }
    return false;
}