cw_card_utils 0.1.5 → 0.1.6
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/lib/cw_card_utils/deck_comparator.rb +108 -0
- data/lib/cw_card_utils/version.rb +1 -1
- data/lib/cw_card_utils.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a8d8eb329c364d67fedf00a49698b9f145f06b6e08f7effae3eb92fb5c22d244
|
4
|
+
data.tar.gz: 8cc571695d9d0b3b07c2da11abffe0a047d08591c8b490fbaffdf88a21226fe5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38000b90cc9c72b84efdf4c8eb892d20748fe4050af8874c99847a9e4b572b4fcbe573cfba49a964fcda60b8d177bbf9195f3f9b89c9f92c4f08d716d18c41ca
|
7
|
+
data.tar.gz: 9f62737b9b7fde768f4f990b0367b94b6e86d8bcab4a4925e1c91a8c6abfaae71a2ac56bd8ecfe5ffb74ec956010ad3c6d8658e102c032eeb3514e8488e0e79f
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CwCardUtils
|
4
|
+
|
5
|
+
class DeckComparator
|
6
|
+
attr_reader :deck_a, :deck_b, :analysis
|
7
|
+
|
8
|
+
def initialize(deck_a, deck_b)
|
9
|
+
@deck_a = deck_a
|
10
|
+
@deck_b = deck_b
|
11
|
+
@analysis = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def compare
|
15
|
+
a_info = analyze_deck(deck_a)
|
16
|
+
b_info = analyze_deck(deck_b)
|
17
|
+
|
18
|
+
matchup = {
|
19
|
+
archetype_a: a_info[:archetype],
|
20
|
+
archetype_b: b_info[:archetype],
|
21
|
+
likely_winner: predict_matchup(a_info, b_info),
|
22
|
+
interaction_overlap: compare_interaction_density(a_info, b_info),
|
23
|
+
notes: generate_notes(a_info, b_info),
|
24
|
+
}
|
25
|
+
|
26
|
+
@analysis = matchup
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def analyze_deck(deck)
|
32
|
+
detector = ArchetypeDetector.new(deck)
|
33
|
+
archetype = detector.detect
|
34
|
+
|
35
|
+
curve = deck.normalized_curve
|
36
|
+
|
37
|
+
early = ((curve[0] || 0) + (curve[1] || 0)).round(2)
|
38
|
+
mid = ((curve[2] || 0) + (curve[3] || 0)).round(2)
|
39
|
+
late = ((curve[4] || 0) + (curve[5] || 0) + (curve[6] || 0) + (curve[7] || 0)).round(2)
|
40
|
+
|
41
|
+
{
|
42
|
+
archetype: archetype,
|
43
|
+
color: detector.colors,
|
44
|
+
early_curve: early,
|
45
|
+
mid_curve: mid,
|
46
|
+
late_curve: late,
|
47
|
+
tag_ratios: detector.tag_ratios,
|
48
|
+
tag_counts: detector.tag_counts,
|
49
|
+
tribe: deck.tribe,
|
50
|
+
format: deck.format,
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
def predict_matchup(a, b)
|
55
|
+
return "Deck A (Aggro)" if is_aggro?(a) && is_control?(b)
|
56
|
+
return "Deck B (Aggro)" if is_aggro?(b) && is_control?(a)
|
57
|
+
return "Deck A (Faster curve)" if a[:early_curve] > b[:early_curve] + 0.15
|
58
|
+
return "Deck B (Faster curve)" if b[:early_curve] > a[:early_curve] + 0.15
|
59
|
+
"Even Matchup"
|
60
|
+
end
|
61
|
+
|
62
|
+
def is_aggro?(info)
|
63
|
+
info[:archetype].downcase.include?("aggro") || info[:early_curve] > 0.5
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_control?(info)
|
67
|
+
info[:archetype].downcase.include?("control") || info[:late_curve] > 0.4
|
68
|
+
end
|
69
|
+
|
70
|
+
def compare_interaction_density(a, b)
|
71
|
+
a_interact = a[:tag_ratios][:interaction].to_f.round(2)
|
72
|
+
b_interact = b[:tag_ratios][:interaction].to_f.round(2)
|
73
|
+
|
74
|
+
if (a_interact - b_interact).abs < 0.05
|
75
|
+
"Similar density"
|
76
|
+
elsif a_interact > b_interact
|
77
|
+
"Deck A has more removal"
|
78
|
+
else
|
79
|
+
"Deck B has more removal"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def generate_notes(a, b)
|
84
|
+
notes = []
|
85
|
+
|
86
|
+
if a[:tribe] && b[:tribe]
|
87
|
+
notes << "Both decks are tribal: #{a[:tribe].capitalize} vs #{b[:tribe].capitalize}"
|
88
|
+
end
|
89
|
+
|
90
|
+
if a[:format] != b[:format]
|
91
|
+
notes << "Decks are from different formats: #{a[:format]} vs #{b[:format]}"
|
92
|
+
end
|
93
|
+
|
94
|
+
if a[:color] == b[:color]
|
95
|
+
notes << "Color overlap may result in symmetrical strategies"
|
96
|
+
end
|
97
|
+
|
98
|
+
notes << "Deck A has a stronger early game" if a[:early_curve] > b[:early_curve] + 0.2
|
99
|
+
notes << "Deck B has a stronger early game" if b[:early_curve] > a[:early_curve] + 0.2
|
100
|
+
|
101
|
+
notes << "Deck A has more combo elements" if a[:tag_ratios][:combo_piece].to_f > 0.1
|
102
|
+
notes << "Deck B has more combo elements" if b[:tag_ratios][:combo_piece].to_f > 0.1
|
103
|
+
|
104
|
+
notes
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
data/lib/cw_card_utils.rb
CHANGED
@@ -4,6 +4,7 @@ require_relative "cw_card_utils/version"
|
|
4
4
|
require_relative "cw_card_utils/curve_calculator"
|
5
5
|
require_relative "cw_card_utils/decklist_parser"
|
6
6
|
require_relative "cw_card_utils/scryfall_cmc_data"
|
7
|
+
require_relative "cw_card_utils/deck_comparator"
|
7
8
|
|
8
9
|
module CwCardUtils
|
9
10
|
class Error < StandardError; end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cw_card_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Stenhouse
|
@@ -38,6 +38,7 @@ files:
|
|
38
38
|
- data/scryfall.cards.cmc.json
|
39
39
|
- lib/cw_card_utils.rb
|
40
40
|
- lib/cw_card_utils/curve_calculator.rb
|
41
|
+
- lib/cw_card_utils/deck_comparator.rb
|
41
42
|
- lib/cw_card_utils/decklist_parser.rb
|
42
43
|
- lib/cw_card_utils/scryfall_cmc_data.rb
|
43
44
|
- lib/cw_card_utils/version.rb
|