belote-cli 0.9.9__tar.gz → 2.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {belote_cli-0.9.9 → belote_cli-2.5.2}/.claude/settings.local.json +3 -1
- belote_cli-2.5.2/CHANGELOG.md +394 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/DEVELOPMENT.md +38 -10
- {belote_cli-0.9.9 → belote_cli-2.5.2}/PKG-INFO +95 -16
- {belote_cli-0.9.9 → belote_cli-2.5.2}/README.md +94 -15
- {belote_cli-0.9.9 → belote_cli-2.5.2}/pyproject.toml +2 -1
- belote_cli-2.5.2/scripts/benchmark.py +188 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/__init__.py +1 -1
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ai.py +134 -70
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ansi.py +5 -4
- belote_cli-2.5.2/src/belote/belatro/core/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/core/economy.py +35 -0
- belote_cli-2.5.2/src/belote/belatro/core/run_state.py +93 -0
- belote_cli-2.5.2/src/belote/belatro/core/scoring.py +139 -0
- belote_cli-2.5.2/src/belote/belatro/engine/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/engine/event_bus.py +72 -0
- belote_cli-2.5.2/src/belote/belatro/engine/modifier_patch.py +71 -0
- belote_cli-2.5.2/src/belote/belatro/engine/round_driver.py +234 -0
- belote_cli-2.5.2/src/belote/belatro/items/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/items/base.py +95 -0
- belote_cli-2.5.2/src/belote/belatro/items/jokers/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/items/jokers/contract.py +136 -0
- belote_cli-2.5.2/src/belote/belatro/items/jokers/corrupted.py +65 -0
- belote_cli-2.5.2/src/belote/belatro/items/jokers/economy.py +52 -0
- belote_cli-2.5.2/src/belote/belatro/items/jokers/hand_comp.py +103 -0
- belote_cli-2.5.2/src/belote/belatro/items/jokers/trick_timing.py +79 -0
- belote_cli-2.5.2/src/belote/belatro/items/partner_jokers/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/items/partner_jokers/passive.py +56 -0
- belote_cli-2.5.2/src/belote/belatro/items/partner_jokers/risky.py +82 -0
- belote_cli-2.5.2/src/belote/belatro/items/partner_jokers/shaper.py +65 -0
- belote_cli-2.5.2/src/belote/belatro/items/planets.py +165 -0
- belote_cli-2.5.2/src/belote/belatro/items/registry.py +91 -0
- belote_cli-2.5.2/src/belote/belatro/items/tarots.py +117 -0
- belote_cli-2.5.2/src/belote/belatro/items/vouchers.py +102 -0
- belote_cli-2.5.2/src/belote/belatro/main.py +241 -0
- belote_cli-2.5.2/src/belote/belatro/partner/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/partner/partner_state.py +28 -0
- belote_cli-2.5.2/src/belote/belatro/partner/personality.py +127 -0
- belote_cli-2.5.2/src/belote/belatro/partner/trust.py +70 -0
- belote_cli-2.5.2/src/belote/belatro/progression/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/progression/save.py +80 -0
- belote_cli-2.5.2/src/belote/belatro/progression/unlocks.py +78 -0
- belote_cli-2.5.2/src/belote/belatro/run/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/run/ante.py +39 -0
- belote_cli-2.5.2/src/belote/belatro/run/boss.py +217 -0
- belote_cli-2.5.2/src/belote/belatro/run/decks.py +126 -0
- belote_cli-2.5.2/src/belote/belatro/run/shop.py +109 -0
- belote_cli-2.5.2/src/belote/belatro/ui/__init__.py +0 -0
- belote_cli-2.5.2/src/belote/belatro/ui/announce.py +77 -0
- belote_cli-2.5.2/src/belote/belatro/ui/collection.py +142 -0
- belote_cli-2.5.2/src/belote/belatro/ui/hud.py +64 -0
- belote_cli-2.5.2/src/belote/belatro/ui/menu.py +184 -0
- belote_cli-2.5.2/src/belote/belatro/ui/rules.py +233 -0
- belote_cli-2.5.2/src/belote/belatro/ui/shop.py +149 -0
- belote_cli-2.5.2/src/belote/belatro/ui/trust_bar.py +36 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/config.py +12 -8
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/context.py +2 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/deck.py +7 -9
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/game.py +315 -80
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/gameflow.py +92 -44
- belote_cli-2.5.2/src/belote/input.py +207 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/main.py +66 -31
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/rules.py +29 -25
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/scoring.py +282 -101
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/stats.py +42 -15
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/themes.py +19 -3
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ui/announce.py +38 -12
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ui/menu.py +52 -39
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ui/prompts.py +49 -31
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ui/render.py +114 -65
- belote_cli-2.5.2/tests/__init__.py +0 -0
- belote_cli-2.5.2/tests/belatro/__init__.py +0 -0
- belote_cli-2.5.2/tests/belatro/test_belatro.py +1699 -0
- belote_cli-2.5.2/tests/belatro/test_boss_modifiers_integration.py +87 -0
- belote_cli-2.5.2/tests/belatro/test_collection_logic.py +38 -0
- belote_cli-2.5.2/tests/belatro/test_deck_variants.py +84 -0
- belote_cli-2.5.2/tests/belatro/test_partner_trust.py +104 -0
- belote_cli-2.5.2/tests/belatro/test_progression.py +34 -0
- belote_cli-2.5.2/tests/belatro/test_round_driver.py +141 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/tests/test_ai.py +15 -18
- {belote_cli-0.9.9 → belote_cli-2.5.2}/tests/test_belote.py +206 -106
- belote_cli-2.5.2/tests/test_extended.py +119 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/tests/test_game_logic.py +14 -16
- {belote_cli-0.9.9 → belote_cli-2.5.2}/tests/test_gameflow.py +32 -30
- {belote_cli-0.9.9 → belote_cli-2.5.2}/tests/test_new_coverage.py +50 -53
- belote_cli-2.5.2/tests/test_official_rules.py +269 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/tests/test_properties.py +10 -6
- belote_cli-0.9.9/CHANGELOG.md +0 -203
- belote_cli-0.9.9/scripts/benchmark.py +0 -74
- belote_cli-0.9.9/src/belote/input.py +0 -223
- belote_cli-0.9.9/tests/test_extended.py +0 -73
- {belote_cli-0.9.9 → belote_cli-2.5.2}/.gitignore +0 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/GRIMAUD Standard Playing-Cards-1898.png +0 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/LICENSE +0 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/__init__.py +0 -0
- {belote_cli-0.9.9/tests → belote_cli-2.5.2/src/belote/belatro}/__init__.py +0 -0
- {belote_cli-0.9.9 → belote_cli-2.5.2}/src/belote/ui/__init__.py +0 -0
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
"Bash(python3 -m ruff check src/ --statistics)",
|
|
8
8
|
"Bash(python3 -m mypy src/belote/ --ignore-missing-imports)",
|
|
9
9
|
"Bash(python3 -m pytest tests/ -q --tb=short)",
|
|
10
|
-
"Bash(python3 -m pytest tests/ -q --tb=no)"
|
|
10
|
+
"Bash(python3 -m pytest tests/ -q --tb=no)",
|
|
11
|
+
"Bash(python3 -m pytest tests/ -x -q)",
|
|
12
|
+
"Bash(PYTHONPATH=src python3 *)"
|
|
11
13
|
]
|
|
12
14
|
}
|
|
13
15
|
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.5.2] - 2026-05-02
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- **Critical Winner Detection Bug**: Resolved an issue in `game.py` where trick wins were assigned to the wrong player.
|
|
12
|
+
- **Scoring Engine Desync**: Fixed a major bug in `round_driver.py` where trick points were being calculated manually, leading to desyncs with boss modifiers. Now uses a direct state differential from the core engine.
|
|
13
|
+
- **Declaration Scoring**: Realized actual point values for sequences and carrés in `round_driver.py` using the official scoring utilities.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Partner Trust Integration**: Fully wired the trust system into the BelAtro run loop. Trust now increases on blind beats and big wins, and decreases on failures or chutes.
|
|
17
|
+
- **AI Personalities in Bidding**: The partner AI now uses its assigned personality (e.g., *Le Courageux*, *L'Économe*) to make bidding decisions, respecting trust levels.
|
|
18
|
+
- **Dynamic Partner Hand Visibility**: The partner's hand now automatically becomes visible to the player once the "shares void info" trust threshold is met.
|
|
19
|
+
- **Performance Cache Invalidation**: Added targeted cache clearing after boss modifier application to ensure game logic remains accurate and performant.
|
|
20
|
+
|
|
21
|
+
## [2.5.1] - 2026-05-02
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- **BelAtro Collection Discovery**: Items are now only revealed in the collection when actually encountered in-game, rather than immediately upon unlocking.
|
|
25
|
+
- **Auto-Save Persistence**: Added automatic profile saving after run initialization and shop encounters to ensure discovered items are never lost.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- **BelAtro Shop Crash**: Resolved a `NameError` in the shop UI by adding the missing `sys` import.
|
|
29
|
+
- **Trick Visibility Timing**: Fixed a race condition in `round_driver.py` where the 4th card of a trick was cleared before it could be rendered. The UI now correctly displays all 4 cards on the table before the trick-win popup appears.
|
|
30
|
+
|
|
31
|
+
## [2.5.0] - 2026-05-02
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Functional State Architecture**: Completed the transition to a pure functional engine. Joker state is now stored immutably in `GameState`, ensuring absolute "frozen-safety" and preventing state leakage between rounds.
|
|
35
|
+
- **Comprehensive BelAtro Test Suite**: Added a massive collection of 50+ new integration and regression tests covering all 57 critical edge cases identified in the audit. Total test count reached 276.
|
|
36
|
+
- **Performance Benchmarking Suite**: Added a new benchmark tool in `scripts/benchmark.py` to measure scoring, dealing, and legal card calculation performance.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- **Scoring Engine Refactor**: Decoupled boss modifier scoring logic into specialized helper functions, significantly improving maintainability and reducing risk of regression in complex Boss Blinds.
|
|
40
|
+
- **AI Strategy Decomposition**: Refactored the Hard AI decision-making into a clean strategy pattern, allowing for more granular tactical tuning.
|
|
41
|
+
- **EventBus Reliability**: Overhauled `EventBus.emit` to safely handle handler unsubscription during event dispatch, fixing a potential runtime crash.
|
|
42
|
+
- **Immutable Score Accumulation**: `ScoreAccumulator` now returns a new `GameState` instead of mutating internal fields, aligning BelAtro with the core engine's architectural principles.
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- **Animation Skip Reset (M6)**: Animation fast-forwarding now correctly resets on every human turn, preventing the game from accidentally staying in high-speed mode.
|
|
46
|
+
- **Score Overflow Precision**: Fixed a floating-point precision issue in `ScoreAccumulator` when dealing with extremely large chip counts (billions+).
|
|
47
|
+
- **Boss Blind Core Bugs**: Fixed all remaining audit bugs (B1-B8), including boss modifier application, scoring accumulation disconnects, and deck-specific bonus triggers.
|
|
48
|
+
|
|
49
|
+
## [2.4.1] - 2026-05-02
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
- **BelAtro Rules UI**: Fixed a major rendering bug where the rules screen would not clear correctly, leading to overlapping text.
|
|
53
|
+
- **Dynamic Formatting**: Rules screen now correctly handles terminal resizing and dynamic centering.
|
|
54
|
+
|
|
55
|
+
## [2.4.0] - 2026-05-02
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
- **BelAtro Collection (Almanac)**: A persistent gallery in the expansion menu to track discovered Jokers, Tarots, Planets, and Vouchers.
|
|
59
|
+
- **Full Boss Blind Suite**: All 17 unique bosses implemented, including complex mechanics like *L'Anarchie* (dynamic trump) and *La Rupture* (no consecutive wins).
|
|
60
|
+
- **Hard AI Overhaul**: Improved endgame awareness (Dix de Der), strategic discarding, and 2-ply void inference.
|
|
61
|
+
- **Enhanced UI Terminology**: Transitioned to "You" and "Partner" labels for a more immersive single-player experience.
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
- **Single-Player Focus**: Removed Hotseat (2P) mode and simplified the game engine and UI menus accordingly.
|
|
65
|
+
- **Consolidated Save Paths**: All local data (stats and profile) now live in a unified `belote` directory.
|
|
66
|
+
- **Menu Streamlining**: Removed "Mode" and "Reset Statistics" options for a cleaner main menu.
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
- **Gameflow Reliability**: Fixed a regression that caused certain tests to hang by properly mocking UI prompts.
|
|
70
|
+
- **Technical Integrity**: Achieved 100% type-safety (0 mypy errors) across all source and test modules.
|
|
71
|
+
|
|
72
|
+
## [2.3.3] - 2026-05-02
|
|
73
|
+
|
|
74
|
+
### Added
|
|
75
|
+
- **BelAtro Mode Integration**: Fully integrated the BelAtro roguelite mode into the main menu.
|
|
76
|
+
- **WIP Deck Completion**: Fully implemented all starting decks (L'Ermite, Le Vétéran, Le Flambeur) with their unique starting items and modifiers.
|
|
77
|
+
- **Advanced Joker Logic**: Completed implementation for all 50+ Jokers, including complex round-end and bidding-phase triggers.
|
|
78
|
+
- **Dynamic UI Rendering**: Refactored menu systems to dynamically center art and text based on terminal width.
|
|
79
|
+
- **Alternate Screen Support**: Implemented alternate screen switching for BelAtro to provide a clean, isolated terminal buffer.
|
|
80
|
+
|
|
81
|
+
### Fixed
|
|
82
|
+
- **BelAtro Startup**: Resolved a `TypeError` and `ImportError` that prevented BelAtro from launching correctly.
|
|
83
|
+
- **UI Centering**: Fixed an issue where menu art assumed a fixed 80-column width, causing misaligned headers on different terminal sizes.
|
|
84
|
+
- **Game Loop Continuity**: Fixed a bug where BelAtro would exit immediately back to the main menu instead of starting a run.
|
|
85
|
+
- **Event Bus Robustness**: Overhauled the `RoundEndEvent` to provide complete game state snapshots to Jokers, fixing several uninitialized logic paths.
|
|
86
|
+
|
|
87
|
+
## [2.3.1] - 2026-05-01
|
|
88
|
+
|
|
89
|
+
### Fixed
|
|
90
|
+
- **Contract Engine Logic**: Fixed a critical bug where trick winner detection failed during "Sans Atout" (No Trump) contracts. The engine now correctly handles `trump=None` scenarios.
|
|
91
|
+
- **Tout Atout / Sans Atout support**: Fully implemented correct card values and rankings for special contracts.
|
|
92
|
+
- *Tout Atout*: All Jacks (20 pts), all 9s (14 pts), and all suits follow trump ranking.
|
|
93
|
+
- *Sans Atout*: All Aces (11 pts), all 10s (10 pts), and all 9s (0 pts).
|
|
94
|
+
- **Coinche Multipliers**: Fixed a bug where Coinche (×2) and Surcoinche (×4) multipliers were not being applied to the final score in the core engine.
|
|
95
|
+
- **Sequence Detection**: Refactored sequence detection logic to be more maintainable and fixed a potential `NameError` in the detection loop.
|
|
96
|
+
- **Project-wide Type Safety**: Resolved over 250 `mypy` errors across the `tests/` and `src/` directories, achieving 100% strict type compliance.
|
|
97
|
+
- **Linting & Code Cleanup**: Eliminated all `ruff` violations and improved idiomatic Python usage throughout the codebase.
|
|
98
|
+
- **API Consistency**: Updated `trick_winner_seat`, `card_points`, and `trick_rank` to explicitly accept the `contract` type, ensuring accurate scoring and AI decisions across all game modes.
|
|
99
|
+
|
|
100
|
+
## [2.3.0] - 2026-05-01
|
|
101
|
+
|
|
102
|
+
### Added
|
|
103
|
+
- **Full Tarot System**: All 10 Tarot cards are now fully functional. Use `[U]` during your turn to open the consumable menu.
|
|
104
|
+
- *Le Chariot*: Steal the current trick (wired `force_next_trick_win`).
|
|
105
|
+
- *La Roue*: Change trump mid-round.
|
|
106
|
+
- *Le Jugement*: Resurrect sold Jokers.
|
|
107
|
+
- *Le Monde*: Double declaration points.
|
|
108
|
+
- *La Tempérance* & *Le Fou*: Permanent deck editing (random removal/duplication).
|
|
109
|
+
- **Complete Voucher Set**: All 9 vouchers are implemented with unique hooks.
|
|
110
|
+
- *La Télescope*: Preview the talon during bidding.
|
|
111
|
+
- *L'Encyclopédie*: Reveal partner personality during bidding.
|
|
112
|
+
- *Les Cartes Dorées*: Increased Gold Seal value (+$5).
|
|
113
|
+
- *Le Couteau*: Unlock card destruction in the Shop for $2 refunds.
|
|
114
|
+
- *La Balance*: Automatic win on close losses (within 10 points of target).
|
|
115
|
+
- *La Surcoinche*: Unlocks the massive ×4.0 Mult contract.
|
|
116
|
+
- **Dynamic Deck-Building**: The game engine now supports modified decks, allowing for permanent card additions and removals across a run.
|
|
117
|
+
- **Corrupted Joker Mechanics**: Implemented `Le Démon` (trust penalty on purchase).
|
|
118
|
+
- **Expanded Test Suite**: Added 52 new tests (total 165), significantly increasing coverage for `round_driver.py`, `shop.py`, `tarots.py`, and `vouchers.py`.
|
|
119
|
+
|
|
120
|
+
### Changed
|
|
121
|
+
- **Bidding Overhaul**: Opponents can now Coinche your bids (×2.0 Mult), and you can counter with Surcoinche (×4.0 Mult) if the voucher is owned.
|
|
122
|
+
- **Input Map**: Added `[U]` key for using consumables and removed `Tab` -> `Enter` mapping.
|
|
123
|
+
- **Performance**: Increased render cache size to 2048 and moved suit/ID mappings to module level for faster scoring.
|
|
124
|
+
- **Code Quality**: Extracted `_undo_or_restart` helper in `gameflow.py` and improved `EventBus` error logging.
|
|
125
|
+
|
|
126
|
+
### Fixed
|
|
127
|
+
- **Critical Bug Fixes**:
|
|
128
|
+
- *La Sentinelle*: Now correctly requires both Jack AND trump suit.
|
|
129
|
+
- *Le Rebelle*: Multiplier no longer stacks exponentially on Belote+Rebelote.
|
|
130
|
+
- *Le Stratège*: Strategic bidding logic (requires high-value cards instead of just any hand).
|
|
131
|
+
- *Recursive UI*: Fixed stack overflow risk in `prompt_card` on UNDO.
|
|
132
|
+
- *Shop Duplicates*: Replaced random choice with sampling to prevent identical jokers in shop.
|
|
133
|
+
- *UI Truncation*: Card destruction UI no longer truncates at 20 cards.
|
|
134
|
+
- **Boss Modifier Engine**: Fully wired 17 boss modifiers (forced pass, zero-point kings/tens, no Dix de Der, etc.) into the game engine.
|
|
135
|
+
- **Declaration scoring crash** (`round_driver.py`): replaced nonexistent `belote.deck.declaration_points` import with `belote.scoring.get_declaration_points`.
|
|
136
|
+
- **JokerResult multiplier zeroing** (`items/base.py`): `times_mult` default changed from `0.0` to `1.0`.
|
|
137
|
+
- **BelAtro standalone crash** (`belatro/main.py`): fixed missing `KeyReader` context.
|
|
138
|
+
- **Bid prompt null-dereference** (`ui/prompts.py`): added guards for `up_card`.
|
|
139
|
+
- **Type safety**: Resolved all 32 mypy errors and improved overall project type integrity.
|
|
140
|
+
- **Starting Decks**: All bonuses for *Le Joueur*, *L'Aristocrate*, *L'Ermite*, *Le Flambeur*, *Le Vétéran*, and *L'Anarchiste* are now correctly applied.
|
|
141
|
+
- **Scoring Hooks**: Wired missing `on_bid`, `on_round_start`, and `on_round_end` triggers for all Jokers.
|
|
142
|
+
|
|
143
|
+
## [2.2.0] - 2026-04-30
|
|
144
|
+
|
|
145
|
+
### Added
|
|
146
|
+
- **BelAtro Score Overlay Toggle**: Press `[I]` during any Belote/BelAtro game to toggle the per-trick score breakdown popup on or off. Useful when you want an unobstructed view of the table between tricks.
|
|
147
|
+
|
|
148
|
+
### Fixed
|
|
149
|
+
- **BelAtro trick display**: The 4th card played in a trick (the trick-completing card) was never shown on the table — the table went blank before the score popup appeared. All 4 cards now remain visible on the mat until the next trick begins.
|
|
150
|
+
- **BelAtro 4th-card visibility**: `on_card_played` now reconstructs the display state from `completed_tricks[-1]` when `current_trick` has been cleared by `play_card`, mirroring the classic mode's pre-play display state pattern.
|
|
151
|
+
|
|
152
|
+
## [2.0.1] - 2026-04-30
|
|
153
|
+
|
|
154
|
+
### Added
|
|
155
|
+
- **Le Républicain deck** is now fully playable: 7s and 8s are wild cards that can be played on any trick regardless of suit constraints. Your team earns +5 chips for every 7 or 8 you capture.
|
|
156
|
+
- **Le Carnet voucher** is now fully implemented: your partner's full hand is visible to you throughout every round. You earn +1 Mult each time South personally wins a trick.
|
|
157
|
+
- Both mechanics documented in the in-game Belatro Rules screen (EN and FR), under new "Starting Decks" and "Vouchers — Le Carnet" sections.
|
|
158
|
+
|
|
159
|
+
### Fixed
|
|
160
|
+
- Card-count invariant assertion added to `_handle_trick` to catch any future hand-size corruption early.
|
|
161
|
+
- Cards on the trick mat now render immediately after each card is played (previously only updated after the trick was complete).
|
|
162
|
+
|
|
163
|
+
## [2.0.0] - 2026-04-30
|
|
164
|
+
|
|
165
|
+
### Added
|
|
166
|
+
- **BelAtro Expansion**: A massive roguelite expansion inspired by Balatro, integrated into the Belote core.
|
|
167
|
+
- **The Run**: Progress through 8 'Antes' with increasing target scores. Each Ante consists of Small, Big, and Boss Blinds.
|
|
168
|
+
- **Scoring Engine**: New Multiplier-based scoring system: `Score = (Chips + Declarations) × Multiplier`.
|
|
169
|
+
- **Joker System**: 50+ unique Jokers (Contract, Corrupted, Economy, Hand Comp, Trick Timing) that provide passive buffs and scoring modifiers.
|
|
170
|
+
- **Consumables**: Planet cards to level up contracts, Tarot cards for one-shot effects, and permanent Vouchers.
|
|
171
|
+
- **Partner Trust**: Dynamic relationship with your AI partner. High trust reveals their hand/voids and boosts their specific "Partner Jokers."
|
|
172
|
+
- **Boss Blinds**: 10+ unique bosses with rule-breaking modifiers (e.g., hidden scores, suit debuffs, mid-round trump changes).
|
|
173
|
+
- **Event-Driven Architecture**: Introduced a centralized `EventBus` to handle complex item interactions and state updates.
|
|
174
|
+
- **Save/Load System**: Persistence for run progress, unlocks, and global statistics.
|
|
175
|
+
- **New UI Package**: Dedicated BelAtro HUD with Multiplier animations, Shop interface, and Trust bar visualization.
|
|
176
|
+
|
|
177
|
+
### Changed
|
|
178
|
+
- **Entry Points**: Added `belatro` as a secondary CLI command for direct access to the roguelite mode.
|
|
179
|
+
- **Core Refactor**: Decoupled the game loop from the rendering engine to support multiple game modes (Classic vs. BelAtro).
|
|
180
|
+
- **Test Suite**: Expanded tests to cover economy, ante scaling, item registry, and boss modifiers.
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
- **State Leakage**: Fixed an issue where items from previous runs could occasionally persist in the registry.
|
|
184
|
+
- **Trust Calculation**: Resolved a rounding error in trust gains during high-multiplier rounds.
|
|
185
|
+
|
|
186
|
+
## [1.1.0] - 2026-04-30
|
|
187
|
+
|
|
188
|
+
### Added
|
|
189
|
+
- **Incremental AI Void Inference**: Optimized AI memory to process tricks incrementally, significantly reducing CPU usage during late-game decision making.
|
|
190
|
+
- **Windows Input Support**: Added full `read_timeout` support for the Windows `KeyReader`, enabling animation skipping (Space/Esc) on Windows machines.
|
|
191
|
+
- **Enhanced Test Suite**: Added 4 new test cases covering Belote-to-defender scenarios, East-West taker variants, and trump sequence comparison logic.
|
|
192
|
+
|
|
193
|
+
### Changed
|
|
194
|
+
- **Scoring Breakdown Refactor**: Refactored the internal `ScoringBreakdown` structure to use clearer terminology (`table_pts` vs `credit_pts`), improving maintainability of the scoring engine.
|
|
195
|
+
- **Cache Optimization**: Replaced mutable object keys in the `trick_winner_seat` cache with primitive IDs, increasing the LRU cache hit rate to nearly 100%.
|
|
196
|
+
- **UI Layout Safety**: Migrated hardcoded terminal offsets to a centralized constant `_TRICK_ROW_OFFSETS` to ensure layout stability across different terminal heights.
|
|
197
|
+
|
|
198
|
+
### Fixed
|
|
199
|
+
- **Ineffective LRU Caching**: Fixed a major performance issue where the trick winner cache was effectively bypassed on every call due to object identity mismatches.
|
|
200
|
+
- **Scoring Comparison Bug**: Fixed a logic error in `scoring.py` where contract fulfillment (Litige/Chute) was comparing raw card points instead of total round points (including 10 de der and declarations).
|
|
201
|
+
- **Flawed Chute Test**: Corrected `test_chute_declaration_transfer` which was incorrectly triggering the capot code path instead of the intended chute path.
|
|
202
|
+
- **Circular Imports**: Resolved a brittle circular dependency between `themes.py` and `ui/render.py` using a new observer-based callback system.
|
|
203
|
+
- **No-op Tests**: Fully implemented `test_litige_detection` and `test_current_round_points_update` which were previously empty stubs.
|
|
204
|
+
|
|
205
|
+
## [1.0.0] - 2026-04-30
|
|
206
|
+
|
|
207
|
+
### Added
|
|
208
|
+
- **Official Rules Compliance**: Significant overhaul of game logic to align with the [Fédération Française de Belote](https://www.ffbelote.org/regles-officielle-belote/).
|
|
209
|
+
- **Litige (Tie-break)**: Implemented standard tie-break rules. On a card-point tie (e.g., 81-81), the taker's points and declarations are held in escrow and awarded to the winner of the next round.
|
|
210
|
+
- **Improved Capot Scoring**: Winning all 8 tricks now awards exactly 252 points (152 cards + 100 bonus) and includes all declarations from both teams.
|
|
211
|
+
- **Correct Chute Scoring**: On a failed bid (chute), the defenders now correctly receive 162 points plus all declarations from both teams.
|
|
212
|
+
- **Tie-breaker Rounds**: Games ending in a perfect tie beyond the target score now trigger an additional round instead of selecting a winner arbitrarily.
|
|
213
|
+
|
|
214
|
+
### Changed
|
|
215
|
+
- **Default Capot Points**: Updated `CAPOT_BASE` from 250 to 252.
|
|
216
|
+
- **Bilingual Rules Text**: Updated the English and French rules viewer to reflect the new official scoring mechanics.
|
|
217
|
+
- **Project Version**: Officially promoted to version 1.0.0.
|
|
218
|
+
|
|
219
|
+
### Fixed
|
|
220
|
+
- **Capot Announcement Bug**: Fixed a regression where Capot was not announced for the NS team due to a truthiness check on team index `0`.
|
|
221
|
+
|
|
222
|
+
## [0.9.9] - 2026-04-28
|
|
223
|
+
|
|
224
|
+
### Fixed
|
|
225
|
+
- **Critical: Failed bid (chute) scoring**: Taker's declarations were incorrectly added to the defender total on failure. In standard French Belote, the taker's declarations are annulled on chute — not transferred. Defender total is now `162 + defender_declarations + defender_belote` only.
|
|
226
|
+
- **Critical: Belote announcement fires on every subsequent card**: `state.announced` was preserved across plays, causing the Belote!/Rebelote! popup to re-trigger on each card played after the announcement. Announcement now resets to `None` at the start of each play and is cleared in `gameflow.py` after display.
|
|
227
|
+
- **Critical: Hand sort not persisted**: Pressing [O] to sort South's hand updated only the local variable in `prompt_card`; the sorted state was never propagated back to `run_play`, reverting on the next turn. `prompt_card` now returns `(Card | str | None, GameState)` so callers receive the potentially-sorted state.
|
|
228
|
+
- **Multi-byte UTF-8 input**: `os.read(fd, 1)` reads one byte at a time — multi-byte characters (accented letters, symbols, emoji) were split across reads producing garbled output. Input reader now accumulates the correct number of continuation bytes based on the leading byte's UTF-8 prefix bits.
|
|
229
|
+
- **AI hard-mode magic number**: Trump rank threshold `rank < 14` hardcoded the numeric rank of the 9 of trump. Now computed as `trick_rank(Card(trump, Rank.NINE), trump)` so it remains correct if the ranking table changes.
|
|
230
|
+
- **`TrickCard` NameError**: `TrickCard` was referenced in `scoring.py` and `ai.py` without being imported, causing a runtime crash during trick scoring.
|
|
231
|
+
- **`ScoringBreakdown` missing fields**: Early-return path in `score_round` omitted `taker_rebelote` and `defender_rebelote` keyword arguments, causing a `TypeError` on all-pass rounds.
|
|
232
|
+
- **`resolve_declarations` type mismatch**: Parameter type corrected from `dict[Seat, dict[str, object]]` to the proper `SeatDeclarations` TypedDict, eliminating unsafe `.get()` calls with stale fallbacks.
|
|
233
|
+
- **`is_capot` walrus operator**: Fixed malformed walrus expression that prevented capot detection from evaluating correctly.
|
|
234
|
+
- **`belote_tracker` tuple type**: Three call sites in `game.py` passed `tuple(list)` producing `tuple[bool, ...]` where `tuple[bool, bool]` was required; fixed to explicit two-element construction.
|
|
235
|
+
- **`deal()` return type**: Third element annotation corrected from `tuple[tuple[Card, ...], ...]` to `tuple[Card, ...]` to match the actual talon structure.
|
|
236
|
+
- **Trump `None` guard in `ai.py`**: Medium AI `_medium_play` now returns early via `_easy_play` when trump is `None`, preventing a `Suit | None` vs `Suit` type error.
|
|
237
|
+
- **Trump `None` guard in `game.py`**: `play_card` extracts `trump` as a local variable and guards `card_points` summation with `if trump is not None else 0`.
|
|
238
|
+
|
|
239
|
+
### Changed
|
|
240
|
+
- **`trick_winner_seat` cache cleared between rounds**: `clear_legal_cards_cache()` now also clears the `trick_winner_seat` LRU cache to prevent unbounded memory accumulation across long games.
|
|
241
|
+
- **Theme change invalidates card render cache**: `ThemeManager.set_current()` now calls `clear_card_cache()` so new theme colors apply immediately without stale card face renders.
|
|
242
|
+
- **`announced` field decoupled from HUD badge**: The HUD Belote!/Rebelote! badge is now derived from `belote_tracker` (persistent) rather than `state.announced` (one-shot trigger), giving correct behaviour in both the popup and the persistent status bar.
|
|
243
|
+
- **AI void tracking incremental**: `_update_voids` now processes only new cards in the current trick on each call rather than re-scanning all cards from index 1 every time.
|
|
244
|
+
- **`initial_hands` comment**: Added clarifying comment that `initial_hands` stores 8-card hands at start of play (not the 5-card deal), used for declaration detection during scoring.
|
|
245
|
+
- **Removed dead fields**: `GameState.declarations_resolved` (set but never read) and `GameState.round_scores` (superseded by `current_round_points`) removed to eliminate confusion.
|
|
246
|
+
- **`themes` import moved to top of `ansi.py`**: The `from .themes import theme_manager` import was placed mid-file with a `# noqa: E402` suppressor; moved to the standard top-of-file position.
|
|
247
|
+
- **Type safety**: Resolved all 70 mypy strict-mode errors across 12 source files — `game.py`, `scoring.py`, `ai.py`, `gameflow.py`, `deck.py`, `input.py`, `stats.py`, `rules.py`, `themes.py`, `config.py`, `ui/prompts.py`, `ui/render.py`.
|
|
248
|
+
- **Code quality**: Resolved all 243 ruff lint violations (188 auto-fixed, 55 manual) across the entire codebase — covering unused imports (F401), bare `except` (B), shadowed builtins (A), redundant conditionals (SIM), pathlib migration (PTH), return simplification (RET), and more.
|
|
249
|
+
- **`rules.py` typed content**: Introduced `RulesSection` and `RulesPage` TypedDicts for the rules content dictionary, replacing untyped `dict[str, object]`.
|
|
250
|
+
- **`input.py` raw-mode guard**: `_old_termios` type changed from `termios.termios` to `list[Any]` to match the actual return type of `termios.tcgetattr`.
|
|
251
|
+
- **`ui/prompts.py` render cache**: Cache key type corrected from `str` to `tuple[str, int]` to include terminal width, preventing stale renders on resize.
|
|
252
|
+
|
|
253
|
+
### Tests
|
|
254
|
+
- Added test: failed bid taker declarations are annulled (not transferred to defenders).
|
|
255
|
+
- Added test: multi-byte UTF-8 input (`♠` = 3 bytes) read as a single `CHAR` event.
|
|
256
|
+
- Added test: `sort_south_hand` is idempotent and produces a stable ordering.
|
|
257
|
+
- Added test: declarations stored at bid time match those recalculated at scoring.
|
|
258
|
+
|
|
259
|
+
### Performance
|
|
260
|
+
- **`visible_len` ANSI cache**: Increased LRU cache size from 1 024 to 4 096 slots to reduce cache evictions during rapid re-renders.
|
|
261
|
+
|
|
262
|
+
## [0.9.8] - 2026-04-28
|
|
263
|
+
|
|
264
|
+
### Added
|
|
265
|
+
- **Overtrump Rule Enforcement**: Added strict validation and tests for the overtrump rule when a trump suit is led.
|
|
266
|
+
- **Improved AI Void Inference**: AI now infers opponent voids in real-time from the current trick, making it more tactically aware during play.
|
|
267
|
+
- **Consistency Tests**: Added new tests to verify point conservation and rule integrity across all trump suits.
|
|
268
|
+
|
|
269
|
+
### Changed
|
|
270
|
+
- **Scoring Integrity**:
|
|
271
|
+
- Corrected `TOTAL_POINTS` to 152 to match the actual sum of card points (A=11, 10=10, K=4, Q=3, J=2/20, 9=0/14).
|
|
272
|
+
- Refactored "failed bid" (chute) logic to explicitly account for card points (152) and last trick bonus (10), totaling 162.
|
|
273
|
+
- **Performance Optimizations**:
|
|
274
|
+
- **Dictionary Rebuilds**: Eliminated redundant mapping rebuilds in `legal_cards` by precomputing card-to-ID lookups.
|
|
275
|
+
- **Batch Stats I/O**: Reduced disk pressure by batching statistics flushes to the end of each game.
|
|
276
|
+
- **UI & Controls**:
|
|
277
|
+
- **Interruptible Announcements**: Players can now skip banner announcements (Dix de Der, Capot) using Space or Esc.
|
|
278
|
+
- **Adaptive Layout**: Fixed coordinate offsets in `patch_trick_card` to ensure perfect card placement on all terminal sizes.
|
|
279
|
+
- **Input Consistency**: Resolved 't'/'T' conflict; 't' is now dedicated to History and 'T' to Theme switching.
|
|
280
|
+
- **Architectural Improvements**:
|
|
281
|
+
- **Clean Exports**: Standardized `replace` usage by importing directly from `dataclasses`.
|
|
282
|
+
|
|
283
|
+
### Fixed
|
|
284
|
+
- **Worst Score Display**: Fixed a bug where round scores ≥ 200 were hidden in the statistics screen.
|
|
285
|
+
- **Off-suit Comparison**: Fixed a redundancy in `_card_beats` to correctly handle same-suit rank comparisons for off-suit cards.
|
|
286
|
+
|
|
287
|
+
## [0.9.7] - 2026-04-27
|
|
288
|
+
|
|
289
|
+
### Added
|
|
290
|
+
- **Pre-game Hand Preview**: Shows your hand and estimated declaration points before the bidding phase starts.
|
|
291
|
+
- **Strategic Hand Sorting**: "Play value" sort mode that groups honors (J, 9, A, 10...) and separates trump strategically.
|
|
292
|
+
- **Improved Medium AI**: Now tracks inferred voids to force trumps or discards, making it significantly more challenging.
|
|
293
|
+
- **Configurable AI Seats**: Fully independent AI difficulty selection for each seat in the main menu.
|
|
294
|
+
- **Illegal Move Protection**: Play loop now strictly enforces rules and raises `IllegalMoveError` for invalid card plays, preventing state corruption.
|
|
295
|
+
- **Centralized Configuration**: All game rules, timings, and UI dimensions consolidated into a global `Config` system.
|
|
296
|
+
|
|
297
|
+
### Changed
|
|
298
|
+
- **Performance Optimization**:
|
|
299
|
+
- HUD updates are now targeted (1-line refresh) instead of full-screen re-renders during animations.
|
|
300
|
+
- Memoized `trick_winner_seat` calculation to avoid redundant scoring logic.
|
|
301
|
+
- Switched to a manual per-round cache for legal card lookups.
|
|
302
|
+
- **XDG Compliance**: Statistics are now stored in standard locations (`~/.local/share/belote/stats.json`) with automatic fallback.
|
|
303
|
+
- **Refactored Architecture**: Eliminated module-level global state in favor of dedicated `StatisticsManager`, `AudioManager`, and `TerminalContext` managers.
|
|
304
|
+
|
|
305
|
+
### Fixed
|
|
306
|
+
- **Sentinel Correction**: Fixed `worst_round_score` initialization and added support for recording 0-point rounds (capot against you).
|
|
307
|
+
- **Type Safety**: Fixed potential crashes in declaration processing by adding safe detail access for Carré/Belote types.
|
|
308
|
+
- **Deterministic RNG**: Round deals are now deterministic when using the `--seed` CLI flag.
|
|
309
|
+
- **Import Errors**: Fixed missing `GameState` import in entry point.
|
|
310
|
+
- **Test Integrity**: Fixed numerous test suite regressions related to generator types and mocked dependencies.
|
|
311
|
+
|
|
312
|
+
## [0.9.6] - 2026-04-27
|
|
313
|
+
|
|
314
|
+
### Added
|
|
315
|
+
- **Enhanced Statistics**: Added tracking for best/worst round scores, longest game length, and win rate broken down by AI difficulty level.
|
|
316
|
+
- **Session Stats**: New "This Session" panel in the statistics screen for real-time session tracking.
|
|
317
|
+
- **Improved AI Strategy**:
|
|
318
|
+
- Medium AI now prioritizes leading from its longest suit and avoids leading into opponent strength.
|
|
319
|
+
- Hard AI features an improved 2-ply lookahead for critical tricks and better void inference.
|
|
320
|
+
- Added "AI personality" variance for less predictable bidding.
|
|
321
|
+
- **Non-UTF-8 Support**: Added graceful degradation for terminals without UTF-8 support (text-only card representation).
|
|
322
|
+
- **Expanded Test Suite**: Increased coverage with new AI logic, gameflow integration, and property-based tests.
|
|
323
|
+
|
|
324
|
+
### Changed
|
|
325
|
+
- **UI Refactoring**: Major modularization of `ui.py` into `belote.ui` package (`render`, `prompts`, `menu`, `announce`).
|
|
326
|
+
- **Game Flow Separation**: Extracted game loop logic from `main.py` into `gameflow.py`.
|
|
327
|
+
- **Keyboard Shortcuts**: Changed History shortcut to 'T' (previously 'H') to resolve conflicts with Help.
|
|
328
|
+
- **Language Toggle**: Changed language toggle in rules screen to 'L' to avoid conflict with History.
|
|
329
|
+
|
|
330
|
+
### Fixed
|
|
331
|
+
- **Initial Hands Bug**: Fixed a bug where `initial_hands` was incorrectly reset to empty tuples at the start of a round.
|
|
332
|
+
- **Input Validation**: Added defensive checks to ensure chosen cards are always in the player's hand and legal.
|
|
333
|
+
- **Redeal Loop**: Ensured dealer rotation works correctly during repeated "all-pass" bidding rounds.
|
|
334
|
+
|
|
335
|
+
## [0.9.5] - 2026-04-26
|
|
336
|
+
|
|
337
|
+
### Added
|
|
338
|
+
- **Hand Sorting**: Press 'O' to sort your hand by suit and rank.
|
|
339
|
+
- **Keyboard Shortcut Help**: Press '?' for a quick reference of all key bindings.
|
|
340
|
+
- **Mute Toggle**: Press 'M' to toggle sound effects on/off.
|
|
341
|
+
- **Declaration Announcements**: Automatic display of sequences (Tierce, Quarte, etc.) and Carrés after the first trick.
|
|
342
|
+
- **CLI --version**: Added standard version flag.
|
|
343
|
+
|
|
344
|
+
### Improved
|
|
345
|
+
- **Terminal Performance**: Switched to incremental rendering (cursor move + EOL clear) for zero-flicker UI.
|
|
346
|
+
- **AI Performance**: Optimized void inference and added LRU caching for legal card lookups.
|
|
347
|
+
- **Memory Efficiency**: Optimized GameState cache keys and pre-calculated Belote eligibility.
|
|
348
|
+
- **Reliability**: Declarations now use pre-calculated initial hands to prevent reconstruction errors.
|
|
349
|
+
- **Sound Effects**: Better timing and distinct sounds for different game events.
|
|
350
|
+
|
|
351
|
+
### Fixed
|
|
352
|
+
- Fixed infinite loop in `show_stats()`.
|
|
353
|
+
- Fixed early return bug in `show_history()`.
|
|
354
|
+
- Fixed missing `Key` import causing crash on animation skip.
|
|
355
|
+
|
|
356
|
+
## [0.9.4] - 2026-04-26
|
|
357
|
+
|
|
358
|
+
### Added
|
|
359
|
+
- Detailed Round Score History pop-up (accessible via 'H').
|
|
360
|
+
- Global Statistics screen in main menu.
|
|
361
|
+
- Hotseat (2P) Mode for local multiplayer.
|
|
362
|
+
- Undo Support (accessible via 'Z' during play).
|
|
363
|
+
- Terminal Sound Effects for key events.
|
|
364
|
+
- Seat-specific AI Difficulty configuration.
|
|
365
|
+
- Support for skipping animations (Space/Esc).
|
|
366
|
+
|
|
367
|
+
### Improved
|
|
368
|
+
- Significant performance optimization for real-time HUD scoring.
|
|
369
|
+
- UI rendering speed and smooth ASCII art animations.
|
|
370
|
+
- O(1) rank lookup performance.
|
|
371
|
+
|
|
372
|
+
### Fixed
|
|
373
|
+
- Indentation and template errors in `main.py` and `ui.py`.
|
|
374
|
+
|
|
375
|
+
## [0.9.2] - 2026-04-26
|
|
376
|
+
|
|
377
|
+
### Fixed
|
|
378
|
+
- Fixed `ValueError: max() iterable argument is empty` in `legal_cards` when trump is led.
|
|
379
|
+
|
|
380
|
+
## [0.9.1] - 2026-04-26
|
|
381
|
+
|
|
382
|
+
### Fixed
|
|
383
|
+
- Fixed `ModuleNotFoundError` during gameplay caused by absolute imports in `game.py`.
|
|
384
|
+
|
|
385
|
+
## [0.9.0] - 2026-04-26
|
|
386
|
+
|
|
387
|
+
### Added
|
|
388
|
+
- Initial release as a standard Python package.
|
|
389
|
+
- Full-screen terminal UI for French Belote.
|
|
390
|
+
- AI difficulty levels: Easy, Medium, Hard.
|
|
391
|
+
- Bidding and scoring systems.
|
|
392
|
+
- Multilingual (EN/FR) rules and history viewer.
|
|
393
|
+
- Standard project structure with `src` layout.
|
|
394
|
+
- Git repository initialization and GitHub sync.
|
|
@@ -23,14 +23,20 @@ Welcome to the Belote development guide. This project is structured as a standar
|
|
|
23
23
|
|
|
24
24
|
## Running the Game
|
|
25
25
|
|
|
26
|
-
After installing, you can run the game using the `belote` command:
|
|
26
|
+
After installing, you can run the game using the `belote` command for Classic mode:
|
|
27
27
|
```bash
|
|
28
28
|
belote
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
Or the `belatro` command for the Roguelite expansion:
|
|
32
|
+
```bash
|
|
33
|
+
belatro
|
|
34
|
+
```
|
|
35
|
+
|
|
31
36
|
Or via python:
|
|
32
37
|
```bash
|
|
33
38
|
python -m belote.main
|
|
39
|
+
python -m belote.belatro.main
|
|
34
40
|
```
|
|
35
41
|
|
|
36
42
|
## Testing
|
|
@@ -42,7 +48,28 @@ pip install pytest
|
|
|
42
48
|
|
|
43
49
|
Run tests:
|
|
44
50
|
```bash
|
|
51
|
+
# Run all tests (Classic + BelAtro)
|
|
45
52
|
PYTHONPATH=src pytest
|
|
53
|
+
|
|
54
|
+
# Run only Classic Belote tests
|
|
55
|
+
PYTHONPATH=src pytest tests/
|
|
56
|
+
|
|
57
|
+
# Run only BelAtro tests
|
|
58
|
+
PYTHONPATH=src pytest tests/belatro/
|
|
59
|
+
|
|
60
|
+
# Run a single test file
|
|
61
|
+
PYTHONPATH=src pytest tests/test_game.py
|
|
62
|
+
PYTHONPATH=src pytest tests/belatro/test_scoring.py
|
|
63
|
+
|
|
64
|
+
# Run a single test by name
|
|
65
|
+
PYTHONPATH=src pytest tests/test_game.py::test_play_card_legal
|
|
66
|
+
PYTHONPATH=src pytest -k "test_scoring"
|
|
67
|
+
|
|
68
|
+
# Run with verbose output
|
|
69
|
+
PYTHONPATH=src pytest -v
|
|
70
|
+
|
|
71
|
+
# Run with coverage report
|
|
72
|
+
PYTHONPATH=src pytest --cov=belote --cov-report=term-missing
|
|
46
73
|
```
|
|
47
74
|
|
|
48
75
|
## Code Quality
|
|
@@ -51,19 +78,20 @@ The project maintains zero lint and type-check violations. Run all checks with:
|
|
|
51
78
|
|
|
52
79
|
```bash
|
|
53
80
|
# Type checking (0 errors expected)
|
|
54
|
-
PYTHONPATH=src
|
|
81
|
+
PYTHONPATH=src mypy .
|
|
55
82
|
|
|
56
83
|
# Linting (0 violations expected)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# Full test suite (67 tests expected)
|
|
84
|
+
ruff check .
|
|
85
|
+
# Full test suite (305 tests expected)
|
|
60
86
|
PYTHONPATH=src pytest
|
|
61
|
-
```
|
|
62
87
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- **
|
|
88
|
+
# ...
|
|
89
|
+
|
|
90
|
+
Current baseline:
|
|
91
|
+
- **mypy**: 0 errors (strict mode)
|
|
92
|
+
- **ruff**: 0 violations
|
|
93
|
+
- **pytest**: 305 tests, 0 failures
|
|
94
|
+
|
|
67
95
|
|
|
68
96
|
## Benchmarking
|
|
69
97
|
|