Skip to content

Instantly share code, notes, and snippets.

@stravant
Created February 14, 2022 05:32
Show Gist options
  • Save stravant/389b6c5810581c2c279b15909e0d0635 to your computer and use it in GitHub Desktop.
Save stravant/389b6c5810581c2c279b15909e0d0635 to your computer and use it in GitHub Desktop.
Fetch info from masterduelmeta.com to compute relative value of SRs / URs.
import requests
import json
import urllib.parse
import re
top_decks_url = "https://www.masterduelmeta.com/api/v1/top-decks?limit=0"
included_cards = {
"Lightning Storm": 1,
"Solemn Judgment": 1,
"Ash Blossom & Joyous Spring": 1,
"Reinforcement of the Army": 1,
"Raigeki": 1,
"Unexpected Dai": 3,
"Blue-Eyes White Dragon": 2,
"Five-Headed Dragon": 2,
"Junk Synchron": 3,
"Junk Warrior": 1,
"Colossal Fighter": 1,
"Rasterliger": 1,
"Decode Talker": 1,
"Link Spider": 1,
"LANphorhynchus": 1,
"Shiranui Shogunsaga": 3,
"Shiranui Style Swallow's Slash": 3,
"Shiranui Solitaire": 3,
"Shiranui Spectralsword": 3,
"Digital Bug Rhinosebus": 3,
"Gladiator Beast Gaiodiaz": 3,
"Gladiator Beast Andabata": 3,
"Gladiator Beast Tamer Editor": 3,
"Gem-Knight Aquamarine": 3,
"Gem-Knight Fusion": 3,
}
def fetch_top_decks():
top_decks_result = requests.get(top_decks_url)
top_decks = top_decks_result.content.decode("utf-8")
with open("top_decks.json", "w", encoding="utf-8") as f:
f.write(top_decks)
return top_decks
def tally_card(card_js, count_per_card, max_per_card):
name = card_js["card"]["name"]
count = card_js["amount"]
if name in included_cards:
count = max(0, count - included_cards[name])
if name in max_per_card:
max_per_card[name] = max(max_per_card[name], count)
else:
max_per_card[name] = count
if name in count_per_card:
count_per_card[name] += count
else:
count_per_card[name] = count
def tally_deck(deck_js, count_per_card, max_per_card, count_per_deck):
deck_type = deck_js["deckType"]["name"]
if deck_type in count_per_deck:
count_per_deck[deck_type] += 1
else:
count_per_deck[deck_type] = 1
for main_card in deck_js["main"]:
tally_card(main_card, count_per_card, max_per_card)
for extra_card in deck_js["extra"]:
tally_card(extra_card, count_per_card, max_per_card)
def transform_and_write_top_decks_json(js):
count_per_card = {}
count_per_deck = {}
max_per_card = {}
for deck_js in js:
tally_deck(deck_js, count_per_card, max_per_card, count_per_deck)
with open("top_decks_processed.json", "w", encoding="utf-8") as fout:
fout.write(json.dumps({
"total": len(js),
"count_per_deck": count_per_deck,
"count_per_card": count_per_card,
"max_per_card": max_per_card,
}))
def process_top_decks():
with open("top_decks.json", "r", encoding="utf-8") as f:
transform_and_write_top_decks_json(json.loads(f.read()))
def open_card_info():
try:
with open("card_info.json", "r", encoding="utf-8") as f:
return json.loads(f.read())
except FileNotFoundError:
return {}
def write_card_info(info):
with open("card_info.json", "w", encoding="utf-8") as f:
f.write(json.dumps(info))
def open_deck_stats():
with open("top_decks_processed.json", "r", encoding="utf-8") as f:
return json.loads(f.read())
card_url = "https://www.masterduelmeta.com/cards/%s"
# <div class="rarity-image svelte-en6kzk"><img src="/img/assets/rarities/ur.png"
def update_card_info():
card_info = open_card_info()
deck_stats = open_deck_stats()
count_per_card = deck_stats["count_per_card"]
written = 0
for name in count_per_card:
if not name in card_info:
encoded_name = urllib.parse.quote(name)
encoded_name = encoded_name.replace("/", "%2f")
result = requests.get(card_url % encoded_name)
if result.status_code == 200:
match = re.search('<div class="rarity-image svelte-en6kzk"><img src="/img/assets/rarities/(\\w+).png', result.content.decode("utf-8"))
rarity = match.group(1).lower() if match else "n"
card_info[name] = rarity
print("Rarity of '%s' is %s" % (name, rarity))
written += 1
if written > 10:
write_card_info(card_info)
written = 0
else:
print("Failed to get card '%s'" % name)
write_card_info(card_info)
def tally_results():
card_info = open_card_info()
deck_stats = open_deck_stats()
deck_count = deck_stats["total"]
count_by_rarity = {
"n": 0,
"r": 0,
"sr": 0,
"ur": 0,
}
count_per_card = deck_stats["count_per_card"]
for card in count_per_card:
count_by_rarity[card_info[card]] += count_per_card[card]
for rarity in count_by_rarity:
count_by_rarity[rarity] /= deck_count
#
total_needed_by_rarity = {
"n": 0,
"r": 0,
"sr": 0,
"ur": 0,
}
max_per_card = deck_stats["max_per_card"]
for card in max_per_card:
total_needed_by_rarity[card_info[card]] += max_per_card[card]
#
print("UR per SR (single deck): %.1f" % (count_by_rarity["ur"] / count_by_rarity["sr"]))
print("UR per SR (every deck): %.1f" % (total_needed_by_rarity["ur"] / total_needed_by_rarity["sr"]))
def everything():
fetch_top_decks()
process_top_decks()
update_card_info()
tally_results()
if __name__ == "__main__":
everything()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment