MTG Find Card At Random

by skibulk

HTML

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>MTG Find Card At Random</title>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"
    />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css"
    />
  </head>
  <body>
    <p>
      <a target="_blank" href="about:blank"><button class="green">About</button></a>
    </p>
    <p id="loading">Loading...</p>
    <div id="loaded" class="hidden">
      <p>Name Pool: <span id="cardNamePool"></span></p>
      <hr>
      <p><button id="getName">Get Name</button></p>
      <p><button id="resetNames" disabled>Reset Names</button></p>
      <p>Random Name:</p>

      <div #swiperRef="" class="swiper mySwiper">
        <div class="swiper-wrapper">
          <div class="swiper-slide">
            <p>...</p>
            <p><img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="></p>
          </div>
        </div>
        <div id="next" class="swiper-button-next"></div>
        <div id="prev" class="swiper-button-prev"></div>
      </div>

      <hr>
      <p><button id="getPool">Get Pool</button></p>
      <p><button id="resetPools" disabled>Reset Pools</button></p>
      <p>Choices at Random: <span id="choicesAtRandom">0</span></p>
      <p>Copies of Pool: <span id="copiesOfPool">0</span></p>
    </div>
    
    <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
  </body>
</html>

CSS

body, p, button {
  margin: 0;
  text-align: center;
	font-family: Arial,Helvetica Neue,Helvetica,sans-serif;
  font-size: 1.2rem;
  line-height: 2.5rem;
}

body{
  margin: 10px 0;
}

.hidden {
  display: none;
}

hr {
  height: 3px;
  margin: 15px 0;
  border: 0;
  background: linear-gradient(to right, white, lightgray, white);
}

button {
  width: 396px;
  height: 60px;
  margin: 5px auto;
  border: 0;
  border-radius: 20px;
  padding: 0 40px 0 40px;
  color: white;
  background-image: linear-gradient(#0070C9, #42A1EC);
  cursor:pointer;
}

button.green {
  background-image: linear-gradient(#00CDAC, #02AAB0);
}

button[disabled]{
  opacity: 0.6;
}

.swiper {
  min-width: 396px;
  user-select: none;
}

.swiper a {
  color: #0070C9;
}

.swiper img {
  width: 396px;
  height: 552px;
  border: none;
  border-radius: 20px;
  background: #DDD;
  margin: 0 auto;
}

JavaScript

;(function () {
  "use strict"
  console.clear()

  // Disable logging to improve performance in production
  //console.log = console.warn = function(){}

  // To-Do
  // Flippable DFCs
  // Exclude Celebration / Unknown / Heroes of the Realm
  // Rename Vars, Comment Code
  // Publish

  console.log("DLoD Initializing")

  let elements = {}
  document.body.querySelectorAll("[id]").forEach((el) => {
    elements[el.id] = el
  })

  // Includes cards that start the game in any zone (Library, Scheme, etc.)
  // Excludes lands even if they have a nonland name (DFCs, etc.)
  // Includes Essence of Ajani
  let queryPrimaryNames =
    "game:paper include:extras -type:card -type:token -layout:token -layout:reversible_card -type:land -type:sticker -(type:emblem mv=0)"

  // Includes Double Faced Cards, Split Cards, Adventure Cards
  // Includes lands only if they have a nonland name (DFCs, etc.)
  // Includes Ormendahl, Profane Prince and Value Town
  let querySecondaryNames =
    'game:paper include:extras "//" -type:card -type:token -layout:reversible_card (-type:land or c>c)'

  let primaryNameCount
  let secondaryNameCount
  let totalNameCount

  // NAME VARIABLES ============================================================

  let resultsPerPage = 175
  let swiper
  let swiperSlideCount = 0

  // POOL VARIABLES ============================================================

  let choicesPerClick = 500000
  let allPickedCards
  let setsProgress = new Array(256).fill(0)
  let cleanThreshold = 20
  let cleanArray = new Array(cleanThreshold).fill(0)
  let totalPickCount = 0
  let setsCompleted = 0
  let ignoredCardCount = 0

  // GET SCRYFALL DATA =========================================================

  scryfall(queryPrimaryNames)
    .then((primaryData) => {
      primaryNameCount = primaryData.total_cards
      return scryfall(querySecondaryNames)
    })
    .then((secondaryData) => {
      secondaryNameCount = secondaryData.total_cards
      enableUI()
    })
   ...