draftomen 0.3.0__py3-none-any.whl

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.
Files changed (59) hide show
  1. draftomen/__init__.py +17 -0
  2. draftomen/assets/draftomen.icns +0 -0
  3. draftomen/assets/draftomen.ico +0 -0
  4. draftomen/assets/draftomen_logo.png +0 -0
  5. draftomen/audit.py +606 -0
  6. draftomen/backtest.py +449 -0
  7. draftomen/benchmark.py +834 -0
  8. draftomen/carddb.py +1869 -0
  9. draftomen/cardimages.py +313 -0
  10. draftomen/cli.py +891 -0
  11. draftomen/config.py +133 -0
  12. draftomen/deckbuilder.py +2723 -0
  13. draftomen/events.py +772 -0
  14. draftomen/logfollow.py +451 -0
  15. draftomen/mock_session.py +745 -0
  16. draftomen/paths.py +120 -0
  17. draftomen/pickengine.py +1117 -0
  18. draftomen/pool.py +1259 -0
  19. draftomen/preferences.py +289 -0
  20. draftomen/qml/AboutDialog.qml +156 -0
  21. draftomen/qml/AppBar.qml +120 -0
  22. draftomen/qml/BacktestView.qml +316 -0
  23. draftomen/qml/BuildView.qml +1151 -0
  24. draftomen/qml/CardPreview.qml +434 -0
  25. draftomen/qml/DimensionalButton.qml +42 -0
  26. draftomen/qml/DimensionalComboBox.qml +182 -0
  27. draftomen/qml/DimensionalSurface.qml +118 -0
  28. draftomen/qml/DimensionalTabButton.qml +41 -0
  29. draftomen/qml/LiveDraftView.qml +468 -0
  30. draftomen/qml/Main.qml +175 -0
  31. draftomen/qml/NavigationRail.qml +226 -0
  32. draftomen/qml/PoolSummaryPanel.qml +322 -0
  33. draftomen/qml/PrivacyDialog.qml +96 -0
  34. draftomen/qml/RecentPickThumbnail.qml +83 -0
  35. draftomen/qml/RecentPicksGallery.qml +333 -0
  36. draftomen/qml/RecommendationRow.qml +404 -0
  37. draftomen/qml/SettingsSwitch.qml +141 -0
  38. draftomen/qml/SettingsView.qml +531 -0
  39. draftomen/qml/StateBanner.qml +189 -0
  40. draftomen/qml/StatusStrip.qml +84 -0
  41. draftomen/qml/Theme.qml +71 -0
  42. draftomen/qml/qmldir +23 -0
  43. draftomen/qt_adapter.py +884 -0
  44. draftomen/qt_gui.py +338 -0
  45. draftomen/qt_mock.py +63 -0
  46. draftomen/ranking.py +126 -0
  47. draftomen/replay.py +480 -0
  48. draftomen/session.py +3668 -0
  49. draftomen/setinfo.py +26 -0
  50. draftomen/seventeen.py +2766 -0
  51. draftomen/splash.py +617 -0
  52. draftomen/tui.py +4007 -0
  53. draftomen/watch.py +336 -0
  54. draftomen-0.3.0.dist-info/METADATA +156 -0
  55. draftomen-0.3.0.dist-info/RECORD +59 -0
  56. draftomen-0.3.0.dist-info/WHEEL +5 -0
  57. draftomen-0.3.0.dist-info/entry_points.txt +6 -0
  58. draftomen-0.3.0.dist-info/licenses/LICENSE +21 -0
  59. draftomen-0.3.0.dist-info/top_level.txt +1 -0
