Add Basic Lands to MTG Guesser (#716)

* fix https

* add beasts

* Remove extra file

* Prettier-ify code

* Prettier-ify

* add basic land guesser

also added fetcher to filter all cards instead of only unique art

* default to original

makes basic better

* added set symbol to basics

added set symbol to the basics game mode. Changed name to "How Basic"

* cleanup

* changed some pixels

* only load set data if needed

* hacked fix for removing image from name

Co-authored-by: Austin Chen <akrolsmir@gmail.com>
This commit is contained in:
marsteralex 2022-08-17 12:40:59 -07:00 committed by GitHub
parent 99009f841b
commit ce3d092497
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 170 additions and 88 deletions

View File

@ -18,7 +18,9 @@ online = false
firstPrint = false firstPrint = false
flag = true flag = true
page = 1 page = 1
sets = {}
window.console.log(sets)
document.location.search.split('&').forEach((pair) => { document.location.search.split('&').forEach((pair) => {
let v = pair.split('=') let v = pair.split('=')
if (v[0] === '?whichguesser') { if (v[0] === '?whichguesser') {
@ -32,39 +34,38 @@ document.location.search.split('&').forEach((pair) => {
} }
}) })
let firstFetch = fetch('jsons/' + whichGuesser + page + '.json') if (whichGuesser === 'basic') {
fetch('jsons/set.json')
.then((response) => response.json())
.then((data) => (sets = data))
}
let firstFetch = fetch('jsons/' + whichGuesser + '.json')
fetchToResponse(firstFetch) fetchToResponse(firstFetch)
function putIntoMapAndFetch(data) { function putIntoMapAndFetch(data) {
putIntoMap(data.data) putIntoMap(data.data)
if (data.has_more) { for (const [key, value] of Object.entries(allData)) {
page += 1 nameList.push(key)
window.setTimeout(() => probList.push(
fetchToResponse(fetch('jsons/' + whichGuesser + page + '.json')) value.length + (probList.length === 0 ? 0 : probList[probList.length - 1])
) )
} else { unseenTotal = total
for (const [key, value] of Object.entries(allData)) {
nameList.push(key)
probList.push(
value.length +
(probList.length === 0 ? 0 : probList[probList.length - 1])
)
unseenTotal = total
}
window.console.log(allData)
window.console.log(total)
window.console.log(probList)
window.console.log(nameList)
if (whichGuesser === 'counterspell') {
document.getElementById('guess-type').innerText = 'Counterspell Guesser'
} else if (whichGuesser === 'burn') {
document.getElementById('guess-type').innerText = 'Match With Hot Singles'
} else if (whichGuesser === 'beast') {
document.getElementById('guess-type').innerText =
'Finding Fantastic Beasts'
}
setUpNewGame()
} }
window.console.log(allData)
window.console.log(total)
window.console.log(probList)
window.console.log(nameList)
if (whichGuesser === 'counterspell') {
document.getElementById('guess-type').innerText = 'Counterspell Guesser'
} else if (whichGuesser === 'burn') {
document.getElementById('guess-type').innerText = 'Match With Hot Singles'
} else if (whichGuesser === 'beast') {
document.getElementById('guess-type').innerText = 'Finding Fantastic Beasts'
} else if (whichGuesser === 'basic') {
document.getElementById('guess-type').innerText = 'How Basic'
}
setUpNewGame()
} }
function getKSamples() { function getKSamples() {
@ -134,11 +135,17 @@ function determineIfSkip(card) {
} }
} }
if (firstPrint) { if (firstPrint) {
if ( if (whichGuesser == 'basic') {
card.reprint === true || if (card.set_type !== 'expansion' && card.set_type !== 'funny') {
(card.frame_effects && card.frame_effects.includes('showcase')) return true
) { }
return true } else {
if (
card.reprint === true ||
(card.frame_effects && card.frame_effects.includes('showcase'))
) {
return true
}
} }
} }
// reskinned card names show in art crop // reskinned card names show in art crop
@ -160,13 +167,16 @@ function putIntoMap(data) {
if (card.card_faces) { if (card.card_faces) {
name = card.card_faces[0].name name = card.card_faces[0].name
} }
if (whichGuesser === 'basic') {
name =
'<img class="symbol" style="width: 17px; height: 17px" src="' +
sets[name][1] +
'" /> ' +
sets[name][0]
}
let normalImg = '' let normalImg = ''
if (card.image_uris.normal) { if (card.image_uris.normal) {
normalImg = card.image_uris.normal normalImg = card.image_uris.normal
} else if (card.image_uris.large) {
normalImg = card.image_uris.large
} else if (card.image_uris.small) {
normalImg = card.image_uris.small
} else { } else {
continue continue
} }
@ -224,7 +234,7 @@ function setUpNewGame() {
for (nameIndex = 1; nameIndex <= k + extra; nameIndex++) { for (nameIndex = 1; nameIndex <= k + extra; nameIndex++) {
currName = document.getElementById('name-' + nameIndex) currName = document.getElementById('name-' + nameIndex)
// window.console.log(currName) // window.console.log(currName)
currName.innerText = namesList[nameIndex - 1] currName.innerHTML = namesList[nameIndex - 1]
nameBank.appendChild(currName) nameBank.appendChild(currName)
} }
} }
@ -236,9 +246,13 @@ function checkAnswers() {
currCard = document.getElementById('card-' + cardIndex) currCard = document.getElementById('card-' + cardIndex)
let incorrect = true let incorrect = true
if (currCard.dataset.name) { if (currCard.dataset.name) {
let guess = document.getElementById(currCard.dataset.name).innerText // remove image text
// window.console.log(artDict[currCard.dataset.url][0], guess); let guess = document
incorrect = artDict[currCard.dataset.url][0] !== guess .getElementById(currCard.dataset.name)
.innerText.split('>')
let ans = artDict[currCard.dataset.url][0].split('>')
window.console.log(ans, guess)
incorrect = ans[ans.length - 1] !== guess[guess.length - 1]
// decide if their guess was correct // decide if their guess was correct
} }
if (incorrect) currCard.classList.add('incorrect') if (incorrect) currCard.classList.add('incorrect')
@ -352,6 +366,10 @@ function dropOnCard(id, data) {
} }
function setWordsLeft() { function setWordsLeft() {
cardName = 'Unused Card Names: '
if (whichGuesser === 'basic') {
cardName = 'Unused Set Names: '
}
document.getElementById('words-left').innerText = document.getElementById('words-left').innerText =
'Unused Card Names: ' + wordsLeft + '/Images: ' + imagesLeft cardName + wordsLeft + '/Images: ' + imagesLeft
} }

View File

@ -77,7 +77,7 @@
} }
.answer-page .card { .answer-page .card {
height: 350px; height: 353px;
/*padding-top: 310px;*/ /*padding-top: 310px;*/
/*background-size: cover;*/ /*background-size: cover;*/
overflow: hidden; overflow: hidden;
@ -253,16 +253,6 @@
.name { .name {
width: 300px; width: 300px;
} }
.card {
width: 300px;
background-size: 300px;
height: 266px;
}
.answer-page .card {
height: 454px;
}
} }
</style> </style>
</head> </head>

