![]() |
Hearthstone screenshot: our character is at the bottom, and the opponent is at the top. |
Last night I discovered that Hearthstone can be configured to create a log of every game-state change, which is awesome. People have used this information to create "deck trackers," which keep track of which cards you've drawn, so you know what's left in your deck. This is just scratching the surface, though. In principle, one could use a library of these log files to put together a sophisticated analysis of what kinds of decks people are playing, what cards are likely to appear together in a deck, and even list the most likely plays of an opponent next turn.
To start, I wanted to look at the log file and see what I could parse. Here is a link to a github repo where I've included a log file from an example game, and some Python code that reads the file and creates a DataFrame object with a list of all of the entities in the game (and entity can be a card, player, hero power, enchantment, and probably some other stuff). If at any time in the game the entity name is revealed, I update the DataFrame to include its name. The output looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Name | |
Entity ID | |
1 NaN | |
2 NaN | |
3 NaN | |
4 Anduin Wrynn | |
5 Lesser Heal | |
6 Twilight Guardian | |
. | |
. | |
. | |
65 NaN | |
66 Fireball | |
67 NaN | |
68 The Coin | |
69 Twilight Endurance | |
70 Dragon Blood | |
. | |
. | |
. |
There's also a function that simply lists all of the cards I draw in the game, and that my opponent plays at some point, whose output looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Holy Nova | |
Blackwing Technician | |
Dark Cultist | |
Blackwing Corruptor | |
The Coin | |
. | |
. | |
. | |
Power Word: Shield | |
Blackwing Corruptor | |
Blackwing Corruptor | |
Bloodfen Raptor | |
Sen'jin Shieldmasta | |
Murloc Raider | |
Raid Leader | |
Wolfrider | |
Nightblade | |
Oasis Snapjaw |
where the first and second blocks are my cards and my opponent's cards, respectively. The next step is to integrate more card information into the DataFrame. I'm using regular expressions to do the parsing, so it's slow work. I'm not worried about putting a front end on this any time soon.