Skip to content

franrizz15/game_oop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Merchants & Marauders Game

Overview

This is an object-oriented Python implementation of a partial version of the Merchants & Marauders board game. The game simulates the economic and combat systems of 17th-century Caribbean trading and piracy. Players take on the roles of merchant captains or pirates, managing ships, completing missions, acquiring cargo, and engaging in combat on the high seas.

Implementation Features

Core Game Systems

  • Player Management: Create and manage multiple players with unique captains, ships, and resources (gold, cargo, glory points)
  • Card Systems: Multiple card decks including captains, ships, missions, events, rumors, cargo, and glory cards
  • Game Board: Tracks players across Caribbean ports and manages game state
  • Combat System: Simulate naval combat between players with hit location mechanics and damage tracking
  • Port Actions: Players can recruit crew, claim missions, and stash gold at various Caribbean ports
  • Merchant Raiding: Non-pirate players can raid merchant ships for cargo
  • Event System: Event cards trigger special game events
  • Victory Condition: First player to acquire 10+ glory points wins

Architecture Highlights

  • Modular Design: Separate modules for cards, boards, players, game logic, and utilities
  • Type Hints: Full type annotations using Python's typing module for better code clarity and IDE support
  • Resource Management: Efficient memory usage with __slots__ and weak references
  • Immutable Constants: Centralized constant definitions (ports, merchants, nationalities, etc.)

Design Patterns Used

1. Flyweight Pattern (Game class)

The Game class implements the Flyweight pattern to ensure only one instance of each game exists per game ID. The __new__ method uses a WeakValueDictionary to store active games and return existing instances rather than creating duplicates, reducing memory overhead when managing multiple concurrent games.

__active_games: ClassVar[WeakValueDictionary[str, Game]] = WeakValueDictionary()

2. Factory Pattern (CardFactory class)

The CardFactory generic class creates and manages shuffled decks of cards. Rather than modifying constant card definitions directly, it creates independent instances for each game, allowing modifications without affecting the original card sets.

3. Observer Pattern (EventNotification class)

The EventNotification class implements the Observer pattern, allowing different components (e.g., the game board) to subscribe to and receive notifications about game events. Currently used for:

  • glory_acquired: Triggered when a player earns glory points
  • combat_declared: Triggered when a player initiates combat with another

4. State Pattern (GameState protocol and state classes)

Game behavior changes based on state (e.g., ActiveState, CombatState, EndGameState). Different states implement different behaviors for actions like creating players, drawing cards, and starting combat. This allows the game flow to be managed cleanly without extensive conditional logic.

5. Façade Pattern (Player class)

The Player class acts as a façade, providing a simplified interface to the more complex PlayerBoard. It abstracts away the implementation details of the player board while exposing only the essential player actions and attributes.

Project Structure

game_oop/
├── __init__.py              # Package initialization
├── game.py                  # Main Game class with Flyweight and State pattern
├── cards.py                 # Card classes and CardFactory (Factory pattern)
├── boards.py                # GameBoard and PlayerBoard classes
├── user.py                  # Player class (Façade pattern)
├── utils.py                 # Constants, types, and EventNotification (Observer pattern)
├── pyproject.toml           # Project configuration
└── README.md                # This file

File Descriptions

File Purpose
game.py Core game logic, game state management, and card deck handling
cards.py Card type definitions and the CardFactory for deck creation
boards.py PlayerBoard class for tracking individual player state and GameBoard for global game tracking
user.py Player class managing player actions, movement, and interactions
utils.py Type aliases, constants, and the EventNotification observer implementation

Key Classes

Game

  • Pattern: Flyweight
  • Purpose: Manages overall game state, card decks, players, and game events
  • Responsibilities: Create/manage games by ID, handle state transitions, manage event subscriptions

Player

  • Pattern: Façade
  • Purpose: Simplified interface for player actions and data
  • Responsibilities: Manage player attributes (crew, gold, state), execute port actions, manage combat

PlayerBoard

  • Purpose: Detailed tracking of individual player state
  • Responsibilities: Track captain, ship, cargo, bounties, hit locations, missions, glory points

GameBoard

  • Purpose: Global game state tracker
  • Responsibilities: Track active players, port occupation, merchant locations, monitor victory condition

CardFactory

  • Pattern: Factory
  • Purpose: Create shuffled, independent card decks
  • Responsibilities: Draw cards from deck, maintain deck integrity

EventNotification

  • Pattern: Observer
  • Purpose: Event publishing and subscription system
  • Responsibilities: Subscribe to events, publish events, notify subscribers

Design Principles Applied

  • Single Responsibility Principle: Each class has a focused purpose
  • Dependency Injection: Game instance passed to components that need it
  • Encapsulation: Private attributes with property accessors
  • DRY (Don't Repeat Yourself): Shared constants and factory methods
  • Type Safety: Full type annotations throughout codebase

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages