overview

A two-player strategy card game inspired by Queen's Blood from Final Fantasy VII Rebirth. Players compete for territorial control across a 3×5 board, placing cards from their own decks onto cells that they own via pawns. Each card spreads influence to adjacent territories based on its unique mini-grid pattern. Victory goes to whoever controls the most valuable rows when the board fills or both players consecutively pass which creates a delicate balance of expansion, defense, and resource management.

play the game

PINK: 0 TEAL: 0
PINK's Turn
◆ Pink's Hand
◆ Teal's Hand

how to play

goal: A player wins rows by having the higher card value than their opponent. Your total score is the sum of your values, but only in rows that you're winning.
pawns & ownership: Each cell shows how many pawns exist. Pink starts with pawns on the left column, Teal on the right. You can only place cards on cells you own by existence of pawns on those cells.
card cost: Each card has a cost ranging from 1 - 3. You need at least that many pawns on a cell to place the card there.
influence spread: When you place a card, a mini-grid spreads influence based on its pattern. Hovering over cards in the player's deck will show the influence grid: purple squares show where new pawns will appear.
capturing territory: If your influence reaches an opponent's cell (without a card), you take ownership. Cells with cards are locked and cannot be overwritten.
game ending: The game ends when the board is full OR both players pass consecutively.

card gallery

Each card has unique stats and influence patterns. Cost determines where it can be placed, value contributes to row totals, and the influence grid shapes your territorial expansion.

Goblin (Cost 1, Value 1): Minimal influence. Cheap blocker.
Archer (Cost 1, Value 2): Horizontal spread for reaching across lanes.
Miner (Cost 1, Value 2): Diagonal sneaker for unexpected spots.
Knight (Cost 1, Value 3): Classic vertical influence.
Healer (Cost 1, Value 3): Wide horizontal spread.
Pekka (Cost 1, Value 4): X-pattern influence.
Valkyrie (Cost 2, Value 4): Corner specialist.
Barbarian (Cost 2, Value 5): Cross pattern.
Wizard (Cost 2, Value 5): Long vertical reach.
Prince (Cost 2, Value 5): Mixed pattern.
Witch (Cost 2, Value 6): Extended vertical.
Golem (Cost 3, Value 6): Compact but strong.
Giant (Cost 3, Value 7): Massive cross pattern.
Musketeer (Cost 2, Value 8): Checkerboard pattern.
Dragon (Cost 3, Value 10): Full 5×5 influence, the ultimate card.

construction

Java Swing MVC JUnit Strategy Pattern

The original implementation for this Sanguine Game is built in Java following strict Model-View-Controller architecture. The model manages all game state and rules, views render the board (both text-based and Swing GUI), and controllers handle player input through a listener-based event system.

mvc architecture: Complete separation between game logic (BasicSanguine model), display (SwingSanguineView, TextBoardView), and input handling (SanguineController).
listener pattern: The model notifies observers via ModelStatusListener and PlayerActionListener interfaces, enabling loose coupling between components.
strategy pattern: AI opponents implement SanguineStrategy interface. Multiple strategies available: FillFirst (greedy), MaximizeRowScore (tactical), Minimax (optimal), and composite FallbackStrategy.
influence system: Cards define 5×5 influence grids where 'I' marks pawn placement, 'C' is center, and 'X' is empty. Teal's grid is mirrored horizontally for symmetric gameplay.
comprehensive testing: JUnit test suites verify model behavior, strategy correctness, and edge cases, while mock objects validate controller interactions.

architecture

Model Listeners Controller View

The game uses an event-driven architecture where the model broadcasts state changes to registered listeners. The controller implements both ModelStatusListener (for turn changes and game-over events) and PlayerActionListener (for card placement and passing). Views subscribe to updates and re-render accordingly.

Player abstraction supports both HumanPlayer (awaits GUI input) and MachinePlayer (computes moves via strategy). This enables human vs human, human vs AI, and AI vs AI game modes with identical underlying logic.

Source? This project was built as part of Northeastern's Object-Oriented Design course (CS 3500), with the full Java implementation demonstrating advanced OOD principles including interface segregation, composition over inheritance, and design patterns in practice.