draftomen/config.py ADDED
@@ -0,0 +1,133 @@
1
+ """Documented tunables for Draftomen.
2
+ Centralize defaults that later scoring and deck-building modules will share.
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from dataclasses import dataclass
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class SplashConfig:
12
+ """Conservative Limited splash defaults shared by picks and builds.
13
+ Keep thresholds explicit so replay data can calibrate them safely.
14
+ """
15
+
16
+ enabled_by_default: bool = True
17
+ maximum_colors: int = 1
18
+ maximum_cards: int = 2
19
+ maximum_off_color_pips: int = 1
20
+ single_card_sources: int = 3
21
+ multiple_card_sources: int = 4
22
+ planned_basic_sources: int = 1
23
+ supported_minimum_grade: str = "A-"
24
+ speculative_minimum_grade: str = "A"
25
+ minimum_score_advantage: float = 5.0
26
+ ready_score_multiplier: float = 0.95
27
+ speculative_score_multiplier: float = 0.85
28
+ fixer_score_multiplier: float = 1.05
29
+ aggressive_minimum_spells: int = 8
30
+ aggressive_average_mana_value_max: float = 2.7
31
+ aggressive_minimum_two_drop_ratio: float = 0.3
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class DeckBuilderConfig:
36
+ """Deck-builder structural defaults.
37
+ Keep values aligned with Limited consensus until data-backed tuning exists.
38
+ """
39
+
40
+ deck_size: int = 40
41
+ target_spell_count: int = 23
42
+ pair_score_card_weight: float = 0.85
43
+ pair_score_win_rate_weight: float = 0.15
44
+ neutral_pair_win_rate: float = 0.5
45
+ pair_score_decimal_places: int = 2
46
+ default_land_count: int = 17
47
+ aggressive_land_count: int = 16
48
+ top_heavy_land_count: int = 18
49
+ aggressive_average_mana_value_max: float = 2.7
50
+ top_heavy_average_mana_value_min: float = 3.4
51
+ creature_floor: int = 14
52
+ creature_ceiling: int = 17
53
+ minimum_two_drops: int = 5
54
+ maximum_expensive_spells: int = 3
55
+ two_drop_mana_value: float = 2.0
56
+ expensive_spell_mana_value: float = 6.0
57
+ near_tie_creature_preference_points: float = 2.0
58
+ splash_max_cards: int = 2
59
+ splash_elite_score_minimum: float = 70.0
60
+ bench_card_count: int = 5
61
+ land_count_iteration_limit: int = 4
62
+ maximum_unresolved_metadata_ratio: float = 0.25
63
+ relaxation_order: tuple[str, ...] = (
64
+ "expensive-spell cap",
65
+ "minimum two-drop quota",
66
+ "creature ceiling",
67
+ "creature floor",
68
+ "eligible-card shortage",
69
+ )
70
+ main_color_source_floor: int = 7
71
+ structure_maindeck_rate_threshold: float = 0.5
72
+ structure_min_land_count: int = 14
73
+ structure_max_land_count: int = 20
74
+
75
+
76
+ @dataclass(frozen=True)
77
+ class PickEngineConfig:
78
+ """Pick-engine scoring defaults.
79
+ Scores stay integer-only for scan-friendly draft tables.
80
+ """
81
+
82
+ neutral_prior_score: float = 50.0
83
+ neutral_prior_win_rate: float = 0.55
84
+ thin_sample_minimum: int = 500
85
+ alsa_adjustment_max: float = 0.03
86
+ alsa_early_pick: float = 1.0
87
+ alsa_late_pick: float = 8.0
88
+ normalization_lower_percentile: float = 5.0
89
+ normalization_upper_percentile: float = 95.0
90
+ normalization_min_half_span: float = 0.05
91
+ score_decimal_places: int = 0
92
+ # Picks 1-5 stay open; pick 6 starts the linear color ramp.
93
+ open_pick_count: int = 5
94
+ commitment_start_pick: int = 6
95
+ # Pick 16 and later are treated as locked to the inferred pair.
96
+ locked_pick_index: int = 16
97
+ # Locked on-color cards get up to +15% score; off-color cards keep 75%.
98
+ on_color_bonus_multiplier: float = 1.15
99
+ off_color_penalty_multiplier: float = 0.75
100
+ # Each picked card starts at 1.0 color weight, then ratings move it up/down.
101
+ pool_weight_baseline: float = 1.0
102
+ pool_weight_rating_scale: float = 10.0
103
+ pool_weight_minimum: float = 0.25
104
+ pool_weight_maximum: float = 2.0
105
+ # Require two materially represented colors before naming a pair.
106
+ pool_weight_epsilon: float = 0.01
107
+ minimum_pair_colors: int = 2
108
+ premier_fallback_enabled: bool = True
109
+ # Open picks use pair win rates only as a close-pick tiebreaker.
110
+ early_pair_tiebreaker_score_threshold: float = 3.0
111
+ early_pair_tiebreaker_pair_weight_threshold: float = 0.25
112
+ early_pair_tiebreaker_max_offered_cards: int = 16
113
+
114
+
115
+ DECK_BUILDER = DeckBuilderConfig()
116
+ PICK_ENGINE = PickEngineConfig()
117
+ SPLASH = SplashConfig()
118
+
119
+ POLL_INTERVAL_SECONDS = 1.0
120
+ RATINGS_CACHE_TTL_HOURS = 24
121
+
122
+ COLOR_PAIRS = (
123
+ "WU",
124
+ "WB",
125
+ "WR",
126
+ "WG",
127
+ "UB",
128
+ "UR",
129
+ "UG",
130
+ "BR",
131
+ "BG",
132
+ "RG",
133
+ )