View File

@ -3,7 +3,8 @@ import requests
import json import json
# add category name here # add category name here
allCategories = ['counterspell', 'beast', 'terror', 'wrath', 'burn'] allCategories = ['counterspell', 'beast', 'burn'] #, 'terror', 'wrath']
specialCategories = ['set', 'basic']
def generate_initial_query(category): def generate_initial_query(category):
@ -12,11 +13,11 @@ def generate_initial_query(category):
string_query += 'otag%3Acounterspell+t%3Ainstant+not%3Aadventure' string_query += 'otag%3Acounterspell+t%3Ainstant+not%3Aadventure'
elif category == 'beast': elif category == 'beast':
string_query += '-type%3Alegendary+type%3Abeast+-type%3Atoken' string_query += '-type%3Alegendary+type%3Abeast+-type%3Atoken'
elif category == 'terror': # elif category == 'terror':
string_query += 'otag%3Acreature-removal+o%3A%2Fdestroy+target.%2A+%28creature%7Cpermanent%29%2F+%28t' \ # string_query += 'otag%3Acreature-removal+o%3A%2Fdestroy+target.%2A+%28creature%7Cpermanent%29%2F+%28t' \
'%3Ainstant+or+t%3Asorcery%29+o%3Atarget+not%3Aadventure' # '%3Ainstant+or+t%3Asorcery%29+o%3Atarget+not%3Aadventure'
elif category == 'wrath': # elif category == 'wrath':
string_query += 'otag%3Asweeper-creature+%28t%3Ainstant+or+t%3Asorcery%29+not%3Aadventure' # string_query += 'otag%3Asweeper-creature+%28t%3Ainstant+or+t%3Asorcery%29+not%3Aadventure'
elif category == 'burn': elif category == 'burn':
string_query += '%28c>%3Dr+or+mana>%3Dr%29+%28o%3A%2Fdamage+to+them%2F+or+%28o%3Adeals+o%3Adamage+o%3A' \ string_query += '%28c>%3Dr+or+mana>%3Dr%29+%28o%3A%2Fdamage+to+them%2F+or+%28o%3Adeals+o%3Adamage+o%3A' \
'%2Fcontroller%28%5C.%7C+%29%2F%29+or+o%3A%2F~+deals+%28.%7C..%29+damage+to+%28any+target%7C' \ '%2Fcontroller%28%5C.%7C+%29%2F%29+or+o%3A%2F~+deals+%28.%7C..%29+damage+to+%28any+target%7C' \
@ -24,9 +25,19 @@ def generate_initial_query(category):
'+%28type%3Ainstant+or+type%3Asorcery%29+not%3Aadventure' '+%28type%3Ainstant+or+type%3Asorcery%29+not%3Aadventure'
# add category string query here # add category string query here
string_query += '+-%28set%3Asld+%28%28cn>%3D231+cn<%3D233%29+or+%28cn>%3D321+cn<%3D324%29+or+%28cn>%3D185+cn' \ string_query += '+-%28set%3Asld+%28%28cn>%3D231+cn<%3D233%29+or+%28cn>%3D321+cn<%3D324%29+or+%28cn>%3D185+cn' \
'<%3D189%29+or+%28cn>%3D138+cn<%3D142%29+or+%28cn>%3D364+cn<%3D368%29+or+cn%3A669+or+cn%3A670%29' \ '<%3D189%29+or+%28cn>%3D138+cn<%3D142%29+or+%28cn>%3D364+cn<%3D368%29+or+cn%3A669+or+cn%3A670%29' \
'%29+-name%3A%2F%5EA-%2F+not%3Adfc+not%3Asplit+-set%3Acmb2+-set%3Acmb1+-set%3Aplist+-set%3Adbl' \ '%29+-name%3A%2F%5EA-%2F+not%3Adfc+not%3Asplit+-set%3Acmb2+-set%3Acmb1+-set%3Aplist+-set%3Adbl' \
'+-frame%3Aextendedart+language%3Aenglish&unique=art&page=' '+language%3Aenglish&order=released&dir=asc&unique=prints&page='
print(string_query)
return string_query
def generate_initial_special_query(category):
string_query = 'https://api.scryfall.com/cards/search?q='
if category == 'set':
return 'https://api.scryfall.com/sets'
elif category == 'basic':
string_query += 't%3Abasic&order=released&dir=asc&unique=prints&page='
# add category string query here
print(string_query) print(string_query)
return string_query return string_query
@ -34,31 +45,60 @@ def generate_initial_query(category):
def fetch_and_write_all(category, query): def fetch_and_write_all(category, query):
count = 1 count = 1
will_repeat = True will_repeat = True
all_cards = {'data' : []}
art_names = set()
while will_repeat: while will_repeat:
will_repeat = fetch_and_write(category, query, count) response = fetch(query, count)
count += 1 will_repeat = response['has_more']
count+=1
to_compact_write_form(all_cards, art_names, response, category)
with open('jsons/' + category + '.json', 'w') as f:
json.dump(all_cards, f)
def fetch_and_write(category, query, count): def fetch_and_write_all_special(category, query):
count = 1
will_repeat = True
all_cards = {'data' : []}
art_names = set()
while will_repeat:
if category == 'set':
response = fetch_special(query)
else:
response = fetch(query, count)
will_repeat = response['has_more']
count+=1
to_compact_write_form_special(all_cards, art_names, response, category)
with open('jsons/' + category + '.json', 'w') as f:
json.dump(all_cards, f)
def fetch(query, count):
query += str(count) query += str(count)
response = requests.get(f"{query}").json() response = requests.get(f"{query}").json()
time.sleep(0.1) time.sleep(0.1)
with open('jsons/' + category + str(count) + '.json', 'w') as f: return response
json.dump(to_compact_write_form(response), f)
return response['has_more'] def fetch_special(query):
response = requests.get(f"{query}").json()
time.sleep(0.1)
return response
def to_compact_write_form(response): def to_compact_write_form(smallJson, art_names, response, category):
fieldsToUse = ['has_more']
fieldsInCard = ['name', 'image_uris', 'content_warning', 'flavor_name', 'reprint', 'frame_effects', 'digital', fieldsInCard = ['name', 'image_uris', 'content_warning', 'flavor_name', 'reprint', 'frame_effects', 'digital',
'set_type'] 'set_type']
smallJson = dict()
data = [] data = []
# write all fields needed in response
for field in fieldsToUse:
smallJson[field] = response[field]
# write all fields needed in card # write all fields needed in card
for card in response['data']: for card in response['data']:
# do not repeat art
if 'illustration_id' not in card or card['illustration_id'] in art_names:
continue
else:
art_names.add(card['illustration_id'])
write_card = dict() write_card = dict()
for field in fieldsInCard: for field in fieldsInCard:
if field == 'name' and 'card_faces' in card: if field == 'name' and 'card_faces' in card:
@ -68,8 +108,33 @@ def to_compact_write_form(response):
elif field in card: elif field in card:
write_card[field] = card[field] write_card[field] = card[field]
data.append(write_card) data.append(write_card)
smallJson['data'] = data smallJson['data'] += data
return smallJson
def to_compact_write_form_special(smallJson, art_names, response, category):
fieldsInBasic = ['image_uris', 'set', 'set_type', 'digital']
data = []
# write all fields needed in card
for card in response['data']:
if category == 'basic':
write_card = dict()
# do not repeat art
if 'illustration_id' not in card or card['illustration_id'] in art_names:
continue
else:
art_names.add(card['illustration_id'])
for field in fieldsInBasic:
if field == 'image_uris':
write_card['image_uris'] = write_image_uris(card['image_uris'])
elif field == 'set':
write_card['name'] = card['set']
elif field in card:
write_card[field] = card[field]
data.append(write_card)
else:
if card['set_type'] != 'token':
smallJson[card['code']] = [card['name'],card['icon_svg_uri']]
smallJson['data'] += data
# only write images needed # only write images needed
@ -87,6 +152,9 @@ def write_image_uris(card_image_uris):
if __name__ == "__main__": if __name__ == "__main__":
for category in allCategories: # for category in allCategories:
# print(category)
# fetch_and_write_all(category, generate_initial_query(category))
for category in specialCategories:
print(category) print(category)
fetch_and_write_all(category, generate_initial_query(category)) fetch_and_write_all_special(category, generate_initial_special_query(category))

View File

@ -159,6 +159,16 @@
> >
<br /> <br />
<input type="radio" id="basic" name="whichguesser" value="basic" />
<label class="radio-label" for="basic">
<img
class="thumbnail"
src="https://c1.scryfall.com/file/scryfall-cards/art_crop/front/0/3/03683fbb-9843-4c14-bb95-387150e97c90.jpg?1642161346"
/>
<h3>How Basic</h3></label
>
<br />
<details id="addl-options"> <details id="addl-options">
<summary> <summary>
<img <img
@ -173,8 +183,8 @@
<input type="checkbox" name="un" id="un" checked /> <input type="checkbox" name="un" id="un" checked />
<label for="un">include un-cards</label> <label for="un">include un-cards</label>
<br /> <br />
<input type="checkbox" name="original" id="original" /> <input type="checkbox" name="original" id="original" checked />
<label for="original">restrict to only original printing</label> <label for="original">only original set printing</label>
</details> </details>
<input type="submit" id="submit" value="Play" /> <input type="submit" id="submit" value="Play" />
</form> </form>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long