class RuneterraCards::CardSet
Represents a collection of cards.
@todo The API to this class is very unstable and will change a lot in a coming release. @todo add #== !
Constants
- HIGH_BIT
Extract this bitmask so Mutant can't see it, until this fix is released github.com/mbj/mutant/pull/1218
Attributes
@return [Hash{String => Number}] @deprecated
Public Class Methods
Parse a Deck Code. @param deck_code [String] @raise [Base32Error] if the deck code cannot be Base32 decoded. @raise [UnrecognizedVersionError] if the deck code's version is not supported by this library
(see {SUPPORTED_VERSION}).
@raise [EmptyInputError] if the deck code is an empty string. @return [CardSet]
# File lib/runeterra_cards/card_set.rb, line 65 def self.from_deck_code(deck_code) binary_data = decode_base32(deck_code) format, version = decode_format_and_version(binary_data[0]) raise UnrecognizedVersionError.new(SUPPORTED_VERSION, version) unless version <= SUPPORTED_VERSION raise unless format.equal? 1 int_array = unpack_big_endian_varint(binary_data[1..]) cards = assemble_card_list(int_array) new(cards.to_h) end
@param [Hash{String => Number},Enumerable{String => Number}] cards A Hash of card codes mapping to card counts
# File lib/runeterra_cards/card_set.rb, line 20 def initialize(cards) @cards = cards end
Private Class Methods
@param [Array<Fixnum>] array @return [Array<Card>]
# File lib/runeterra_cards/card_set.rb, line 106 def self.assemble_card_list(array) 3.downto(1).flat_map do |number_of_copies| set_faction_combination_count = array.shift set_faction_combination_count.times.flat_map do number_of_cards, set, faction = array.shift(3) array.shift(number_of_cards).map do |card_number| cac = Card.new(set: set, faction_number: faction, card_number: card_number) [cac.code, number_of_copies] end end end end
@param string [String] base32-encoded string @return [String] binary data
# File lib/runeterra_cards/card_set.rb, line 81 def self.decode_base32(string) raise EmptyInputError if string.empty? begin Base32.decode(string) rescue StandardError raise Base32Error end end
@param byte [String] a single byte @return [FixNum] format and version, in that order
# File lib/runeterra_cards/card_set.rb, line 95 def self.decode_format_and_version(byte) format_and_version = byte.unpack1('C') format = format_and_version >> 4 version = format_and_version & 0xF [format, version] end
@param [String] binary @return [Enumerable<Fixnum>]
# File lib/runeterra_cards/card_set.rb, line 124 def self.unpack_big_endian_varint(binary) binary.each_byte.slice_after { |b| (b & HIGH_BIT).zero? }.map do |int_bytes| acc = 0 int_bytes.each_with_index do |byte, index| acc += (byte & 0b0111_1111) << (7 * index) end acc end end
Public Instance Methods
Subtract another {CardSet CardSet} from this one. Items with count 0 are not represented in the returned {CardSet CardSet}, they are removed altogether. @param [CardSet] other An object that responds to {#count_for_card_code} @return [CardSet]
# File lib/runeterra_cards/card_set.rb, line 28 def -(other) remaining_cards = cards.each_with_object({}) do |(code, count), result| new_count = count - other.count_for_card_code(code) result[code] = new_count unless new_count.equal?(0) end CardSet.new(remaining_cards) end
Return all cards in the card set as a map of card codes to counts. @example
set.as_card_codes #=> { '01DE044' => 1, '02NX003' => 2 }
@return [Enumerable<String => Number>]
# File lib/runeterra_cards/card_set.rb, line 47 def as_card_codes cards end
@return [Enumerable<Card => Number>]
# File lib/runeterra_cards/card_set.rb, line 39 def as_cards cards.transform_keys { |code| Card.new(code: code) } end