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
flag = true
page = 1
sets = {}
window.console.log(sets)
document.location.search.split('&').forEach((pair) => {
let v = pair.split('=')
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)
function putIntoMapAndFetch(data) {
putIntoMap(data.data)
if (data.has_more) {
page += 1
window.setTimeout(() =>
fetchToResponse(fetch('jsons/' + whichGuesser + page + '.json'))
for (const [key, value] of Object.entries(allData)) {
nameList.push(key)
probList.push(
value.length + (probList.length === 0 ? 0 : probList[probList.length - 1])
)
} else {
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()
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'
} else if (whichGuesser === 'basic') {
document.getElementById('guess-type').innerText = 'How Basic'
}
setUpNewGame()
}
function getKSamples() {
@ -134,11 +135,17 @@ function determineIfSkip(card) {
}
}
if (firstPrint) {
if (
card.reprint === true ||
(card.frame_effects && card.frame_effects.includes('showcase'))
) {
return true
if (whichGuesser == 'basic') {
if (card.set_type !== 'expansion' && card.set_type !== 'funny') {
return true
}
} else {
if (
card.reprint === true ||
(card.frame_effects && card.frame_effects.includes('showcase'))
) {
return true
}
}
}
// reskinned card names show in art crop
@ -160,13 +167,16 @@ function putIntoMap(data) {
if (card.card_faces) {
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 = ''
if (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 {
continue
}
@ -224,7 +234,7 @@ function setUpNewGame() {
for (nameIndex = 1; nameIndex <= k + extra; nameIndex++) {
currName = document.getElementById('name-' + nameIndex)
// window.console.log(currName)
currName.innerText = namesList[nameIndex - 1]
currName.innerHTML = namesList[nameIndex - 1]
nameBank.appendChild(currName)
}
}
@ -236,9 +246,13 @@ function checkAnswers() {
currCard = document.getElementById('card-' + cardIndex)
let incorrect = true
if (currCard.dataset.name) {
let guess = document.getElementById(currCard.dataset.name).innerText
// window.console.log(artDict[currCard.dataset.url][0], guess);
incorrect = artDict[currCard.dataset.url][0] !== guess
// remove image text
let guess = document
.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
}
if (incorrect) currCard.classList.add('incorrect')
@ -352,6 +366,10 @@ function dropOnCard(id, data) {
}
function setWordsLeft() {
cardName = 'Unused Card Names: '
if (whichGuesser === 'basic') {
cardName = 'Unused Set Names: '
}
document.getElementById('words-left').innerText =
'Unused Card Names: ' + wordsLeft + '/Images: ' + imagesLeft
cardName + wordsLeft + '/Images: ' + imagesLeft
}

View File

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

View File

@ -3,7 +3,8 @@ import requests
import json
# add category name here
allCategories = ['counterspell', 'beast', 'terror', 'wrath', 'burn']
allCategories = ['counterspell', 'beast', 'burn'] #, 'terror', 'wrath']
specialCategories = ['set', 'basic']
def generate_initial_query(category):
@ -12,11 +13,11 @@ def generate_initial_query(category):
string_query += 'otag%3Acounterspell+t%3Ainstant+not%3Aadventure'
elif category == 'beast':
string_query += '-type%3Alegendary+type%3Abeast+-type%3Atoken'
elif category == 'terror':
string_query += 'otag%3Acreature-removal+o%3A%2Fdestroy+target.%2A+%28creature%7Cpermanent%29%2F+%28t' \
'%3Ainstant+or+t%3Asorcery%29+o%3Atarget+not%3Aadventure'
elif category == 'wrath':
string_query += 'otag%3Asweeper-creature+%28t%3Ainstant+or+t%3Asorcery%29+not%3Aadventure'
# elif category == 'terror':
# string_query += 'otag%3Acreature-removal+o%3A%2Fdestroy+target.%2A+%28creature%7Cpermanent%29%2F+%28t' \
# '%3Ainstant+or+t%3Asorcery%29+o%3Atarget+not%3Aadventure'
# elif category == 'wrath':
# string_query += 'otag%3Asweeper-creature+%28t%3Ainstant+or+t%3Asorcery%29+not%3Aadventure'
elif category == 'burn':
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' \
@ -24,9 +25,19 @@ def generate_initial_query(category):
'+%28type%3Ainstant+or+type%3Asorcery%29+not%3Aadventure'
# 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' \
'<%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' \
'+-frame%3Aextendedart+language%3Aenglish&unique=art&page='
'<%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' \
'+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)
return string_query
@ -34,31 +45,60 @@ def generate_initial_query(category):
def fetch_and_write_all(category, query):
count = 1
will_repeat = True
all_cards = {'data' : []}
art_names = set()
while will_repeat:
will_repeat = fetch_and_write(category, query, count)
count += 1
response = fetch(query, count)
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)
response = requests.get(f"{query}").json()
time.sleep(0.1)
with open('jsons/' + category + str(count) + '.json', 'w') as f:
json.dump(to_compact_write_form(response), f)
return response['has_more']
return response
def fetch_special(query):
response = requests.get(f"{query}").json()
time.sleep(0.1)
return response
def to_compact_write_form(response):
fieldsToUse = ['has_more']
def to_compact_write_form(smallJson, art_names, response, category):
fieldsInCard = ['name', 'image_uris', 'content_warning', 'flavor_name', 'reprint', 'frame_effects', 'digital',
'set_type']
smallJson = dict()
data = []
# write all fields needed in response
for field in fieldsToUse:
smallJson[field] = response[field]
# write all fields needed in card
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()
for field in fieldsInCard:
if field == 'name' and 'card_faces' in card:
@ -68,8 +108,33 @@ def to_compact_write_form(response):
elif field in card:
write_card[field] = card[field]
data.append(write_card)
smallJson['data'] = data
return smallJson
smallJson['data'] += data
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
@ -87,6 +152,9 @@ def write_image_uris(card_image_uris):
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)
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 />
<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">
<summary>
<img
@ -173,8 +183,8 @@
<input type="checkbox" name="un" id="un" checked />
<label for="un">include un-cards</label>
<br />
<input type="checkbox" name="original" id="original" />
<label for="original">restrict to only original printing</label>
<input type="checkbox" name="original" id="original" checked />
<label for="original">only original set printing</label>
</details>
<input type="submit" id="submit" value="Play" />
</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