Skip to content

Instantly share code, notes, and snippets.

@MintPaw
Created August 14, 2016 09:20
Show Gist options
  • Save MintPaw/642a45b6288c6abe142f9f0f64f97c1e to your computer and use it in GitHub Desktop.
Save MintPaw/642a45b6288c6abe142f9f0f64f97c1e to your computer and use it in GitHub Desktop.
Attempts to guess your opponents HS deck.
from bs4 import BeautifulSoup
from urllib.request import urlopen
import re
import pickle
import sys
from colorama import Fore, Back, Style, init
init()
decks = list()
def parseDeckPage(url):
soup = BeautifulSoup(urlopen(url).read(), "html.parser")
deckLinks = list()
for a in soup.find_all("a"):
link = a.get("href")
if link is None: continue
if "decks/" in link:
deckLinks.append("http://www.hearthpwn.com" + link)
return deckLinks
def parseDeck(url):
soup = BeautifulSoup(urlopen(url).read(), "html.parser")
deck = dict()
deck["name"] = soup.find("title").contents[0][0:-21]
deck["cards"] = list()
print("Parsing: " + deck["name"])
for a in soup.find_all("a"):
link = a.get("href")
count = a.get("data-count")
if link is not None and count is not None:
if "cards/" in link:
deck["cards"].append(a.contents[0].strip())
if count == "2": deck["cards"].append(a.contents[0].strip())
return deck
def addDeck(newDeck):
global decks
add = True
for d in decks:
if d["name"] == newDeck["name"]:
add = False
break
if add: decks.append(newDeck)
def readdb():
global decks
f = open("db", "rb")
decks = pickle.load(f)
f.close()
def writedb():
global decks
f = open("db", "wb")
pickle.dump(decks, f)
f.close()
def resetdb():
global decks
decks = list()
writedb()
updatedb()
def addpagedb(url):
links = parseDeckPage(url)
for l in links:
newDeck = parseDeck(l)
addDeck(newDeck)
writedb()
def updatedb():
readdb()
# Top 3 pages
addpagedb("http://www.hearthpwn.com/decks")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&page=2")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&page=3")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=4")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=8")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=32")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=64")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=128")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=256")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=512")
addpagedb("http://www.hearthpwn.com/decks?filter-deck-tag=1&filter-class=1024")
if sys.argv[-1] == "--update":
resetdb()
readdb()
# updatedb()
# addpagedb("http://www.hearthpwn.com/decks?filter-search=basic&filter-deck-tag=1&filter-class=16") # Basic Mage
# addpagedb("http://www.hearthpwn.com/decks?filter-search=basic&filter-deck-tag=1&filter-class=1024") # Basic Warrior
print(str(len(decks)) + " Decks loaded.\n")
f = open("Hearthstone_Data/output_log.txt", "r")
allEnemyPlays = list()
while True:
line = f.readline()
if "START waiting for zone FRIENDLY PLAY (Hero)" in line: allEnemyPlays = list()
if line == "": break
if line.find("OPPOSING HAND ->") != -1:
if "name=" not in line: continue
nameStart = line.find("name=")+5
nameEnd = line.find("id=", nameStart)-1
name = line[nameStart:nameEnd]
allEnemyPlays.append(name)
stats = list()
for deck in decks:
matchingCards = 0
for deckCard in deck["cards"]:
for enemyCard in allEnemyPlays:
if (enemyCard == deckCard):
matchingCards += 1
continue
stats.append((deck, matchingCards))
stats.sort(key=lambda s: s[1], reverse=True)
def printDeck(deck, plays, matching):
print(str(round(matching/2/30*100)) + "% - " + deck["name"])
prevCardName = None
for i in range(0, len(deck["cards"])):
cardName = deck["cards"][i]
nextCardName = None
if (len(deck["cards"]) > i+1): nextCardName = deck["cards"][i+1]
if prevCardName == cardName: continue
theyHave = 1
if cardName == nextCardName: theyHave = 2
theyUsed = plays.count(cardName)
mainInRed = (theyUsed == 1 and theyHave == 1) or (theyUsed == 2 and theyHave == 2)
twoInRed = theyUsed == 1 or mainInRed
print(Fore.RESET, end="")
if mainInRed: print(Fore.RED, end="")
print(cardName, end="")
print(Fore.RESET, end="")
if theyHave == 2:
if twoInRed: print(Fore.RED, end="")
print(" x2")
print(Fore.RESET, end="")
else:
print("")
prevCardName = cardName
for i in range(0, 1):
printDeck(stats[i][0], allEnemyPlays, stats[i][1])
print("\n")
print("Enemy plays: " + str(allEnemyPlays))
f.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment