Host Ida and Alex's MTG Guesser game (#656)
* Copy over code from Mtg Guesser * Run Prettier * CSS Tweaks: Hover feedback, button positioning * Hide all but counterspell & burn, for now * Move to /mtg directory * Fix prettierignore * smaller jsons (#673) limited burn to only red cards and also added limited json files to only have fields needed to play * Add Ida's tweak to card position Co-authored-by: marsteralex <bob.masteralex@gmail.com>
This commit is contained in:
parent
528dd2b28a
commit
a3f150b1d9
|
@ -1,3 +1,4 @@
|
||||||
# Ignore Next artifacts
|
# Ignore Next artifacts
|
||||||
.next/
|
.next/
|
||||||
out/
|
out/
|
||||||
|
public/**/*.json
|
362
web/public/mtg/app.js
Normal file
362
web/public/mtg/app.js
Normal file
|
@ -0,0 +1,362 @@
|
||||||
|
mode = 'PLAY'
|
||||||
|
allData = {}
|
||||||
|
total = 0
|
||||||
|
unseenTotal = 0
|
||||||
|
probList = []
|
||||||
|
nameList = []
|
||||||
|
k = 12
|
||||||
|
extra = 3
|
||||||
|
artDict = {}
|
||||||
|
totalCorrect = 0
|
||||||
|
totalSeen = 0
|
||||||
|
wordsLeft = k + extra
|
||||||
|
imagesLeft = k
|
||||||
|
maxRounds = 20
|
||||||
|
whichGuesser = 'counterspell'
|
||||||
|
un = false
|
||||||
|
online = false
|
||||||
|
firstPrint = false
|
||||||
|
flag = true
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let firstFetch = fetch('jsons/' + whichGuesser + page + '.json')
|
||||||
|
fetchToResponse(firstFetch)
|
||||||
|
|
||||||
|
function putIntoMapAndFetch(data) {
|
||||||
|
putIntoMap(data.data)
|
||||||
|
if (data.has_more) {
|
||||||
|
page += 1
|
||||||
|
window.setTimeout(() =>
|
||||||
|
fetchToResponse(fetch('jsons/' + whichGuesser + page + '.json'))
|
||||||
|
)
|
||||||
|
} 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 === 'beast') {
|
||||||
|
document.getElementById('guess-type').innerText =
|
||||||
|
'Finding Fantastic Beasts'
|
||||||
|
} else if (whichGuesser === 'terror') {
|
||||||
|
document.getElementById('guess-type').innerText =
|
||||||
|
"I'm a Terror-able Guesser"
|
||||||
|
} else if (whichGuesser === 'wrath') {
|
||||||
|
document.getElementById('guess-type').innerText = "I'll Clean Sweep"
|
||||||
|
} else if (whichGuesser === 'burn') {
|
||||||
|
document.getElementById('guess-type').innerText = 'Match With Hot Singles'
|
||||||
|
}
|
||||||
|
setUpNewGame()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getKSamples() {
|
||||||
|
let usedCounters = new Set()
|
||||||
|
let currentTotal = unseenTotal
|
||||||
|
let samples = {}
|
||||||
|
let i = 0
|
||||||
|
while (i < k) {
|
||||||
|
let rand = Math.floor(Math.random() * currentTotal)
|
||||||
|
let count = 0
|
||||||
|
for (const [key, value] of Object.entries(allData)) {
|
||||||
|
if (usedCounters.has(key)) {
|
||||||
|
continue
|
||||||
|
} else if (count >= rand) {
|
||||||
|
usedCounters.add(key)
|
||||||
|
currentTotal -= value.length
|
||||||
|
unseenTotal--
|
||||||
|
let randIndex = Math.floor(Math.random() * value.length)
|
||||||
|
let arts = allData[key].splice(randIndex, 1)
|
||||||
|
samples[arts[0].artImg] = [key, arts[0].normalImg]
|
||||||
|
i++
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
count += value.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const key of usedCounters) {
|
||||||
|
if (allData[key].length === 0) {
|
||||||
|
delete allData[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let count = 0
|
||||||
|
while (count < extra) {
|
||||||
|
let rand = Math.floor(Math.random() * total)
|
||||||
|
for (let j = 0; j < nameList.length; j++) {
|
||||||
|
if (j >= rand) {
|
||||||
|
if (usedCounters.has(nameList[j])) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
usedCounters.add(nameList[j])
|
||||||
|
count += 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [samples, usedCounters]
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (!online) {
|
||||||
|
if (card.digital) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (firstPrint) {
|
||||||
|
if (
|
||||||
|
card.reprint === true ||
|
||||||
|
(card.frame_effects && card.frame_effects.includes('showcase'))
|
||||||
|
) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// reskinned card names show in art crop
|
||||||
|
if (card.flavor_name) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// don't include racist cards
|
||||||
|
return card.content_warning
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
// 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.innerText = namesList[nameIndex - 1]
|
||||||
|
nameBank.appendChild(currName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
let guess = document.getElementById(currCard.dataset.name).innerText
|
||||||
|
// window.console.log(artDict[currCard.dataset.url][0], guess);
|
||||||
|
incorrect = artDict[currCard.dataset.url][0] !== guess
|
||||||
|
// decide if their guess was correct
|
||||||
|
}
|
||||||
|
if (incorrect) currCard.classList.add('incorrect')
|
||||||
|
// tally some kind of score
|
||||||
|
if (incorrect) score--
|
||||||
|
// 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() {
|
||||||
|
document.getElementById('words-left').innerText =
|
||||||
|
'Unused Card Names: ' + wordsLeft + '/Images: ' + imagesLeft
|
||||||
|
}
|
225
web/public/mtg/choose.html
Normal file
225
web/public/mtg/choose.html
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Google Tag Manager -->
|
||||||
|
<script>
|
||||||
|
;(function (w, d, s, l, i) {
|
||||||
|
w[l] = w[l] || []
|
||||||
|
w[l].push({
|
||||||
|
'gtm.start': new Date().getTime(),
|
||||||
|
event: 'gtm.js',
|
||||||
|
})
|
||||||
|
var f = d.getElementsByTagName(s)[0],
|
||||||
|
j = d.createElement(s),
|
||||||
|
dl = l !== 'dataLayer' ? '&l=' + l : ''
|
||||||
|
j.async = true
|
||||||
|
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl
|
||||||
|
f.parentNode.insertBefore(j, f)
|
||||||
|
})(window, document, 'script', 'dataLayer', 'GTM-M3MBVGG')
|
||||||
|
</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h3 {
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px 20px;
|
||||||
|
background-color: cadetblue;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit:hover {
|
||||||
|
background-color: rgb(0, 146, 156);
|
||||||
|
}
|
||||||
|
|
||||||
|
[type='radio'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type='radio'] + label.radio-label {
|
||||||
|
background: lightgrey;
|
||||||
|
display: block;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.radio-label:hover {
|
||||||
|
background: darkgrey;
|
||||||
|
}
|
||||||
|
|
||||||
|
[type='radio']:checked + label.radio-label {
|
||||||
|
background: lightcoral;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-label h3 {
|
||||||
|
margin: 0;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumbnail {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 67px;
|
||||||
|
height: 48px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 70px 0 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addl-options {
|
||||||
|
position: absolute;
|
||||||
|
top: 30px;
|
||||||
|
right: 30px;
|
||||||
|
background-color: white;
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#addl-options > summary {
|
||||||
|
list-style: none;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Google Tag Manager (noscript) -->
|
||||||
|
<noscript>
|
||||||
|
<iframe
|
||||||
|
src="https://www.googletagmanager.com/ns.html?id=GTM-M3MBVGG"
|
||||||
|
height="0"
|
||||||
|
width="0"
|
||||||
|
style="display: none; visibility: hidden"
|
||||||
|
></iframe>
|
||||||
|
</noscript>
|
||||||
|
<!-- End Google Tag Manager (noscript) -->
|
||||||
|
<h1>Magic the Guessering</h1>
|
||||||
|
<div class="play-page" style="justify-content: center">
|
||||||
|
<form
|
||||||
|
method="get"
|
||||||
|
action="index.html"
|
||||||
|
style="display: flex; flex-direction: column; align-items: center"
|
||||||
|
>
|
||||||
|
<!-- <input type="radio" id="wrath" name="whichguesser" value="wrath" />
|
||||||
|
<label class="radio-label" for="wrath">
|
||||||
|
<img
|
||||||
|
class="thumbnail"
|
||||||
|
src="https://c1.scryfall.com/file/scryfall-cards/art_crop/front/0/6/0619d670-7b53-4185-a25d-2fab5db1aab5.jpg?1562896185"
|
||||||
|
/>
|
||||||
|
<h3>I'll Clean Sweep</h3></label
|
||||||
|
><br /> -->
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
id="counterspell"
|
||||||
|
name="whichguesser"
|
||||||
|
value="counterspell"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
<label class="radio-label" for="counterspell">
|
||||||
|
<img
|
||||||
|
class="thumbnail"
|
||||||
|
src="https://c1.scryfall.com/file/scryfall-cards/art_crop/front/7/1/71cfcba5-1571-48b8-a3db-55dca135506e.jpg?1562843855"
|
||||||
|
/>
|
||||||
|
<h3>Counterspell Guesser</h3></label
|
||||||
|
><br />
|
||||||
|
|
||||||
|
<!-- <input type="radio" id="terror" name="whichguesser" value="terror" />
|
||||||
|
<label class="radio-label" for="terror">
|
||||||
|
<img
|
||||||
|
class="thumbnail"
|
||||||
|
src="https://c1.scryfall.com/file/scryfall-cards/art_crop/front/2/d/2dd5d601-aff7-4b7a-ab6c-b89f403af076.jpg?1562905752"
|
||||||
|
/>
|
||||||
|
<h3>I'm a Terror-able Guesser</h3></label
|
||||||
|
><br /> -->
|
||||||
|
|
||||||
|
<input type="radio" id="burn" name="whichguesser" value="burn" />
|
||||||
|
<label class="radio-label" for="burn">
|
||||||
|
<img
|
||||||
|
class="thumbnail"
|
||||||
|
src="https://c1.scryfall.com/file/scryfall-cards/art_crop/front/6/0/60b2fae1-242b-45e0-a757-b1adc02c06f3.jpg?1562760596"
|
||||||
|
/>
|
||||||
|
<h3>Match With Hot Singles</h3></label
|
||||||
|
><br />
|
||||||
|
|
||||||
|
<!-- <input type="radio" id="beast" name="whichguesser" value="beast" />
|
||||||
|
<label class="radio-label" for="beast">
|
||||||
|
<img
|
||||||
|
class="thumbnail"
|
||||||
|
src="https://c1.scryfall.com/file/scryfall-cards/art_crop/front/3/3/33f7e788-8fc7-49f3-804b-2d7f96852d4b.jpg?1562905469"
|
||||||
|
/>
|
||||||
|
<h3>Finding Fantastic Beasts</h3></label
|
||||||
|
>
|
||||||
|
<br /> -->
|
||||||
|
|
||||||
|
<details id="addl-options">
|
||||||
|
<summary>
|
||||||
|
<img
|
||||||
|
src="http://mythicspoiler.com/images/buttons/ustset.png"
|
||||||
|
style="width: 32px; vertical-align: top"
|
||||||
|
/>
|
||||||
|
Options
|
||||||
|
</summary>
|
||||||
|
<input type="checkbox" name="digital" id="digital" checked />
|
||||||
|
<label for="digital">include digital cards</label>
|
||||||
|
<br />
|
||||||
|
<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>
|
||||||
|
</details>
|
||||||
|
<input type="submit" id="submit" value="Play" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="margin: -40px 0 0; height: 60px">
|
||||||
|
<a href="https://paypal.me/idamayer">Donate, buy us a boba 🧋</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
font-size: 0.9em;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
color: grey;
|
||||||
|
font-style: italic;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
made by
|
||||||
|
<a
|
||||||
|
style="color: rgb(0, 146, 156); font-style: italic"
|
||||||
|
href="https://idamayer.com"
|
||||||
|
>Ida Mayer</a
|
||||||
|
>
|
||||||
|
& Alex Lien 2022
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
92
web/public/mtg/importCards.py
Normal file
92
web/public/mtg/importCards.py
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
import time
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
# add category name here
|
||||||
|
allCategories = ['counterspell', 'beast', 'terror', 'wrath', 'burn']
|
||||||
|
|
||||||
|
|
||||||
|
def generate_initial_query(category):
|
||||||
|
string_query = 'https://api.scryfall.com/cards/search?q='
|
||||||
|
if category == 'counterspell':
|
||||||
|
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 == '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' \
|
||||||
|
'.*player%28%5C.%7C+or+planeswalker%29%7C.*opponent%28%5C.%7C+or+planeswalker%29%29%2F%29' \
|
||||||
|
'+%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='
|
||||||
|
print(string_query)
|
||||||
|
return string_query
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_and_write_all(category, query):
|
||||||
|
count = 1
|
||||||
|
will_repeat = True
|
||||||
|
while will_repeat:
|
||||||
|
will_repeat = fetch_and_write(category, query, count)
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
|
||||||
|
def fetch_and_write(category, 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']
|
||||||
|
|
||||||
|
|
||||||
|
def to_compact_write_form(response):
|
||||||
|
fieldsToUse = ['has_more']
|
||||||
|
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']:
|
||||||
|
write_card = dict()
|
||||||
|
for field in fieldsInCard:
|
||||||
|
if field == 'name' and 'card_faces' in card:
|
||||||
|
write_card['name'] = card['card_faces'][0]['name']
|
||||||
|
elif field == 'image_uris':
|
||||||
|
write_card['image_uris'] = write_image_uris(card['image_uris'])
|
||||||
|
elif field in card:
|
||||||
|
write_card[field] = card[field]
|
||||||
|
data.append(write_card)
|
||||||
|
smallJson['data'] = data
|
||||||
|
return smallJson
|
||||||
|
|
||||||
|
|
||||||
|
# only write images needed
|
||||||
|
def write_image_uris(card_image_uris):
|
||||||
|
image_uris = dict()
|
||||||
|
if 'normal' in card_image_uris:
|
||||||
|
image_uris['normal'] = card_image_uris['normal']
|
||||||
|
elif 'large' in card_image_uris:
|
||||||
|
image_uris['normal'] = card_image_uris['large']
|
||||||
|
elif 'small' in card_image_uris:
|
||||||
|
image_uris['normal'] = card_image_uris['small']
|
||||||
|
if card_image_uris:
|
||||||
|
image_uris['art_crop'] = card_image_uris['art_crop']
|
||||||
|
return image_uris
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
for category in allCategories:
|
||||||
|
print(category)
|
||||||
|
fetch_and_write_all(category, generate_initial_query(category))
|
554
web/public/mtg/index.html
Normal file
554
web/public/mtg/index.html
Normal file
|
@ -0,0 +1,554 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<!-- Google Tag Manager -->
|
||||||
|
<script>
|
||||||
|
;(function (w, d, s, l, i) {
|
||||||
|
w[l] = w[l] || []
|
||||||
|
w[l].push({
|
||||||
|
'gtm.start': new Date().getTime(),
|
||||||
|
event: 'gtm.js',
|
||||||
|
})
|
||||||
|
var f = d.getElementsByTagName(s)[0],
|
||||||
|
j = d.createElement(s),
|
||||||
|
dl = l !== 'dataLayer' ? '&l=' + l : ''
|
||||||
|
j.async = true
|
||||||
|
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl
|
||||||
|
f.parentNode.insertBefore(j, f)
|
||||||
|
})(window, document, 'script', 'dataLayer', 'GTM-M3MBVGG')
|
||||||
|
</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script type="text/javascript" src="app.js"></script>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cards-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 230px;
|
||||||
|
height: 208px;
|
||||||
|
border: 5px solid lightgrey;
|
||||||
|
margin: 5px;
|
||||||
|
align-items: flex-end;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 11px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
/*background-size: contain;*/
|
||||||
|
background-size: 220px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
transition: height 1s, background-image 1s, border 0.4s 0.6s;
|
||||||
|
background-position-y: calc(50% - 20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:not([data-name^='name'])::after {
|
||||||
|
content: '';
|
||||||
|
height: 34px;
|
||||||
|
background: white;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .card {
|
||||||
|
height: 350px;
|
||||||
|
/*padding-top: 310px;*/
|
||||||
|
/*background-size: cover;*/
|
||||||
|
overflow: hidden;
|
||||||
|
border-color: rgb(0, 146, 156);
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .card.incorrect {
|
||||||
|
border-color: rgb(216, 27, 96);
|
||||||
|
}
|
||||||
|
|
||||||
|
.names-bank {
|
||||||
|
position: fixed;
|
||||||
|
padding: 10px 10px 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.names-bank .name {
|
||||||
|
margin: 6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .names-bank .name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .names-bank .word-count {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-count {
|
||||||
|
text-align: center;
|
||||||
|
font-style: italic;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.score {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
background-color: rgb(255, 193, 7);
|
||||||
|
width: 200px;
|
||||||
|
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.names-bank .score {
|
||||||
|
overflow: hidden;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .names-bank .score {
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 1.2s 0.2s;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
width: 230px;
|
||||||
|
min-height: 36px;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: lightgrey;
|
||||||
|
padding: 8px 12px 2px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card .name {
|
||||||
|
border-radius: 0 0 5px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 8px 20px;
|
||||||
|
background-color: cadetblue;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 1.1em;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#submit:hover {
|
||||||
|
background-color: rgb(0, 146, 156);
|
||||||
|
}
|
||||||
|
|
||||||
|
#newGame {
|
||||||
|
padding: 8px 20px;
|
||||||
|
background-color: lightpink;
|
||||||
|
border: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 0.7em;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#newGame:hover {
|
||||||
|
background-color: coral;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected {
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (orientation: landscape) and (max-height: 680px) {
|
||||||
|
/* CSS applied when the device is in landscape mode*/
|
||||||
|
.names-bank {
|
||||||
|
padding: 0;
|
||||||
|
top: 0;
|
||||||
|
max-height: 100vh;
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-count {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin-right: 240px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (orientation: portrait) and (max-width: 1100px) {
|
||||||
|
body {
|
||||||
|
font-size: 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.play-page {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.names-bank {
|
||||||
|
flex-direction: row;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
/* position: fixed; */
|
||||||
|
padding: 10px 10px 40px;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .names-bank {
|
||||||
|
min-width: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.names-bank .name {
|
||||||
|
margin: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.names-bank .score {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .names-bank .score {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.word-count {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name {
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
width: 300px;
|
||||||
|
background-size: 300px;
|
||||||
|
height: 266px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.answer-page .card {
|
||||||
|
height: 454px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Google Tag Manager (noscript) -->
|
||||||
|
<noscript>
|
||||||
|
<iframe
|
||||||
|
src="https://www.googletagmanager.com/ns.html?id=GTM-M3MBVGG"
|
||||||
|
height="0"
|
||||||
|
width="0"
|
||||||
|
style="display: none; visibility: hidden"
|
||||||
|
></iframe>
|
||||||
|
</noscript>
|
||||||
|
<!-- End Google Tag Manager (noscript) -->
|
||||||
|
|
||||||
|
<h1><span id="guess-type"></span>: <span id="round-number"></span></h1>
|
||||||
|
|
||||||
|
<div class="play-page">
|
||||||
|
<div
|
||||||
|
class="names-bank"
|
||||||
|
ondrop="returnDrop(event)"
|
||||||
|
ondragover="event.preventDefault()"
|
||||||
|
>
|
||||||
|
<div class="score">
|
||||||
|
YOUR SCORE
|
||||||
|
<div>Correct Answers This Round: <span id="score-amount"></span></div>
|
||||||
|
<div>
|
||||||
|
Correct Answers In Total: <span id="score-amount-total"></span>
|
||||||
|
</div>
|
||||||
|
<div>Overall Percent: <span id="score-percent"></span>%</div>
|
||||||
|
</div>
|
||||||
|
<div class="word-count"><span id="words-left"></span></div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-1"
|
||||||
|
>
|
||||||
|
Name 1
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-2"
|
||||||
|
>
|
||||||
|
Name 2
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-3"
|
||||||
|
>
|
||||||
|
Name 3
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-4"
|
||||||
|
>
|
||||||
|
Name 4
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-5"
|
||||||
|
>
|
||||||
|
Name 5
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-6"
|
||||||
|
>
|
||||||
|
Name 6
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-7"
|
||||||
|
>
|
||||||
|
Name 7
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-8"
|
||||||
|
>
|
||||||
|
Name 8
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-9"
|
||||||
|
>
|
||||||
|
Name 9
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-10"
|
||||||
|
>
|
||||||
|
Name 10
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-11"
|
||||||
|
>
|
||||||
|
Name 11
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-12"
|
||||||
|
>
|
||||||
|
Name 12
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-13"
|
||||||
|
>
|
||||||
|
Name 13
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-14"
|
||||||
|
>
|
||||||
|
Name 14
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="name"
|
||||||
|
draggable="true"
|
||||||
|
ondragstart="drag(event)"
|
||||||
|
onClick="selectName(event)"
|
||||||
|
id="name-15"
|
||||||
|
>
|
||||||
|
Name 15
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<form onsubmit="toggleMode(event)">
|
||||||
|
<div class="cards-container">
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,1)"
|
||||||
|
ondragover="allowDrop(event,1)"
|
||||||
|
onclick="dropSelected(event, 1)"
|
||||||
|
id="card-1"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,2)"
|
||||||
|
ondragover="allowDrop(event,2)"
|
||||||
|
onclick="dropSelected(event, 2)"
|
||||||
|
id="card-2"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,3)"
|
||||||
|
ondragover="allowDrop(event,3)"
|
||||||
|
onclick="dropSelected(event, 3)"
|
||||||
|
id="card-3"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,4)"
|
||||||
|
ondragover="allowDrop(event,4)"
|
||||||
|
onclick="dropSelected(event, 4)"
|
||||||
|
id="card-4"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,5)"
|
||||||
|
ondragover="allowDrop(event,5)"
|
||||||
|
onclick="dropSelected(event, 5)"
|
||||||
|
id="card-5"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event, 6)"
|
||||||
|
ondragover="allowDrop(event,6)"
|
||||||
|
onclick="dropSelected(event,6)"
|
||||||
|
id="card-6"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,7)"
|
||||||
|
ondragover="allowDrop(event,7)"
|
||||||
|
onclick="dropSelected(event, 7)"
|
||||||
|
id="card-7"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,8)"
|
||||||
|
ondragover="allowDrop(event,8)"
|
||||||
|
onclick="dropSelected(event, 8)"
|
||||||
|
id="card-8"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,9)"
|
||||||
|
ondragover="allowDrop(event,9)"
|
||||||
|
onclick="dropSelected(event, 9)"
|
||||||
|
id="card-9"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,10)"
|
||||||
|
ondragover="allowDrop(event,10)"
|
||||||
|
onclick="dropSelected(event, 10)"
|
||||||
|
id="card-10"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,11)"
|
||||||
|
ondragover="allowDrop(event,11)"
|
||||||
|
onclick="dropSelected(event, 11)"
|
||||||
|
id="card-11"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
class="card"
|
||||||
|
ondrop="drop(event,12)"
|
||||||
|
ondragover="allowDrop(event,12)"
|
||||||
|
onclick="dropSelected(event, 12)"
|
||||||
|
id="card-12"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<input type="submit" id="submit" value="Submit" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="position: absolute; top: 0; left: 0; right: 0; color: grey">
|
||||||
|
<form method="get" action="choose.html">
|
||||||
|
<input type="submit" id="newGame" value="New Game" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div style="margin: -40px 0 0; height: 60px">
|
||||||
|
<a href="https://paypal.me/idamayer">Donate, buy us a boba 🧋</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
font-size: 0.9em;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
color: grey;
|
||||||
|
font-style: italic;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
made by
|
||||||
|
<a
|
||||||
|
style="color: rgb(0, 146, 156); font-style: italic"
|
||||||
|
href="https://idamayer.com"
|
||||||
|
>Ida Mayer</a
|
||||||
|
>
|
||||||
|
& Alex Lien 2022
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
web/public/mtg/jsons/beast1.json
Normal file
1
web/public/mtg/jsons/beast1.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/beast2.json
Normal file
1
web/public/mtg/jsons/beast2.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/beast3.json
Normal file
1
web/public/mtg/jsons/beast3.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/burn1.json
Normal file
1
web/public/mtg/jsons/burn1.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/burn2.json
Normal file
1
web/public/mtg/jsons/burn2.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/burn3.json
Normal file
1
web/public/mtg/jsons/burn3.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/counterspell1.json
Normal file
1
web/public/mtg/jsons/counterspell1.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/counterspell2.json
Normal file
1
web/public/mtg/jsons/counterspell2.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/counterspell3.json
Normal file
1
web/public/mtg/jsons/counterspell3.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/terror1.json
Normal file
1
web/public/mtg/jsons/terror1.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/terror2.json
Normal file
1
web/public/mtg/jsons/terror2.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/terror3.json
Normal file
1
web/public/mtg/jsons/terror3.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/wrath1.json
Normal file
1
web/public/mtg/jsons/wrath1.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/wrath2.json
Normal file
1
web/public/mtg/jsons/wrath2.json
Normal file
File diff suppressed because one or more lines are too long
1
web/public/mtg/jsons/wrath3.json
Normal file
1
web/public/mtg/jsons/wrath3.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user