cw_card_utils 0.1.11 → 0.2.1
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.
- checksums.yaml +4 -4
- data/README.md +151 -6
- data/data/scryfall.cards.cmc.json +396952 -427530
- data/lib/crackling_wit/card_utils.rb +41 -0
- data/lib/crackling_wit.rb +5 -0
- data/lib/cw_card_utils/curve_calculator.rb +50 -0
- data/lib/cw_card_utils/deck_comparator.rb +47 -0
- data/lib/cw_card_utils/decklist_parser/archetype_detector.rb +34 -0
- data/lib/cw_card_utils/decklist_parser/card.rb +67 -2
- data/lib/cw_card_utils/decklist_parser/card_tagger.rb +32 -0
- data/lib/cw_card_utils/decklist_parser/color_identity_resolver.rb +7 -0
- data/lib/cw_card_utils/decklist_parser/deck.rb +177 -1
- data/lib/cw_card_utils/decklist_parser/parser.rb +26 -0
- data/lib/cw_card_utils/scryfall_cmc_data.rb +94 -6
- data/lib/cw_card_utils/synergy_probability.rb +35 -1
- data/lib/cw_card_utils/version.rb +8 -1
- data/lib/cw_card_utils.rb +38 -1
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 906b2d48d1b46bac9ddae4395dde482acda9017854a8f43a88b554421bc34da5
|
|
4
|
+
data.tar.gz: de6f89e9b88dc62552f3ad39253ba40522cfceacf78718aa301c30e71598b25e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f4c05be5fede670c4dbaaf06a1813db002366dda8e81ff462452fe8252207f7b790ecf22e86bb93b056304f7680886cceff58a83d90ea6cd0a76791bcc8be6a3
|
|
7
|
+
data.tar.gz: f5da3ba07dc6df50857dada5a27760012d7ecdc344c7be49aafddafcae1564997f1530fab99d018cf3e552d273ba02efa62269a16dfecdecad33cbeb1f1f8d84
|
data/README.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
A Ruby gem for analyzing Magic: The Gathering decklists and calculating various metrics.
|
|
4
4
|
|
|
5
|
+
> Note: A new preferred namespace is available: `CracklingWit::CardUtils`.
|
|
6
|
+
> The legacy `CwCardUtils` namespace remains for backward compatibility and will be softly deprecated.
|
|
7
|
+
>
|
|
8
|
+
> New usage (preferred):
|
|
9
|
+
>
|
|
10
|
+
> ```ruby
|
|
11
|
+
> require "crackling_wit/card_utils"
|
|
12
|
+
> a = CracklingWit::CardUtils::DecklistParser::Parser.new(decklist_a).parse
|
|
13
|
+
> b = CracklingWit::CardUtils::DecklistParser::Parser.new(decklist_b).parse
|
|
14
|
+
> cmp = CracklingWit::CardUtils::DeckComparator.new(a, b)
|
|
15
|
+
> ```
|
|
16
|
+
>
|
|
17
|
+
> Legacy usage (still supported):
|
|
18
|
+
>
|
|
19
|
+
> ```ruby
|
|
20
|
+
> require "cw_card_utils"
|
|
21
|
+
> a = CwCardUtils::DecklistParser::Parser.new(decklist_a).parse
|
|
22
|
+
> ```
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- Parse decklists (MTGA/MTGO/Moxfield) into a rich `Deck` model
|
|
27
|
+
- Compute curves: raw, normalized, and collapsed-normalized
|
|
28
|
+
- Detect archetypes from tag ratios, average CMC, and color/tribe labels
|
|
29
|
+
- Tag cards using lightweight text/keyword heuristics (threat, interaction, ramp, synergy, tribal)
|
|
30
|
+
- Calculate synergy probabilities for single/pair/triple combos
|
|
31
|
+
- Compare two decks and produce on-play/on-draw matchup insights
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- Ruby 3.0+ (tested on 3.x)
|
|
36
|
+
- No external services required for defaults (bundled Scryfall JSON)
|
|
37
|
+
|
|
5
38
|
## Installation
|
|
6
39
|
|
|
7
40
|
Add this line to your application's Gemfile:
|
|
@@ -16,30 +49,82 @@ And then execute:
|
|
|
16
49
|
bundle install
|
|
17
50
|
```
|
|
18
51
|
|
|
52
|
+
Or install directly:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
gem install cw_card_utils
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quickstart
|
|
59
|
+
|
|
60
|
+
```ruby
|
|
61
|
+
require "cw_card_utils"
|
|
62
|
+
|
|
63
|
+
decklist_a = <<~DECK
|
|
64
|
+
4 Lightning Bolt
|
|
65
|
+
4 Monastery Swiftspear
|
|
66
|
+
20 Mountain
|
|
67
|
+
DECK
|
|
68
|
+
|
|
69
|
+
decklist_b = <<~DECK
|
|
70
|
+
4 Counterspell
|
|
71
|
+
4 Memory Deluge
|
|
72
|
+
4 Supreme Verdict
|
|
73
|
+
24 Island
|
|
74
|
+
DECK
|
|
75
|
+
|
|
76
|
+
a = CwCardUtils::DecklistParser::Parser.new(decklist_a).parse
|
|
77
|
+
b = CwCardUtils::DecklistParser::Parser.new(decklist_b).parse
|
|
78
|
+
|
|
79
|
+
puts a.archetype # => e.g., "Mono-Red Aggro"
|
|
80
|
+
puts a.color_identity_string # => "Red"
|
|
81
|
+
puts a.collapsed_normalized_curve # => { "0-1"=>..., "2"=>..., ... }
|
|
82
|
+
|
|
83
|
+
cmp = CwCardUtils::DeckComparator.new(a, b)
|
|
84
|
+
pp cmp.compare[:on_play] # => win_rate_a, favored, notes, etc.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
New namespace quickstart:
|
|
88
|
+
|
|
89
|
+
```ruby
|
|
90
|
+
require "crackling_wit/card_utils"
|
|
91
|
+
|
|
92
|
+
a = CracklingWit::CardUtils::DecklistParser::Parser.new(decklist_a).parse
|
|
93
|
+
b = CracklingWit::CardUtils::DecklistParser::Parser.new(decklist_b).parse
|
|
94
|
+
|
|
95
|
+
cmp = CracklingWit::CardUtils::DeckComparator.new(a, b)
|
|
96
|
+
pp cmp.compare[:on_play]
|
|
97
|
+
```
|
|
98
|
+
|
|
19
99
|
## Configuration
|
|
20
100
|
|
|
21
101
|
You can configure the card data source used by the library:
|
|
22
102
|
|
|
23
103
|
```ruby
|
|
24
|
-
#
|
|
104
|
+
# Legacy namespace
|
|
25
105
|
CwCardUtils.configure do |config|
|
|
26
106
|
config.card_data_source = MyCustomDataSource.new
|
|
27
107
|
end
|
|
28
108
|
|
|
109
|
+
# New namespace (delegates to the same config under the hood)
|
|
110
|
+
CracklingWit::CardUtils.configure do |config|
|
|
111
|
+
config.card_data_source = MyCustomDataSource.new
|
|
112
|
+
end
|
|
113
|
+
|
|
29
114
|
# Or set it directly
|
|
30
115
|
CwCardUtils.card_data_source = MyCustomDataSource.new
|
|
116
|
+
CracklingWit::CardUtils.card_data_source = MyCustomDataSource.new
|
|
31
117
|
```
|
|
32
118
|
|
|
33
119
|
The default data source is `CwCardUtils::ScryfallCmcData.instance`, which loads card data from a local JSON file.
|
|
34
120
|
|
|
35
121
|
## Usage
|
|
36
122
|
|
|
37
|
-
###
|
|
123
|
+
### Deck Parsing and Formats
|
|
38
124
|
|
|
39
125
|
```ruby
|
|
40
126
|
require 'cw_card_utils'
|
|
41
127
|
|
|
42
|
-
# Parse a decklist
|
|
43
128
|
decklist = <<~DECK
|
|
44
129
|
4 Lightning Bolt
|
|
45
130
|
4 Mountain
|
|
@@ -48,12 +133,57 @@ DECK
|
|
|
48
133
|
|
|
49
134
|
deck = CwCardUtils::DecklistParser::Parser.new(decklist).parse
|
|
50
135
|
|
|
51
|
-
#
|
|
136
|
+
# Common accessors
|
|
52
137
|
puts deck.mainboard_size # => 10
|
|
53
138
|
puts deck.color_identity # => ["R"]
|
|
54
|
-
puts deck.archetype
|
|
139
|
+
puts deck.archetype # => "Mono-Red Aggro" (string label)
|
|
140
|
+
puts deck.format # => :standard, :modern, :commander (heuristic)
|
|
55
141
|
```
|
|
56
142
|
|
|
143
|
+
Parses common formats (MTGA, MTGO, Moxfield). Sideboard sections are detected (e.g., lines starting with "Sideboard").
|
|
144
|
+
|
|
145
|
+
### Curves and Summaries
|
|
146
|
+
|
|
147
|
+
```ruby
|
|
148
|
+
deck.curve # => { 0=>2, 1=>8, 2=>6, 3=>4, ... }
|
|
149
|
+
deck.normalized_curve # => { 1=>0.22, 2=>0.18, ... }
|
|
150
|
+
deck.collapsed_curve # => { "0-1"=>10, "2"=>6, "3"=>4, ... }
|
|
151
|
+
deck.collapsed_normalized_curve
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Archetype Detection and Tags
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
deck.archetype # => "Izzet Control", "Selesnya Midrange", etc.
|
|
158
|
+
deck.main.first.tags # => [:interaction, :draw, :etb, ...]
|
|
159
|
+
deck.color_identity_string# => "Azorius"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Synergy Probabilities
|
|
163
|
+
|
|
164
|
+
```ruby
|
|
165
|
+
sp = CwCardUtils::SynergyProbability.new(deck, deck_size: deck.size)
|
|
166
|
+
sp.prob_single(["Lightning Bolt"], 7) # => Float 0..1
|
|
167
|
+
sp.prob_combo(["Card A", "Card B"], 10) # => Float 0..1
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Deck Comparison (Matchup)
|
|
171
|
+
|
|
172
|
+
```ruby
|
|
173
|
+
cmp = CwCardUtils::DeckComparator.new(deck_a, deck_b)
|
|
174
|
+
pp cmp.compare # => { on_play: {...}, on_draw: {...} }
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Generating API Docs (RDoc)
|
|
178
|
+
|
|
179
|
+
Bilingual (EN/JA) RDoc is embedded in the source. Generate HTML docs:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
rdoc -f darkfish -o doc lib README.md --title "Crackling Wit: Card Utilities" --exclude '\.json$'
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Then open `doc/index.html`.
|
|
186
|
+
|
|
57
187
|
### Custom Data Sources
|
|
58
188
|
|
|
59
189
|
You can implement your own card data source by inheriting from `CwCardUtils::CardDataSource`:
|
|
@@ -76,4 +206,19 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
|
76
206
|
|
|
77
207
|
## Contributing
|
|
78
208
|
|
|
79
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/cracklingwit/cw_card_utils.
|
|
209
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/cracklingwit/cw_card_utils.
|
|
210
|
+
|
|
211
|
+
## Data Sources
|
|
212
|
+
|
|
213
|
+
The default data source for this gem is an extraction from the wonderful [Scryfall Bulk Data][1] set. It is intended to be used only to test the functionality of the gem and serve as a fallback source of data.
|
|
214
|
+
|
|
215
|
+
You should use your own source, preferably backed by a database that conforms to our `card_data_source` API for your own production projects.
|
|
216
|
+
|
|
217
|
+
A huge, huge thank you to the wonderful folks at [Scryfall][2] for the hard work they put into keeping their data accurate, up to date, and free for the community to use. We are not endorsed or supported by [Scryfall][2] in any way.
|
|
218
|
+
|
|
219
|
+
## Fan Content Policy
|
|
220
|
+
|
|
221
|
+
Crackling Wit's Card Utils gem is unofficial Fan Content permitted under the Fan Content Policy. It is not approved/endorsed by Wizards. Portions of the materials used are property of Wizards of the Coast. © Wizards of the Coast LLC.
|
|
222
|
+
|
|
223
|
+
[1]: https://scryfall.com/docs/api/bulk-data
|
|
224
|
+
[2]: https://scryfall.com
|