Skip to content

Repository files navigation

xMahjong

A Tux-themed Mahjong solitaire game for Linux, windows & MacOS built with Rust and SDL2.

About

xMahjong is a classic tile-matching solitaire game featuring Tux penguin-themed graphics. Clear all 144 tiles from the board by matching pairs of free tiles. The game uses the traditional Turtle layout with 5 stacked layers, and every generated board is guaranteed to be solvable.

v0.1.5

Example

Initial board

Features

  • 1000 Levels across 5 phases (Penguin, Dog, Space, Endgame, and Grandmaster Mixed)
  • Modern top status bar (HUD) featuring brand logo, phase indicator, stat pills with custom pixel-art icons, and top-right audio mute button:
    • 🀄 Brand & Phase: xMahjong logo and current level phase badge
    • 🏆 Score: Live score with golden trophy icon
    • ❤️ Lives: Available lives (shuffles) with red heart icon
    • 💡 Hints: Hints counter with glowing yellow lightbulb icon
    • 🀄 Tiles Count: Live countdown of remaining / total tiles (e.g. 120/120 counting down)
    • ⏱️ Timer: Elapsed game timer with clock icon
    • 🔊 / 🔇 Mute Button: One-click audio mute toggle in the top-right corner
  • 12 Supported Languages with full localized UI across all dialogs, HUD, trophies, and menus:
    • 🇬🇧 English (EN)
    • 🇪🇸 Spanish (ES / Español)
    • 🇫🇷 French (FR / Français)
    • 🇩🇪 German (DE / Deutsch)
    • 🇮🇹 Italian (IT / Italiano)
    • 🇧🇷 Portuguese (PT / Português do Brasil)
    • 🇳🇱 Dutch (NL / Nederlands)
    • 🇵🇱 Polish (PL / Polski)
    • 🇹🇷 Turkish (TR / Türkçe)
    • 🇮🇳 Tamil (TA / தமிழ்)
    • 🇯🇵 Japanese (JA / 日本語)
    • 🇨🇳 Chinese (ZH / 简体中文)
  • Dynamic Language Switcher in the Pause Menu (Esc / Ctrl+P) with automatic system locale detection and persistent preference saving
  • Level Select screen to browse, choose, and replay any completed or unlocked level
  • 4 rich tile theme packs: Tux Penguins, Puppies, Space, and Ocean (200 unique tile face graphics)
  • Classic Turtle layout with 144 tiles across 5 layers
  • Guaranteed solvable boards via reverse-deal generation
  • Hint system, undo (up to 10 moves), and progressive lives / shuffle system
  • Timer and scoring system with local leaderboard (top 10)
  • Keyboard shortcuts for all actions
  • Crisp audio sound effects with mute support (tile selection click, deselection, electric lightning zap pair match, error buzz, victory fanfare, shuffle roll)
  • Resizable window (min 800×600, adapts to screen resolution)
  • Native Linux packages (.deb, .rpm, AppImage), Windows installers (portable, MSI, MSIX), and macOS builds
  • Daily new free Life / Shuffle +1

Game Over - Shuffle

Supported Languages (i18n)

xMahjong provides comprehensive multi-language support (12 languages):

Code Language Native Name Region
EN English English Default / Global
ES Spanish Español Spain / Latin America
FR French Français France / Francophone
DE German Deutsch Germany / Austria / Switzerland
IT Italian Italiano Italy
PT Portuguese Português Brazil (pt-BR)
NL Dutch Nederlands Netherlands / Belgium
PL Polish Polski Poland
TR Turkish Türkçe Turkey
TA Tamil தமிழ் India / Sri Lanka / Singapore
JA Japanese 日本語 Japan
ZH Chinese 简体中文 Simplified Chinese

Language can be switched at any time from the in-game Pause Menu (Esc or Ctrl+P -> LANGUAGE: <CODE>) or will automatically follow your operating system locale.

Prerequisites

System Dependencies

You need SDL2 development libraries installed:

Ubuntu / Debian:

sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev pkg-config

Fedora:

sudo dnf install SDL2-devel SDL2_image-devel SDL2_mixer-devel SDL2_ttf-devel pkg-config

Arch Linux:

sudo pacman -S sdl2 sdl2_image sdl2_mixer sdl2_ttf pkg-config

Rust Toolchain

Install Rust via rustup:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Building

# Debug build
cargo build

# Release build (optimized)
cargo build --release

macOS (requires Homebrew SDL2 libraries):

brew install sdl2 sdl2_image sdl2_mixer sdl2_ttf pkg-config
LIBRARY_PATH="/opt/homebrew/lib" cargo build --release

