class Deckstrings::Deck

A Hearthstone deck with metadata that is convertible to and from a deckstring. @see Deck.decode @see Deck.encode

Attributes

cards[R]

The cards contained in this deck. @return [Hash{Card => Integer}] A Hash from {Card} to its instance count in the deck.

format[R]

@return [Format] Format for this deck.

heroes[R]

The heroes associated with this deck. @return [Array<Hero>] Typically, this array will contain one element.

Public Class Methods

decode(deckstring) click to toggle source

Decodes a Hearthstone deckstring into a {Deck} with basic hero and card metadata.

This method validates the well-formedness of the deckstring, the embedded version, the format, card counts, and each hero/card ID.

All IDs refer to unique Hearthstone DBF IDs which can be used in conjunction with [HearthstoneJSON metadata](hearthstonejson.com/). @example

deck = Deckstrings::Deck.decode('AAEBAf0GAA/yAaIC3ALgBPcE+wWKBs4H2QexCMII2Q31DfoN9g4A')

@example

deck = Deckstrings::Deck.decode('AAECAZICCPIF+Az5DK6rAuC7ApS9AsnHApnTAgtAX/4BxAbkCLS7Asu8As+8At2+AqDNAofOAgA=')

@param deckstring [String] Base64-encoded Hearthstone deckstring. @raise [FormatError] If the deckstring is malformed or contains invalid deck data. @return [Deck] Decoded Hearthstone deck. @see Deckstrings.decode @see Deck.encode @see hearthstonejson.com/ HearthstoneJSON

# File lib/deckstrings/deckstrings.rb, line 340
def self.decode(deckstring)
  parts = Deckstrings::decode(deckstring)
  begin
    Deck.new(parts)
  rescue ArgumentError => e
    raise FormatError, e.to_s
  end
end
encode(format:, heroes:, cards:) click to toggle source

Encodes a Hearthstone deck as a compact deckstring.

This method validates card counts, format, and each hero/card ID.

All IDs refer to unique Hearthstone DBF IDs which can be seen in [HearthstoneJSON metadata](hearthstonejson.com/). @example

deckstring = Deckstrings::Deck.encode(format: 2, heroes: [637], cards: { 1004 => 2, 315 => 2 })

@example

deckstring = Deckstrings::Deck.encode(
  format: Deckstrings::Format.standard,
  heroes: [Deckstrings::Hero.mage],
  cards: { 1004 => 2, 315 => 2 }
)

@param format [Integer, Deckstrings::Format] Format for this deck: wild or standard. @param heroes [Array<Integer, Deckstrings::Hero>] Heroes for this deck. Multiple heroes are supported, but typically

this array will contain one element.

@param cards [Hash{Integer, Deckstrings::Card => Integer}] Cards in the deck. A Hash from card ID to its instance count in the deck. @raise [FormatError] If any card counts are less than 1, or if any IDs do not refer to valid Hearthstone entities. @return [String] Base64-encoded compact byte string representing the deck. @see .encode @see Deck.decode @see hearthstonejson.com/ HearthstoneJSON

# File lib/deckstrings/deckstrings.rb, line 371
def self.encode(format:, heroes:, cards:)
  begin
    Deck.new(format: format, heroes: heroes, cards: cards).deckstring
  rescue ArgumentError => e
    raise FormatError, e.to_s
  end
end
new(format:, heroes:, cards:) click to toggle source

Create a new deck from component parts. @param format [Integer, Deckstrings::Format] Format for this deck: wild or standard. @param heroes [Array<Integer, Deckstrings::Hero>] Heroes for this deck. Multiple heroes are supported, but typically

this array will contain one element.

@param cards [Hash{Integer, Deckstrings::Card => Integer}] Cards in the deck. A Hash from card ID to its instance count in the deck. @raise [ArgumentError] If format, heroes, or any cards are unknown.

# File lib/deckstrings/deckstrings.rb, line 290
def initialize(format:, heroes:, cards:)
  @format = Format.parse(format) if !format.is_a?(Format)
  raise ArgumentError, "Unknown format: #{format}." if !@format

  @heroes = heroes.map do |id|
    hero = Database.instance.heroes[id]
    raise ArgumentError, "Unknown hero: #{id}." if hero.nil?
    Hero.new(id, hero['name'], hero['class'])
  end

  @cards = cards.map do |id, count|
    card = Database.instance.cards[id]
    raise ArgumentError, "Unknown card: #{id}." if card.nil?
    [Card.new(id, card['name'], card['cost']), count]
  end.sort_by { |card, _| card.cost }.to_h
end

Public Instance Methods

deckstring() click to toggle source

Encoded deckstring for this deck. @return [String] Base64-encoded compact byte string representing the deck. @see Deckstrings.encode @see .encode

# File lib/deckstrings/deckstrings.rb, line 320
def deckstring
  return Deckstrings::encode(self.raw)
end
raw() click to toggle source

Raw deck details. @return [{ format: Integer, heroes: Array<Integer>, cards: Hash{Integer => Integer} }] See {Deckstrings.decode} for details. @see Deckstrings.decode

# File lib/deckstrings/deckstrings.rb, line 310
def raw
  heroes = @heroes.map(&:id)
  cards = @cards.map { |card, count| [card.id, count] }.to_h
  { format: @format.value, heroes: heroes, cards: cards }
end
standard?() click to toggle source

@return [Boolean] `true` if the deck is Standard format, `false` otherwise. @see wild?

# File lib/deckstrings/deckstrings.rb, line 387
def standard?
  format.standard?
end
to_s() click to toggle source

Pretty-printed deck listing. @example

puts Deckstrings::Deck.decode('AAECAZICCPIF+Az5DK6rAuC7ApS9AsnHApnTAgtAX/4BxAbkCLS7Asu8As+8At2+AqDNAofOAgA=')

@example

Format: Standard
Class: Druid
Hero: Malfurion Stormrage

2× Innervate
2× Jade Idol
2× Wild Growth
2× Wrath
2× Jade Blossom
2× Swipe
2× Jade Spirit
1× Fandral Staghelm
1× Spellbreaker
2× Nourish
1× Big Game Hunter
2× Spreading Plague
1× The Black Knight
1× Aya Blackpaw
2× Jade Behemoth
1× Malfurion the Pestilent
1× Primordial Drake
2× Ultimate Infestation
1× Kun the Forgotten King

@return [String] A pretty-printed listing of deck details.

# File lib/deckstrings/deckstrings.rb, line 419
def to_s
  listing = "Format: #{format}"

  hero = @heroes.first
  if hero
    listing += "\nClass: #{hero.hero_class}\nHero: #{hero.name}"
  end

  if !cards.empty?
    listing += "\n\n" + cards.map { |card, count| "#{count}× #{card.name}" }.join("\n")
  end

  listing
end
wild?() click to toggle source

@return [Boolean] `true` if the deck is Wild format, `false` otherwise. @see standard?

# File lib/deckstrings/deckstrings.rb, line 381
def wild?
  format.wild?
end