Created
August 14, 2016 09:20
-
-
Save MintPaw/642a45b6288c6abe142f9f0f64f97c1e to your computer and use it in GitHub Desktop.
Attempts to guess your opponents HS deck.
This file contains hidden or 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
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