Class: Deckstrings::Deck

Inherits:
Object
  • Object
show all
Defined in:
lib/deckstrings/deckstrings.rb

Overview

A Hearthstone deck with metadata that is convertible to and from a deckstring.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(format:, heroes:, cards:) ⇒ Deck

Create a new deck from component parts.

Parameters:

  • format (Integer, Deckstrings::Format)

    Format for this deck: wild or standard.

  • heroes (Array<Integer, Deckstrings::Hero>)

    Heroes for this deck. Multiple heroes are supported, but typically this array will contain one element.

  • cards (Hash{Integer, Deckstrings::Card => Integer})

    Cards in the deck. A Hash from card ID to its instance count in the deck.

Raises:

  • (ArgumentError)

    If format, heroes, or any cards are unknown.



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# 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

Instance Attribute Details

#cardsHash{Card => Integer} (readonly)

The cards contained in this deck.

Returns:

  • (Hash{Card => Integer})

    A Hash from Card to its instance count in the deck.



443
444
445
# File 'lib/deckstrings/deckstrings.rb', line 443

def cards
  @cards
end

#formatFormat (readonly)

Returns Format for this deck.

Returns:

  • (Format)

    Format for this deck.



435
436
437
# File 'lib/deckstrings/deckstrings.rb', line 435

def format
  @format
end

#heroesArray<Hero> (readonly)

The heroes associated with this deck.

Returns:

  • (Array<Hero>)

    Typically, this array will contain one element.



439
440
441
# File 'lib/deckstrings/deckstrings.rb', line 439

def heroes
  @heroes
end

Class Method Details

.decode(deckstring) ⇒ Deck

Decodes a Hearthstone deckstring into a Deckstrings::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.

Examples:

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

Parameters:

  • deckstring (String)

    Base64-encoded Hearthstone deckstring.

Returns:

  • (Deck)

    Decoded Hearthstone deck.

Raises:

  • (FormatError)

    If the deckstring is malformed or contains invalid deck data.

See Also:



340
341
342
343
344
345
346
347
# 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:) ⇒ String

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.

Examples:

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

Parameters:

  • format (Integer, Deckstrings::Format)

    Format for this deck: wild or standard.

  • heroes (Array<Integer, Deckstrings::Hero>)

    Heroes for this deck. Multiple heroes are supported, but typically this array will contain one element.

  • cards (Hash{Integer, Deckstrings::Card => Integer})

    Cards in the deck. A Hash from card ID to its instance count in the deck.

Returns:

  • (String)

    Base64-encoded compact byte string representing the deck.

Raises:

  • (FormatError)

    If any card counts are less than 1, or if any IDs do not refer to valid Hearthstone entities.

See Also:



371
372
373
374
375
376
377
# 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

Instance Method Details

#deckstringString

Encoded deckstring for this deck.

Returns:

  • (String)

    Base64-encoded compact byte string representing the deck.

See Also:



320
321
322
# File 'lib/deckstrings/deckstrings.rb', line 320

def deckstring
  return Deckstrings::encode(self.raw)
end

#raw{ format: Integer, heroes: Array<Integer>, cards: Hash{Integer => Integer} }

Raw deck details.

Returns:

  • ({ format: Integer, heroes: Array<Integer>, cards: Hash{Integer => Integer} })

    See Deckstrings.decode for details.

See Also:



310
311
312
313
314
# 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?Boolean

Returns true if the deck is Standard format, false otherwise.

Returns:

  • (Boolean)

    true if the deck is Standard format, false otherwise.

See Also:



387
388
389
# File 'lib/deckstrings/deckstrings.rb', line 387

def standard?
  format.standard?
end

#to_sString

Pretty-printed deck listing.

Examples:

puts Deckstrings::Deck.decode('AAECAZICCPIF+Az5DK6rAuC7ApS9AsnHApnTAgtAX/4BxAbkCLS7Asu8As+8At2+AqDNAofOAgA=')
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

Returns:

  • (String)

    A pretty-printed listing of deck details.



419
420
421
422
423
424
425
426
427
428
429
430
431
432
# 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?Boolean

Returns true if the deck is Wild format, false otherwise.

Returns:

  • (Boolean)

    true if the deck is Wild format, false otherwise.

See Also:



381
382
383
# File 'lib/deckstrings/deckstrings.rb', line 381

def wild?
  format.wild?
end