runeterra_cards 0.4.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 13de26db2b79d60bca9fce39d36d3d82fcaaa19fbcdae3dc2c6f34c785253d91
4
- data.tar.gz: 061a9c9e56f751fc2451166af0e9b27f415c4b9293b1ac1d0dc58df714a46a6b
3
+ metadata.gz: a1e0528d970e63dfad42a4f65e907f76cc966bc5da298de031bb8b0903870ebe
4
+ data.tar.gz: 4546f417aeea04a3dd767d959603670235a8fe0f382e4a6a15a61fe726d09e49
5
5
  SHA512:
6
- metadata.gz: cde13398e27b94c917c74efb2cedf4fa82c3af5b8cc7e2da4a19af959176bf24703574170718d17ace331cf20e23b019001150fdd12a90a81688cd2f17f186c3
7
- data.tar.gz: 18d73970af5591a2f65ccf9ba4739800d1025f042499416ed5e2ccd6b5ad33797c3b4640bd7b89dd99600b1a4f2a3bc0f641be0499d392ad56385ec53318dc22
6
+ metadata.gz: 6fe77c6a6ca5c0f7c40c2f75678737f44ac4a6d3d5f120ffd2b55228462e1ebdb3963a1cdfc965d0569e252c5df7b7b9721f8b52810eb7f5fabb3fd9372719cf
7
+ data.tar.gz: 7686da5bfecde6a4322cff7989f25c3668c776e4185870231f39cfb998ac72c99d44c24d8383234189c6f876cbdd12d4ba283bf049b0e9982815b22fbf4575ea
data/doc/CHANGELOG.md CHANGED
@@ -4,11 +4,44 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
5
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.6.1] - 2022-04-30
8
+ ### Added
9
+
10
+ - Documented which versions of Ruby are officially supported:
11
+ - Ruby: 2.6, 2.7, 3.0, 3.1
12
+ - JRuby: 9.3
13
+ - TruffleRuby: 20, 21, 22
14
+
15
+ ### Fixed
16
+
17
+ - Various scenarios where invalid deck codes would produce unhelpful exceptions now raise a `DeckCodeParseError` instead.
18
+
19
+ ## [0.6.0] - 2021-08-25
20
+ ### Added
21
+ - Support for the Bandle City faction.
22
+ - Support for version 4 deck codes.
23
+
24
+ ## [0.5.0] - 2021-03-05
25
+ ### Added
26
+ - Support for the Shurima faction.
27
+ - Support for version 3 deck codes.
28
+ - A new Card class to represent cards on their own without a count.
29
+ - CardSet#as_cards, which returns all the cards in the set as Cards.
30
+ - CardSet#as_card_codes, which returns all the cards in the set as card codes.
31
+
32
+ ### Removed
33
+ - RuneterraCards.from_card_and_counts method.
34
+ - CardAndCount class (replaced by the new Card class).
35
+ - CardSet#as_card_and_counts (replaced by #as_cards).
36
+
37
+ ### Deprecated
38
+ - CardSet#cards – the signature of this method will be changing in a future version to match #as_cards, migrate to #as_card_codes to keep the current #cards behaviour.
39
+
7
40
  ## [0.4.1] - 2021-02-05
41
+ ### Fixed
8
42
 