The binary is output to target/debug/xmahjong or target/release/xmahjong.

Running

# Run directly
cargo run

# Or run the release binary
cargo run --release

Running Tests

# Run all tests (unit + property-based)
cargo test

# Run only unit tests
cargo test --lib

# Run a specific property test file
cargo test --test board_properties

# Run tests with output shown
cargo test -- --nocapture

The project includes 19 property-based tests using proptest that validate correctness properties like board generation invariants, solvability, matching logic, undo/redo behavior, shuffle guarantees, and layout scaling.

Controls

Shortcut Action
Left click Select tile
Ctrl+S Save game
Ctrl+Q Save + Quit
Ctrl+N New Game
Ctrl+R Resume
Ctrl+P Pause
Ctrl+M Toggle Mute
Shift+S Shuffle
Shift+U Undo
Shift+H Hint
Escape Pause / Resume (toggle)

Scoring

Score starts at 0 and increases with each pair matched:

  • Base: +10 points per pair removed
  • Streak bonus: +2 per pair (rewards continuous play)
  • Penalties: −5 per hint used, −10 per shuffle used
  • Time bonus (at game end): max(0, 500 − elapsed_seconds)

Top 10 scores are saved to a local leaderboard.

Shuffle System

Shuffles rearrange the remaining tiles on the board when no moves are available (or strategically when desired). The shuffle economy is progressive:

  • Starting shuffles: Each new game begins with 1 shuffle
  • Level completion bonus: +1 shuffle awarded for each level completed (carried across levels)
  • Daily bonus: +1 shuffle granted once per day when the game is launched
  • Total potential: Accumulate shuffles across levels (1 starting + 1 per completed level), plus daily bonuses earned
  • Wait for Shuffle: If you run out of shuffles and moves mid-run, you can choose "Wait for Shuffle" instead of starting over. This saves your game and exits. The next day when you launch the game, the daily bonus gives you a new shuffle so you can continue where you left off.

Shuffle state persists across sessions via shuffles.json in the data storage directory.

Difficulty

The game offers two difficulty levels that affect how shuffles behave:

  • Easy (default): Shuffles are guaranteed to produce a playable board state. The game uses smart placement to ensure free tiles always have valid matching pairs after a shuffle. You will never get stuck due to a bad shuffle.
  • Normal: Shuffles randomly redistribute face IDs across the remaining tiles without any solvability guarantee. You may end up with no valid moves after a shuffle and need to use another shuffle to continue.

Switching Difficulty

Difficulty can be changed at any time from the pause menu (ESC → navigate to "DIFFICULTY" → press Enter or click). Mid-game you can pause, switch from EASY to NORMAL (or vice versa), resume, and keep playing. The shuffle behavior changes immediately — if you switch to NORMAL and use a shuffle on the current level, it will already be the random (non-guaranteed) shuffle. When you advance to the next level, the game uses whichever difficulty you last set.

Difficulty is saved with the game state and displayed on the leaderboard.

Level Select & Replaying Levels

You can replay any level you have already completed (or currently unlocked):

  1. Press Escape or click the MENU button in-game to open the Pause Menu.
  2. Select LEVELS (using arrows + Enter, or mouse click).
  3. Browse the 1000-level catalog with phase jump tabs (PENGUIN, DOG, SPACE, ENDGAME, GRANDMASTER) or page through using < PREV / NEXT > (or PgUp / PgDn).
  4. Select any completed or unlocked level to start playing immediately. Completed levels are saved to progress.json per user profile.

Trophies & Stats

View your career achievements, consistency streaks, and clean-clearance records:

  • Career Overview: Tracks highest completed level out of 1000 and total career points accumulated across runs.
  • Daily Consistency Streaks: Displays your current active day streak and all-time best streak record with daily launch gift bonuses.
  • Mastery & Clean Clearances: Counts the total number of levels cleared with No Hints (💡), No Undos (↩️), and No Lives/Shuffles Used (❤️).
  • Save Stats Image: Click the SAVE STATS IMAGE button to export a high-resolution screenshot of your trophy dashboard to disk (trophies_stats_<timestamp>.bmp) and immediately open it for convenient sharing online.
  • Close: Click CLOSE or press Escape / Enter to exit and return directly to the menu screen.
  • Access via the ACHIEVEMENTS option in the Pause Menu or from the Game Won / Game Over summary screens.

Packaging (.deb, .rpm, AppImage)

A packaging script is included to create distribution packages:

# Build all three formats
./package.sh all

# Or build individually
./package.sh deb
./package.sh rpm
./package.sh appimage

Output goes to target/package/.

Prerequisites for packaging

