44deaf7b0a
* 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 * removed check from original * remove check from original * sort names by set instead of by set symbol * include battlebond * update cards for categories update for dominaria united * added commander category commander category * update basic land art * can use double feature * removing racist cards upstream this way we don't have to store the cards in the json * remove generated cards from digital commanders * fix counterspell setting default * added difficulty rating * updated padding * add dfc support for commanders * add artists * use latest non-digital if possible * change vsCode settings for python * update with latest non-digital printing * update artist list * update algo to select k samples * cleanup code * equally weight artists * weight everything equally * updated for all artists * update artists * add allowlist * update artists to min 50 art * allow promo to be replaced * update jsons * update with min 100 arts * update code to be smaller jsons * updated to 18 artists per game * update ui * update importing artists * update to 21 * move num artists to top of js file * update artistList to not include artist sigs * update to 50 artists * update for ub * update artist list * update ub defaults * update jsons * allow non-english cards to be replaced * update allowlist * update jsons * add watermark * update jsons * update jsons * make jsons slightly smaller * add checkmarks and x's * remove python * add no answer and checkbox and x Co-authored-by: Austin Chen <akrolsmir@gmail.com>
497 lines
13 KiB
JavaScript
497 lines
13 KiB
JavaScript
mode = 'PLAY'
|
|
allData = {}
|
|
total = 0
|
|
cardNames = []
|
|
k = 12
|
|
extra = 3
|
|
num_artists = k + extra * 2
|
|
artDict = {}
|
|
totalCorrect = 0
|
|
totalSeen = 0
|
|
wordsLeft = k + extra
|
|
imagesLeft = k
|
|
maxRounds = 20
|
|
whichGuesser = 'counterspell'
|
|
un = false
|
|
ub = false
|
|
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') {
|
|
whichGuesser = v[1]
|
|
} else if (v[0] === 'un') {
|
|
un = v[1]
|
|
} else if (v[0] === 'digital') {
|
|
online = v[1]
|
|
} else if (v[0] === 'original') {
|
|
firstPrint = v[1]
|
|
} else if (v[0] === 'ub') {
|
|
ub = v[1]
|
|
}
|
|
})
|
|
|
|
if (whichGuesser === 'basic') {
|
|
fetch('jsons/set.json')
|
|
.then((response) => response.json())
|
|
.then((data) => (sets = data))
|
|
}
|
|
|
|
if (whichGuesser === 'watermark') {
|
|
fetch('jsons/wm.json')
|
|
.then((response) => response.json())
|
|
.then((data) => (sets = data))
|
|
}
|
|
|
|
let firstFetch = fetch('jsons/' + whichGuesser + '.json')
|
|
fetchToResponse(firstFetch)
|
|
|
|
function putIntoMapAndFetch(data) {
|
|
putIntoMap(data.data)
|
|
if (whichGuesser == 'artist') {
|
|
newArtistData = createNewArtistMap()
|
|
allData = newArtistData[0]
|
|
total = newArtistData[1]
|
|
}
|
|
cardNames = Array.from(Object.keys(allData))
|
|
window.console.log(allData)
|
|
window.console.log(cardNames)
|
|
window.console.log(total)
|
|
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'
|
|
} else if (whichGuesser === 'commander') {
|
|
document.getElementById('guess-type').innerText = 'General Knowledge'
|
|
} else if (whichGuesser === 'watermark') {
|
|
document.getElementById('guess-type').innerText = 'Watermark It'
|
|
} else if (whichGuesser === 'artist') {
|
|
document.getElementById('guess-type').innerText = 'Aesthetic Consultation'
|
|
}
|
|
window.console.log(whichGuesser)
|
|
setUpNewGame()
|
|
}
|
|
|
|
function getKSamples() {
|
|
let usedCounters = new Set()
|
|
let samples = {}
|
|
let i = 0
|
|
let allCards = Array.from(Object.keys(allData))
|
|
shuffleArray(allCards)
|
|
window.console.log(allCards)
|
|
for (let j = 0; j < allCards.length; j++) {
|
|
key = allCards[j]
|
|
value = allData[key]
|
|
if (usedCounters.has(key)) {
|
|
continue
|
|
} else {
|
|
window.console.log(key)
|
|
usedCounters.add(key)
|
|
let randIndex = Math.floor(Math.random() * value.length)
|
|
let arts = allData[key].splice(randIndex, 1)
|
|
samples[arts[0].artImg] = [key, arts[0].normalImg]
|
|
i++
|
|
if (i >= k) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
for (const key of usedCounters) {
|
|
if (allData[key].length === 0) {
|
|
delete allData[key]
|
|
}
|
|
}
|
|
let count = 0
|
|
shuffleArray(cardNames)
|
|
for (let j = 0; j < cardNames.length; j++) {
|
|
key = cardNames[j]
|
|
value = cardNames[key]
|
|
if (usedCounters.has(key)) {
|
|
continue
|
|
} else {
|
|
window.console.log(key)
|
|
usedCounters.add(key)
|
|
count++
|
|
if (count >= extra) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
return [samples, usedCounters]
|
|
}
|
|
|
|
function createNewArtistMap() {
|
|
let usedCounters = new Set()
|
|
let samples = {}
|
|
let i = 0
|
|
let newTotal = 0
|
|
let allCards = []
|
|
for (const [key, value] of Object.entries(allData)) {
|
|
for (let j = 0; j < value.length; j++) {
|
|
allCards.push(key)
|
|
}
|
|
}
|
|
shuffleArray(allCards)
|
|
window.console.log(allCards)
|
|
for (let j = 0; j < allCards.length; j++) {
|
|
key = allCards[j]
|
|
value = allData[key]
|
|
if (usedCounters.has(key)) {
|
|
continue
|
|
} else {
|
|
window.console.log(key)
|
|
usedCounters.add(key)
|
|
samples[key] = value
|
|
newTotal += value.length
|
|
i++
|
|
if (i >= num_artists) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
return [samples, newTotal]
|
|
}
|
|
|
|
function fetchToResponse(fetch) {
|
|
return fetch
|
|
.then((response) => response.json())
|
|
.then((json) => putIntoMapAndFetch(json))
|
|
}
|
|
|
|
function determineIfSkip(card) {
|
|
if (!un) {
|
|
if (card.set_type === 'funny') {
|
|
return true
|
|
}
|
|
}
|
|
if (!ub) {
|
|
if (card.security_stamp === 'triangle') {
|
|
return true
|
|
}
|
|
}
|
|
if (!online) {
|
|
if (card.digital) {
|
|
return true
|
|
}
|
|
}
|
|
if (firstPrint) {
|
|
if (whichGuesser == 'basic') {
|
|
if (card.set_type !== 'expansion' && card.set_type !== 'funny') {
|
|
return true
|
|
}
|
|
} else if (whichGuesser == 'artist') {
|
|
if (
|
|
card.set_type === 'token' ||
|
|
card.set_type === 'vanguard' ||
|
|
card.set_type === 'planechase' ||
|
|
card.set_type === 'archenemy' ||
|
|
card.set_type === 'memorabilia'
|
|
) {
|
|
return true
|
|
}
|
|
} else if (whichGuesser == 'watermark') {
|
|
if (
|
|
card.name === 'Set' ||
|
|
card.name === 'Planeswalker' ||
|
|
card.name === 'Flavor' ||
|
|
card.name === 'Conspiracy' ||
|
|
card.name === 'Foretell' ||
|
|
card.name === 'Tarkir' ||
|
|
card.set === 'h17' ||
|
|
card.set === 'ptg' ||
|
|
card.set === 'htr18'
|
|
) {
|
|
return true
|
|
}
|
|
} else {
|
|
if (
|
|
card.reprint ||
|
|
(card.frame_effects && card.frame_effects.includes('showcase'))
|
|
) {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
// reskinned card names show in art crop
|
|
if (card.flavor_name) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
function putIntoMap(data) {
|
|
for (let i = 0; i < data.length; i++) {
|
|
let card = data[i]
|
|
if (determineIfSkip(card)) {
|
|
continue
|
|
}
|
|
let name = card.name
|
|
// remove slashes from adventure cards
|
|
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]
|
|
}
|
|
if (whichGuesser === 'watermark' && sets.hasOwnProperty(name)) {
|
|
name = sets[name]
|
|
}
|
|
let normalImg = ''
|
|
if (card.image_uris.normal) {
|
|
normalImg = card.image_uris.normal
|
|
} else {
|
|
continue
|
|
}
|
|
let artImg = ''
|
|
if (card.image_uris.art_crop) {
|
|
artImg = card.image_uris.art_crop
|
|
} else {
|
|
continue
|
|
}
|
|
total += 1
|
|
if (!allData[name]) {
|
|
allData[name] = [{ artImg: artImg, normalImg: normalImg }]
|
|
} else {
|
|
allData[name].push({ artImg: artImg, normalImg: normalImg })
|
|
}
|
|
}
|
|
}
|
|
|
|
function shuffleArray(array) {
|
|
for (let i = array.length - 1; i > 0; i--) {
|
|
let j = Math.floor(Math.random() * (i + 1))
|
|
let temp = array[i]
|
|
array[i] = array[j]
|
|
array[j] = temp
|
|
}
|
|
}
|
|
|
|
function setUpNewGame() {
|
|
wordsLeft = k + extra
|
|
imagesLeft = k
|
|
let currentRound = totalSeen / k
|
|
if (currentRound + 1 === maxRounds) {
|
|
document.getElementById('round-number').innerText = 'Final Round'
|
|
} else {
|
|
document.getElementById('round-number').innerText =
|
|
'Round ' + (1 + currentRound)
|
|
}
|
|
|
|
setWordsLeft()
|
|
// select new cards
|
|
let sampledData = getKSamples()
|
|
artDict = sampledData[0]
|
|
let randomImages = Object.keys(artDict)
|
|
shuffleArray(randomImages)
|
|
let namesList = Array.from(sampledData[1]).sort((a, b) =>
|
|
removeSymbol(a).localeCompare(removeSymbol(b))
|
|
)
|
|
// fill in the new cards and names
|
|
for (let cardIndex = 1; cardIndex <= k; cardIndex++) {
|
|
let currCard = document.getElementById('card-' + cardIndex)
|
|
currCard.classList.remove('incorrect')
|
|
currCard.dataset.name = ''
|
|
currCard.dataset.url = randomImages[cardIndex - 1]
|
|
currCard.style.backgroundImage = "url('" + currCard.dataset.url + "')"
|
|
}
|
|
const nameBank = document.querySelector('.names-bank')
|
|
for (nameIndex = 1; nameIndex <= k + extra; nameIndex++) {
|
|
currName = document.getElementById('name-' + nameIndex)
|
|
// window.console.log(currName)
|
|
currName.innerHTML = namesList[nameIndex - 1]
|
|
nameBank.appendChild(currName)
|
|
}
|
|
document.querySelectorAll('.temporary-name-holder').forEach((x) => x.remove())
|
|
}
|
|
|
|
function removeSymbol(name) {
|
|
let arr = name.split('>')
|
|
return arr[arr.length - 1]
|
|
}
|
|
|
|
function checkAnswers() {
|
|
let score = k
|
|
// show the correct full cards
|
|
for (cardIndex = 1; cardIndex <= k; cardIndex++) {
|
|
currCard = document.getElementById('card-' + cardIndex)
|
|
let incorrect = true
|
|
if (currCard.dataset.name) {
|
|
// remove image text
|
|
let guessWithSymbol = document.getElementById(
|
|
currCard.dataset.name
|
|
).innerHTML
|
|
let ansWithSymbol = artDict[currCard.dataset.url][0]
|
|
let guess = removeSymbol(guessWithSymbol)
|
|
let ans = removeSymbol(ansWithSymbol)
|
|
incorrect = ans !== guess
|
|
// decide if their guess was correct
|
|
// window.console.log(ans, guess, incorrect)
|
|
correctAns = String.fromCodePoint(0x2705) + ' ' + ansWithSymbol
|
|
if (incorrect) {
|
|
window.console.log(
|
|
document.getElementById(currCard.dataset.name),
|
|
guess,
|
|
ans
|
|
)
|
|
document.getElementById(currCard.dataset.name).innerHTML =
|
|
String.fromCodePoint(0x274c) +
|
|
' <i style="opacity:.6"><strike>' +
|
|
guessWithSymbol +
|
|
'</strike></i><br/><span style="opacity:0;">' +
|
|
String.fromCodePoint(0x274c) +
|
|
'</span> ' +
|
|
ansWithSymbol
|
|
} else {
|
|
document.getElementById(currCard.dataset.name).innerHTML = correctAns
|
|
}
|
|
} else {
|
|
answerCorrectionHolder = document.createElement('div')
|
|
answerCorrectionHolder.classList.add('name')
|
|
answerCorrectionHolder.classList.add('temporary-name-holder')
|
|
|
|
answerCorrectionHolder.innerHTML =
|
|
String.fromCodePoint(0x274c) +
|
|
' <i style="opacity:.6"><No Answer> </i><br/><span style="opacity:0;">' +
|
|
String.fromCodePoint(0x274c) +
|
|
'</span> ' +
|
|
artDict[currCard.dataset.url][0]
|
|
currCard.appendChild(answerCorrectionHolder)
|
|
}
|
|
if (incorrect) {
|
|
currCard.classList.add('incorrect')
|
|
// tally some kind of score
|
|
score--
|
|
// show the correct answer
|
|
}
|
|
|
|
// show the correct card
|
|
currCard.style.backgroundImage =
|
|
"url('" + artDict[currCard.dataset.url][1] + "')"
|
|
}
|
|
totalSeen += k
|
|
totalCorrect += score
|
|
document.getElementById('score-amount').innerText = score + '/' + k
|
|
document.getElementById('score-percent').innerText = Math.round(
|
|
(totalCorrect * 100) / totalSeen
|
|
)
|
|
document.getElementById('score-amount-total').innerText =
|
|
totalCorrect + '/' + totalSeen
|
|
}
|
|
|
|
function toggleMode() {
|
|
event.preventDefault()
|
|
if (mode === 'PLAY') {
|
|
mode = 'ANSWER'
|
|
document.querySelector('.play-page').classList.add('answer-page')
|
|
window.console.log(totalSeen)
|
|
if (totalSeen / k === maxRounds - 1) {
|
|
document.getElementById('submit').style.display = 'none'
|
|
} else {
|
|
document.getElementById('submit').value = 'Next Round'
|
|
}
|
|
checkAnswers()
|
|
} else {
|
|
mode = 'PLAY'
|
|
document.querySelector('.play-page').classList.remove('answer-page')
|
|
document.getElementById('submit').value = 'Submit'
|
|
setUpNewGame()
|
|
}
|
|
}
|
|
|
|
function allowDrop(ev, id) {
|
|
ev.preventDefault()
|
|
}
|
|
|
|
function drag(ev) {
|
|
ev.dataTransfer.setData('text', ev.target.id)
|
|
let nameEl = document.querySelector('.selected')
|
|
if (nameEl) nameEl.classList.remove('selected')
|
|
}
|
|
|
|
function drop(ev, id) {
|
|
ev.preventDefault()
|
|
var data = ev.dataTransfer.getData('text')
|
|
dropOnCard(id, data)
|
|
}
|
|
|
|
function returnDrop(ev) {
|
|
ev.preventDefault()
|
|
var data = ev.dataTransfer.getData('text')
|
|
returnToNameBank(data)
|
|
}
|
|
|
|
function returnToNameBank(name) {
|
|
document
|
|
.querySelector('.names-bank')
|
|
.appendChild(document.getElementById(name))
|
|
let prevContainer = document.querySelector('[data-name=' + name + ']')
|
|
if (prevContainer) {
|
|
prevContainer.dataset.name = ''
|
|
wordsLeft += 1
|
|
imagesLeft += 1
|
|
setWordsLeft()
|
|
}
|
|
}
|
|
|
|
function selectName(ev) {
|
|
if (ev.target.parentNode.classList.contains('names-bank')) {
|
|
let nameEl = document.querySelector('.selected')
|
|
if (nameEl) nameEl.classList.remove('selected')
|
|
ev.target.classList.add('selected')
|
|
} else {
|
|
returnToNameBank(ev.target.id)
|
|
}
|
|
}
|
|
|
|
function dropSelected(ev, id) {
|
|
ev.preventDefault()
|
|
let nameEl = document.querySelector('.selected')
|
|
window.console.log('drop selected', nameEl)
|
|
if (!nameEl) return
|
|
nameEl.classList.remove('selected')
|
|
dropOnCard(id, nameEl.id)
|
|
}
|
|
|
|
function dropOnCard(id, data) {
|
|
let target = document.getElementById('card-' + id)
|
|
target.appendChild(document.getElementById(data))
|
|
// if this already has a name, remove that name
|
|
if (target.dataset.name) {
|
|
returnToNameBank(target.dataset.name)
|
|
}
|
|
// remove name data from a previous card if there is one
|
|
let prevContainer = document.querySelector('[data-name=' + data + ']')
|
|
if (prevContainer) {
|
|
prevContainer.dataset.name = ''
|
|
} else {
|
|
wordsLeft -= 1
|
|
imagesLeft -= 1
|
|
setWordsLeft()
|
|
}
|
|
target.dataset.name = data
|
|
}
|
|
|
|
function setWordsLeft() {
|
|
cardName = 'Unused Card Names: '
|
|
if (whichGuesser === 'basic') {
|
|
cardName = 'Unused Set Names: '
|
|
}
|
|
document.getElementById('words-left').innerText =
|
|
cardName + wordsLeft + '/Images: ' + imagesLeft
|
|
}
|