9
- Fixed
43
+ - Fixed issue where card numbers > 127 came out extremely wrong, e.g. Aphelios and several other of the new cards ([issue #4](https://github.com/zofrex/runeterra_cards/issues/4)).
10
44
 
11
- - Fixed issue where card numbers > 127 came out extremely wrong, e.g. Aphelios and several other of the new cards ([issue #4](https://github.com/zofrex/runeterra_cards/issues/4))
12
45
  ## [0.4.0] - 2020-12-08
13
46
  ### Added
14
47
  - [`CardMetadata` now has a `#cost` attribute representing the mana cost of a card.](https://github.com/zofrex/runeterra_cards/pull/3) (thanks, [nieszkah](https://github.com/alpm)!) Technically this is backwards-compatibility breaking as it makes a new field in metadata json mandatory.
data/doc/README.md CHANGED
@@ -9,15 +9,23 @@ This library makes it easy to decode Legends of Runeterra deck codes, load Data
9
9
  Add the following to your `Gemfile`:
10
10
 
11
11
  ```
12
- gem 'runeterra_cards', '~> 0.4.1'
12
+ gem 'runeterra_cards', '~> 0.6.1'
13
13
  ```
14
14
 
15
15
  Or, if you're building a Gem, your `.gemspec`:
16
16
 
17
17
  ```
18
- spec.add_dependency 'runeterra_cards', '~> 0.4.1'
18
+ spec.add_dependency 'runeterra_cards', '~> 0.6.1'
19
19
  ```
20
20
 
21
+ ### Ruby version support
22
+
23
+ * Ruby: 2.6, 2.7, 3.0, 3.1
24
+ * JRuby: 9.3 only
25
+ * TruffleRuby: 20, 21, 22
26
+
27
+ Note that only Linux and Windows are included in automated testing, although other platforms are expected to work. Also note that truffleruby compatibility is not tested on Windows.
28
+
21
29
  ## Updates & Versioning
22
30
 
23
31
  This library will conform to [semantic versioning](https://semver.org/) once it hits 1.0. In the meantime, you can rely on the minor version (Y in x.Y.z) being bumped for backwards-incompatible changes.
@@ -1,22 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RuneterraCards
4
- # Represents a card and how many of that card are in a collection.
5
- # @deprecated
6
- class CardAndCount
4
+ # Represents a card.
5
+ #
6
+ # @todo: add getters for set, faction, card number
7
+ class Card
7
8
  # The card code, for example "01DE123"
8
9
  # @return [String]
9
10
  attr_reader :code
10
11
 
11
- # How many of this card are in a collection (between 1-3).
12
- # @return [Fixnum]
13
- attr_reader :count
14
-
15
12
  # @param set [Fixnum]
16
13
  # @param faction_number [Fixnum]
17
14
  # @param card_number [Fixnum]
18
- # @param count [Fixnum]
19
- def initialize(count:, code: nil, set: nil, faction_number: nil, card_number: nil)
15
+ def initialize(code: nil, set: nil, faction_number: nil, card_number: nil)
20
16
  if code
21
17
  raise if set || faction_number || card_number
22
18
 
@@ -27,17 +23,23 @@ module RuneterraCards
27
23
  padded_card_number = format('%<i>03d', i: card_number)
28
24
  @code = "#{padded_set}#{faction}#{padded_card_number}"
29
25
  end
30
- @count = count
31
26
  end
32
27
 
33
- #:nodoc:
28
+ # Returns +true+ if _this_ and _other_ both have the same card code.
29
+ #
30
+ # @param other [Card]
31
+ # @return [Boolean]
34
32
  def eql?(other)
35
- code.eql?(other.code) && count.equal?(other.count)
33
+ code.eql?(other.code)
36
34
  end
37
35
 
38
- #:nodoc:
36
+ # Compute a hash code for this card. Two cards with the same card code will have the same hash code (and will
37
+ # compare using {#eql?}).
38
+ #
39
+ # @see Object#hash.
40
+ # @return [Integer]
39
41
  def hash
40
- [code, count].hash
42
+ code.hash
41
43
  end
42
44
  end
43
45
  end
@@ -6,20 +6,21 @@ module RuneterraCards
6
6
  # Represents a collection of cards.
7
7
  #
8
8
  # @todo The API to this class is very unstable and will change a lot in a coming release.
9
+ # @todo add #== !
9
10
  class CardSet
10
- # @return [Hash<String,Fixnum>]
11
+ # Extract this bitmask so Mutant can't see it, until this fix is released https://github.com/mbj/mutant/pull/1218
12
+ HIGH_BIT = 0b1000_0000
13
+ private_constant :HIGH_BIT
14
+
15
+ # @return [Hash{String => Number}]
16
+ # @deprecated
11
17
  attr_reader :cards
12
18
 
13
- # @param [Hash<String,Fixnum>] cards A Hash of card codes mapping to card counts
19
+ # @param [Hash{String => Number},Enumerable{String => Number}] cards A Hash of card codes mapping to card counts
14
20
  def initialize(cards)
15
21
  @cards = cards
16
22
  end
17
23
 
18
- # @deprecated
19
- def self.from_card_and_counts(set)
20
- new(Hash[set.map { |cac| [cac.code, cac.count] }])
21
- end
22
-
23
24
  # Subtract another {CardSet CardSet} from this one. Items with count 0 are not represented in the returned
24
25
  # {CardSet CardSet}, they are removed altogether.
25
26
  # @param [CardSet] other An object that responds to {#count_for_card_code}
@@ -28,21 +29,28 @@ module RuneterraCards
28
29
  remaining_cards =
29
30
  cards.each_with_object({}) do |(code, count), result|
30
31
  new_count = count - other.count_for_card_code(code)
31
- result[code] = new_count unless new_count.equal?(0)
32
+ result[code] = new_count unless new_count.eql?(0)
32
33
  end
33
34
 
34
35
  CardSet.new(remaining_cards)
35
36
  end
36
37
 
37
- # @return [Enumerator<CardAndCount>]
38
- # @deprecated
39
- def as_card_and_counts
40
- cards.map { |code, count| CardAndCount.new(code: code, count: count) }
38
+ # @return [Enumerable<Card => Number>]
39
+ def as_cards
40
+ cards.transform_keys { |code| Card.new(code: code) }
41
+ end
42
+
43
+ # Return all cards in the card set as a map of card codes to counts.
44
+ # @example
45
+ # set.as_card_codes #=> { '01DE044' => 1, '02NX003' => 2 }
46
+ # @return [Enumerable<String => Number>]
47
+ def as_card_codes
48
+ cards
41
49
  end
42
50
 
43
51
  # Returns how many of the given card are in this CardSet.
44
52
  # @param [String] code Card code, e.g. "01DE031"
45
- # @return [Fixnum] How many of the card are in this CardSet, or 0 if it isn't present.
53
+ # @return [Integer] How many of the card are in this CardSet, or 0 if it isn't present.
46
54
  def count_for_card_code(code)
47
55
  cards[code] || 0
48
56
  end
@@ -60,12 +68,12 @@ module RuneterraCards
60
68
 
61
69
  raise UnrecognizedVersionError.new(SUPPORTED_VERSION, version) unless version <= SUPPORTED_VERSION
62
70
 
63
- raise unless format.equal? 1
71
+ raise unless format.eql? 1
64
72
 
65
- int_array = unpack_uleb128(binary_data[1..])
73
+ int_array = unpack_big_endian_varint(binary_data[1..])
66
74
  cards = assemble_card_list(int_array)
67
75
 
68
- from_card_and_counts(cards)
76
+ new(cards.to_h)
69
77
  end
70
78
 
71
79
  # @param string [String] base32-encoded string
@@ -94,15 +102,16 @@ module RuneterraCards
94
102
  private_class_method :decode_format_and_version
95
103
 
96
104
  # @param [Array<Fixnum>] array
97
- # @return [Array<CardAndCount>]
105
+ # @return [Array<Card>]
98
106
  def self.assemble_card_list(array)
99
107
  3.downto(1).flat_map do |number_of_copies|
100
- set_faction_combination_count = array.shift
108
+ set_faction_combination_count = shift_and_check(array)
101
109
  set_faction_combination_count.times.flat_map do
102
- number_of_cards, set, faction = array.shift(3)
110
+ number_of_cards, set, faction = shift_and_check(array, 3)
103
111
 
104
- array.shift(number_of_cards).map do |card_number|
105
- CardAndCount.new(set: set, faction_number: faction, card_number: card_number, count: number_of_copies)
112
+ shift_and_check(array, number_of_cards).map do |card_number|
113
+ cac = Card.new(set: set, faction_number: faction, card_number: card_number)
114
+ [cac.code, number_of_copies]
106
115
  end
107
116
  end
108
117
  end
@@ -110,10 +119,30 @@ module RuneterraCards
110
119
 
111
120
  private_class_method :assemble_card_list
112
121
 
122
+ # Like Array#shift but checks that the number of items requested was
123
+ # actually retrieved, errors otherwise.
124
+ # @param [Array<T>] array Array to shift one or more values from
125
+ # @param [Integer] count Number of items to shift from the array (default 1)
126
+ # @return [Array<T>,T]
127
+ # @raise [DeckCodeParseError]
128
+ def self.shift_and_check(array, count=nil)
129
+ if count
130
+ raise DeckCodeParseError if array.length < count
131
+
132
+ array.shift(count)
133
+ else
134
+ raise DeckCodeParseError if array.empty?
135
+
136
+ array.shift
137
+ end
138
+ end
139
+
140
+ private_class_method :shift_and_check
141
+
113
142
  # @param [String] binary
114
143
  # @return [Enumerable<Fixnum>]
115
- def self.unpack_uleb128(binary)
116
- binary.each_byte.slice_after { |b| (b & 0b1000_0000).zero? }.map do |int_bytes|
144
+ def self.unpack_big_endian_varint(binary)
145
+ binary.each_byte.slice_after { |b| (b & HIGH_BIT).zero? }.map do |int_bytes|
117
146
  acc = 0
118
147
  int_bytes.each_with_index do |byte, index|
119
148
  acc += (byte & 0b0111_1111) << (7 * index)
@@ -122,6 +151,6 @@ module RuneterraCards
122
151
  end
123
152
  end
124
153
 
125
- private_class_method :unpack_uleb128
154
+ private_class_method :unpack_big_endian_varint
126
155
  end
127
156
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # @todo could be more obvious what's wrong when you call == on the wrong class e.g. a number
3
4
  module RuneterraCards
4
5
  # Represents the cost of a {CardSet}, as wildcards or shards.
5
6
  # To get the cost of a {CardSet} you need to call {Metadata#cost_of}, as rarity (and therefore cost) is a property
@@ -54,10 +55,10 @@ module RuneterraCards
54
55
  # The number of shards needed. I.e. the equivalent amount of shards for all these wildcards.
55
56
  # @return [Fixnum] shards
56
57
  def shards
57
- common * 100 +
58
- rare * 300 +
59
- epic * 1200 +
60
- champion * 3000
58
+ (common * 100) +
59
+ (rare * 300) +
60
+ (epic * 1200) +
61
+ (champion * 3000)
61
62
  end
62
63
 
63
64
  # Whether this Cost is equal to another. Equality means exactly the same number of each wildcard, not just the
@@ -65,10 +66,10 @@ module RuneterraCards
65
66
  # @param [Cost] other an object that response to {#common}, {#rare}, {#epic}, and {#champion}.
66
67
  # @return [Boolean] equal?
67
68
  def ==(other)
68
- common.equal?(other.common) &&
69
- rare.equal?(other.rare) &&
70
- epic.equal?(other.epic) &&
71
- champion.equal?(other.champion)
69
+ common.eql?(other.common) &&
70
+ rare.eql?(other.rare) &&
71
+ epic.eql?(other.epic) &&
72
+ champion.eql?(other.champion)
72
73
  end
73
74
 
74
75
  # Subtracts another Cost from this one. Subtraction is performed by subtracting each wildcard type individually,
@@ -13,7 +13,9 @@ module RuneterraCards
13
13
  4 => 'PZ',
14
14
  5 => 'SI',
15
15
  6 => 'BW',
16
+ 7 => 'SH',
16
17
  9 => 'MT',
18
+ 10 => 'BC',
17
19
  }.freeze
18
20
  public_constant :FACTION_IDENTIFIERS_FROM_INT
19
21
 
@@ -29,7 +31,9 @@ module RuneterraCards
29
31
  'PZ' => 4,
30
32
  'SI' => 5,
31
33
  'BW' => 6,
34
+ 'SH' => 7,
32
35
  'MT' => 9,
36
+ 'BC' => 10,
33
37
  }.freeze
34
38
  public_constant :FACTION_INTS_FROM_IDENTIFIER
35
39
  end
@@ -33,7 +33,7 @@ module RuneterraCards
33
33
  data = JSON.parse(file)
34
34
  data.each do |card_data|
35
35
  card = CardMetadata.new(card_data)
36
- @cards[card.card_code] = card
36
+ @cards[card.card_code] = card # TODO: warn or error if there are duplicate card codes!
37
37
  end
38
38
  end
39
39
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RuneterraCards
4
4
  # The version of this library
5
- VERSION = '0.4.1'
5
+ VERSION = '0.6.1'
6
6
  public_constant :VERSION
7
7
  end
@@ -3,7 +3,7 @@
3
3
  require 'runeterra_cards/version'
4
4
  require 'runeterra_cards/errors'
5
5
  require 'runeterra_cards/factions'
6
- require 'runeterra_cards/card_and_count'
6
+ require 'runeterra_cards/card'
7
7
  require 'runeterra_cards/card_metadata'
8
8
  require 'runeterra_cards/metadata'
9
9
  require 'runeterra_cards/card_set'
@@ -16,6 +16,6 @@ require 'runeterra_cards/cost'
16
16
  # You might also want to check out the {file:doc/README.md} and the {file:doc/CHANGELOG.md}.
17
17
  module RuneterraCards
18
18
  # The version of deck encoding supported
19
- SUPPORTED_VERSION = 2
19
+ SUPPORTED_VERSION = 4
20
20
  public_constant :SUPPORTED_VERSION
21
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runeterra_cards
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James "zofrex" Sanderson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-05 00:00:00.000000000 Z
11
+ date: 2022-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
@@ -24,34 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.2
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '2.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '2.0'
41
- - !ruby/object:Gem::Dependency
42
- name: deep-cover
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '0.7'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '0.7'
55
27
  - !ruby/object:Gem::Dependency
56
28
  name: minitest
57
29
  requirement: !ruby/object:Gem::Requirement
@@ -122,6 +94,20 @@ dependencies:
122
94
  - - "~>"
123
95
  - !ruby/object:Gem::Version
124
96
  version: 13.0.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: redcarpet
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 3.5.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 3.5.1
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: rubocop
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +128,14 @@ dependencies:
142
128
  requirements:
143
129
  - - "~>"
144
130
  - !ruby/object:Gem::Version
145
- version: 0.10.1
131
+ version: 0.15.2
146
132
  type: :development
147
133
  prerelease: false
148
134
  version_requirements: !ruby/object:Gem::Requirement
149
135
  requirements:
150
136
  - - "~>"
151
137
  - !ruby/object:Gem::Version
152
- version: 0.10.1
138
+ version: 0.15.2
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: rubocop-packaging
155
141
  requirement: !ruby/object:Gem::Requirement
@@ -204,7 +190,7 @@ files:
204
190
  - doc/CHANGELOG.md
205
191
  - doc/README.md
206
192
  - lib/runeterra_cards.rb
207
- - lib/runeterra_cards/card_and_count.rb
193
+ - lib/runeterra_cards/card.rb
208
194
  - lib/runeterra_cards/card_metadata.rb
209
195
  - lib/runeterra_cards/card_set.rb
210
196
  - lib/runeterra_cards/cost.rb
@@ -212,7 +198,7 @@ files:
212
198
  - lib/runeterra_cards/factions.rb
213
199
  - lib/runeterra_cards/metadata.rb
214
200
  - lib/runeterra_cards/version.rb
215
- homepage:
201
+ homepage:
216
202
  licenses:
217
203
  - MIT
218
204
  metadata:
@@ -220,7 +206,8 @@ metadata:
220
206
  changelog_uri: https://www.rubydoc.info/gems/runeterra_cards/file/doc/CHANGELOG.md
221
207
  source_code_uri: https://github.com/zofrex/runeterra_cards
222
208
  documentation_uri: https://www.rubydoc.info/gems/runeterra_cards/
223
- post_install_message:
209
+ rubygems_mfa_required: 'true'
210
+ post_install_message:
224
211
  rdoc_options: []
225
212
  require_paths:
226
213
  - lib
@@ -235,8 +222,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
222
  - !ruby/object:Gem::Version
236
223
  version: '0'
237
224
  requirements: []
238
- rubygems_version: 3.1.4
239
- signing_key:
225
+ rubygems_version: 3.1.6
226
+ signing_key:
240
227
  specification_version: 4
241
228
  summary: Legends of Runeterra deck code decoder & Data Dragon card data loader.
242
229
  test_files: []