Format Tool needed Install with
.deb dpkg-deb Pre-installed on Debian/Ubuntu
.rpm rpmbuild sudo dnf install rpm-build
AppImage wget Pre-installed on most distros (downloads appimagetool automatically)

Installing the packages

.deb (Ubuntu/Debian):

sudo apt install ./target/package/xmahjong_0.1.0_amd64.deb

This automatically installs SDL2 runtime dependencies via apt.

.rpm (Fedora/RHEL):

sudo dnf install ./target/package/xmahjong-0.1.0-1.x86_64.rpm

This automatically installs SDL2 runtime dependencies via dnf.

AppImage (any distro):

chmod +x target/package/xmahjong-0.1.0-x86_64.AppImage
./target/package/xmahjong-0.1.0-x86_64.AppImage

AppImages bundle SDL2 libraries inside, so no system dependencies are needed.

macOS (.app bundle):

cp -R xMahjong-0.1.0-aarch64.app /Applications/
open /Applications/xMahjong-0.1.0-aarch64.app

Copy the .app to your Applications folder and launch it. The app bundle includes all SDL2 libraries — no Homebrew or other dependencies required.

macOS (.dmg disk image):

open xMahjong-0.1.0-arm64.dmg

Double-click the .dmg to mount it, then drag xMahjong.app into the Applications folder. No additional dependencies are needed.

macOS Gatekeeper notice: Since the app is ad-hoc signed (not notarized with Apple), macOS may block it with a "cannot verify" warning. To allow it to run, remove the quarantine attribute:

xattr -cr /Applications/xMahjong.app

Assets

Tux Penguin Sprite Sheet Puppy Sprite Sheet Space Sprite Sheet

Data Storage & Player Profiles

xmahjong features full multi-user profile management. When starting the game (or choosing SWITCH USER from the Pause Menu):

  • Existing Player Selection: All existing saved player profiles are automatically detected and displayed in a clean visual selection menu showing in-progress save status (RESUME LVL X), level completion progress (LVL X/1000), and daily streaks (STRK:X).
  • Quick 1-Click / 1-Key Play: Simply click on any player card or press Enter on a highlighted player to jump straight into their game.
  • New Player Creation: Easily create a new player profile by typing a name into the "New Player" input field and clicking START or pressing Enter.
  • Pagination Support: Browse across multiple profile pages seamlessly using < PREV / NEXT > buttons or Arrow keys / PageUp / PageDown.

All settings, levels, progress, trophies, and saved games are stored within platform-specific user directories:

Platform Path
Linux ~/.local/share/xmahjong/<user_name>/
macOS ~/Library/Application Support/xmahjong/<user_name>/
Windows %APPDATA%\xmahjong\<user_name>\ (e.g. C:\Users\<user>\AppData\Roaming\xmahjong\<user_name>\)

Files (per username folder)

File Description
leaderboard.json Top 10 scores with player name, score, time, hints used, shuffles used, undos used, and date
settings.json Persistent settings (muted state)
savegame.json In-progress game state for resuming later (deleted after loading)
progress.json Persistent level completion and unlocked level tracking
shuffles.json Shuffle state: tracks last daily bonus date for the +1 daily shuffle reward
trophies.json Persistent trophy achievement progress

Menu & Dialogs

  • Pause menu (render_menu) — ✅ Has keyboard nav & Switch User option
  • Victory (render_victory) — ✅ Has keyboard nav
  • Leaderboard (render_leaderboard) — ✅ Has Enter/Escape support
  • Shortcuts (render_shortcuts) — ✅ Has Enter/Escape support
  • No Moves (render_no_moves) — ✅ Has Shuffle + New Game buttons
  • Game Over (render_game_over) — ✅ Has Save Score + New Game buttons
  • Quit Confirmation (render_quit_confirmation) — ✅ Has Yes/No buttons
  • Player Selection / Name Entry (render_name_entry) — ✅ Existing player list, badges, pagination & new player creation

Graphify

  • Manually Update .gitignore
add graphify-out/cache

Windows

  • PS> winget install astral-sh.uv
  • PS> uv tool install graphifyy
  • PS> graphify install --platform antigravity / kiro
  • PS> graphify hook install

Linux

  • $ sudo snap install astral-uv --classic
  • $ uv tool install graphifyy
  • $ graphify install --platform antigravity / kiro
  • $ graphify hook install

License

This project is licensed under the GNU General Public License v3.0.

About

XMahjong is a classic tile-matching solitaire game featuring Tux penguin-themed graphics. Clear all 144 tiles from the board by matching pairs of free tiles. The game uses the traditional Turtle layout with 5 stacked layers, and every generated board is guaranteed to be solvable.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages