Native Windows Solitaire (Klondike) implemented with Rust and Win32 APIs via the windows crate. Ships as a single ~3.5MB EXE with embedded resources, card sprites, menus, and dialogs.
- Two Scoring Modes: Standard (with optional timed penalty) and Vegas (with cumulative bank)
- Two Victory Animations: Classic Windows XP-style cascade and Modern physics-based bounce
- Advanced Solver: K+ compressed DFS algorithm determines deal solvability in ~120ms
- Professional Graphics: WIC-based PNG decoding, double-buffered GDI rendering with alpha blending
- Full Undo/Redo: Complete game state snapshots for unlimited undo
- Settings Persistence: Window position, game options, and Vegas bank saved to Windows Registry
- Intelligent Hints: Priority-based move suggestions (Ctrl+H)
- Deterministic Replay: BCrypt-based RNG with seed storage for "Deal Again" feature
📘 Comprehensive Architecture Documentation - Complete system design, data flow diagrams, module structure, and implementation details (1,636 lines, 64KB)
Prerequisites (Windows 10/11 x64):
- Rust toolchain (stable MSVC):
rustup toolchain install stable - Visual Studio Build Tools with Windows 10/11 SDK (for
rc.exeand link libs) cargoon PATH
Build and run:
cargo build --release
target\\release\\mdsol.exe
Notes:
- Double-buffered GDI rendering is enabled. If no card PNG is embedded, a placeholder card is drawn.
- Manifest, menu, accelerators, and version info are embedded. Icon and card assets are optional and can be added later.
The repository already includes a pre-generated card sprite at res/cards.png, so builds embed the checked-in art. Run the optional xtask helper below only if you need to regenerate the sprites (for example, to use different artwork or dimensions).
Optional regeneration (requires internet):
cargo run -p xtask -- gen-cards --card-w 224 --card-h 312
This will:
- Download the deck from the
notpeter/Vector-Playing-Cardsmirror - Rasterize SVGs to the requested size
- Generate
res/cards.png(13 columns × 4 rows) - Update
res/app.rcto embed the PNG asIDB_CARDS
After that, rebuild:
cargo build --release
If you already have the SVGs locally:
cargo run -p xtask -- gen-cards --source path\to\cards-svg
The tool also writes a JSON map alongside the PNG for debugging (not used at runtime).
- Cards: Place a CC0/PD card sprite sheet PNG at
res/cards.png(e.g., Kenney playing cards). Then openres/app.rcand uncomment the line:
// IDB_CARDS RCDATA "res/cards.png"
to become
IDB_CARDS RCDATA "res/cards.png"
Rebuild to embed the PNG. The app will decode it via WIC and render a test card.
- Icon: Place a multi-size icon at
res/app.icoand add anICONentry inres/app.rcif desired.
- Byron Knoll’s “Vector Playing Cards” are Public Domain. The
notpeter/Vector-Playing-Cardsrepo indicates “Public Domain/WTFPL” for images/outputs. See upstream for details.
- Code: MIT License (see repository).
- Card art: Public Domain
- Byron Knoll’s Vector Playing Cards (mirror: notpeter/Vector-Playing-Cards)
- Kenney Playing Cards Pack (kenneyNL/playing-cards-pack)
- Tools used in asset generation (
xtask): resvg, usvg, tiny-skia (see crates.io pages for licenses).
Attribution is shown in the About dialog. If you ship different assets, ensure you comply with their licenses and update attributions accordingly.
Open File → Options… to configure:
- Draw Mode: Draw 1 or Draw 3
- Victory Animation: Classic or Modern
- Scoring: Standard or Vegas
- Timed scoring: counts down -2 points every 10 seconds (Standard only)
- Vegas cumulative: keeps Vegas balance across hands
- Highlight hint target: draws a brief gold outline on the suggested destination
Notes:
- Timed scoring starts when you make your first move and pauses when the window is minimized; it resumes when restored.
- Vegas scores show as currency (e.g., -$52); Standard scores are whole numbers (with thousands separators).
- New: F2
- Deal Again: Ctrl+N
- Undo: Ctrl+Z
- Redo: Ctrl+Y
- Hint: Ctrl+H
- Pause Timer: Ctrl+P / Esc (when no victory animation)
- Pause Timer: Ctrl+P
- M1: Skeleton app/resources (done)
- M2: Rendering path (WIC decode + back buffer)
- M3: Engine + interaction
- M4: Scoring/options/persistence
- M5: Polish/QA
We ship a simple Inno Setup script in installers/ so you can produce a Windows installer like the stock Microsoft Solitaire experience.
- Build the release binary:
cargo build --release
Note: The installer filename uses the crate version from Cargo.toml (e.g., Solitaire-1.0.7-Setup.exe) and lands in installers/.
2. Run Inno Setup's command line compiler (iscc) from the repository root:
iscc installers\Solitaire.issThe compiled installer (Solitaire-1.0.7-Setup.exe) lands in installers\. Adjust the MyAppVersion constant at the top of Solitaire.iss when you bump the crate version.
- On Windows:
cargo test(runs engine/solver tests and builds the app)cargo clippy(lint checks)cargo fmt --check(format checks)
- In CI:
- Windows tests run in
.github/workflows/windows-tests.yml - Lint checks in
.github/workflows/lint.yml - Linux checks for
xtaskrun in.github/workflows/xtask-check.yml
- Windows tests run in
- Language: Rust 2021 Edition (MSVC toolchain)
- Graphics: GDI (double-buffered), WIC (PNG decoding), AlphaBlend
- RNG: BCrypt (cryptographically secure shuffling)
- UI Framework: Native Win32 via
windows-rsv0.52 - Build System: Cargo + embed-resource (rc.exe integration)
src/
├── main.rs (~4,300 lines) - UI, rendering, Win32 integration
├── engine.rs (~1,000 lines) - Game logic, move validation, scoring
├── solver.rs (~650 lines) - K+ compressed DFS solvability checker
└── constants.rs (~56 lines) - Shared resource IDs and constants
Game Engine (engine.rs):
- 52-card deck with BCrypt-based Fisher-Yates shuffle
- Move validation for foundations (same suit, ascending) and tableaus (alternating colors, descending)
- Two scoring modes with different rules and penalties
- Win condition detection and solvability integration
Solver Algorithm (solver.rs):
- K+ compressed stock/waste representation (~10x speedup)
- Iterative-deepening DFS with transposition table (~100x speedup)
- Auto-normalization (safe foundation moves)
- 120ms time budget per solve attempt
- Returns: Winnable, Unwinnable, or Timeout
Rendering Pipeline (main.rs):
- WIC decodes embedded PNG to 32bpp PBGRA (pre-multiplied alpha)
- Double-buffered off-screen composition
- Sprite sheet: 13×4 grid (2912×1248 px, 224×312 per card)
- AlphaBlend for transparency, single BitBlt per frame
UI Interaction (main.rs):
- Hit testing with cached tableau slots for performance
- Drag-and-drop with 4px threshold
- Double-click auto-move to foundations
- Hint system with 6-level priority (reveals hidden cards first)
- Rendering: 1-2ms per frame on modern hardware, 60 FPS achievable
- Solver: <10ms (simple), 20-50ms (medium), 100-120ms (hard deals)
- Startup: 100-200ms cold start (includes WIC PNG decode)
- Memory: 15-25MB total (14MB sprite sheet, 8MB backbuffer)
For detailed architecture documentation including data flow diagrams, subsystem analysis, and development guidelines, see 2025.11.06 - Comprehensive Architecture Documentation.md.
Before making changes:
- Read CLAUDE.md for AI assistant guidance
- Review Architecture Documentation for system design
- Ensure resource IDs in
constants.rsmatchres/app.rcexactly - Run
cargo test,cargo clippy, andcargo fmtbefore committing
MIT License - see repository for details.
Card artwork is Public Domain (Byron Knoll's Vector Playing Cards).