Skip to content

Instantly share code, notes, and snippets.

@henryamster
Created August 3, 2019 04:41

Revisions

  1. henryamster created this gist Aug 3, 2019.
    7 changes: 7 additions & 0 deletions generic-match-game.markdown
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    Generic Match Game
    ------------------


    A [Pen](https://codepen.io/henryamster/pen/EqwZEM) by [Henry Fritz](https://codepen.io/henryamster) on [CodePen](https://codepen.io).

    [License](https://codepen.io/henryamster/pen/EqwZEM/license).
    69 changes: 69 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    <div class="container ">
    <div class="columns">

    <div class="column is-8 is-offset-2 ">
    <h1 id="title" class="is-size-1 has-text-centered "> Generic Match Game</h1>

    <p id="record " class="has-text-centered">Record: <span id="gp">0</span> rounds played. <span id="gw">0</span> correct.</p>
    <br/>
    <a class="is-size-3 has-text-centered" id="addTermTrigger">&bull;Add Term?</a>
    <p class="has-text-centered box has-background-sas is-hidden" id="addTermContainer"> <label for="term" class="has-text-centered">Term:</label><br/> <input class="input" type="text" name="term" id="term" placeholder="Text input">
    <label for="definition">Definition:</label>
    <textarea class="textarea" placeholder="Text input" name="definition" id="definition"></textarea>
    <br/>
    <a id="addTerm" class="button is-dark">Add term</a>

    </p>
    <br/>

    <a class="is-size-3 has-text-centered" id="importExportTrigger">&bull;Import/Export Data Set?</a>
    <div class="has-text-centered box is-centered has-background-sas is-hidden" id="importExportContainer">
    <div class="file is-centered">
    <label class="file-label">
    <input class="file-input" type="file" name="docpicker" id="docpicker">
    <span class="file-cta">
    <span class="file-icon">
    <i class="fas fa-upload"></i>
    </span>
    <span class="file-label">
    Choose a file…
    </span>
    </span>
    </label>
    </div>
    <br/>
    <a id="import" class="button is-dark">Import File</a>
    <a id="export" class="button is-dark">Save File</a>

    </div>

    <p class="has-text-centered" id="paContainer"> <a id="playAgain" class="is-centered is-size-3">Play again?</a></p>



    <div class="box inverse" id="def"><h3 class="is-size-3" id="schema">Definition:</h3>
    <p id="description">description goes here</p>
    </div>

    <div id="answers" class="columns answers is-centered">
    <a class=" column answer inverse " id="a1">answer 1</a>
    <a class=" column answer inverse " id="a2">answer 2</a>
    <a class=" column answer inverse " id="a3">answer 3</a>
    <a class=" column answer inverse " id="a4">answer 4</a>
    </div>

    <div class="results">
    <h4 id="result" class="has-text-centered">choose</h4>
    </div>

    <p class="has-text-centered is-size-7">a fun matching game template designed by
    <a href="https://henryfritz.xyz/"> Henry Fritz</a>
    </p>
    </div>





    </div>
    </div>
    220 changes: 220 additions & 0 deletions script.babel
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,220 @@
    /**
    Data
    */
    let labels =[];
    let descrips=[];

    let numOfTerms =labels.length;


    /**
    Classes
    */
    class Player {
    constructor() {
    this.score = 0;
    this.rounds = 0;
    }

    winRound() {
    this.score++;
    this.rounds++;
    }
    loseRound() {
    this.rounds++;
    }
    updateStats() {
    $("gp").textContent = this.rounds;
    $("gw").textContent = this.score;
    }
    }

    class Round {
    numOfTerms =labels.length;
    constructor(player) {
    this.enabled = true;
    this.result = "";
    this.id = Math.floor(Math.random() * numOfTerms);
    this.genRandos = function() {
    let randos = new Array();
    for (var i = 0; i < 3; i++) {
    randos.push(Math.floor(Math.random() * numOfTerms));
    }
    return randos;
    };
    $("def").classList.remove("has-background-success");
    $("def").classList.remove("has-background-danger");
    for (let i = 1; i < 5; i++) {
    $(`a${i}`).classList.remove("has-background-success");
    $(`a${i}`).classList.remove("has-background-danger");
    $("schema").textContent = "Definition:";
    }
    this.randos = this.genRandos();
    this.generateNew();
    }
    generateNew() {
    $("description").innerHTML = descrips[this.id];
    this.randos.push(this.id);
    let shuffy = shuffle(this.randos);
    for (let i = 1; i < 5; i++) {
    $(`a${i}`).textContent = labels[shuffy[i - 1]];
    $(`a${i}`).setAttribute("data-id", shuffy[i - 1]);
    }
    this.listenForAnswer();
    }

    checkAnswer(e) {
    if (this.enabled) {
    let gameResult =
    e.getAttribute("data-id") == this.id ? "Correct" : "Incorrect";
    e.classList.add(
    gameResult == "Correct"
    ? "has-background-success"
    : "has-background-danger"
    );
    $("def").classList.add(
    gameResult == "Correct"
    ? "has-background-success"
    : "has-background-danger"
    );

    $("schema").textContent = `${e.text}:`;
    this.result = gameResult;
    $("result").textContent = this.result;
    this.enabled = false;
    $("playAgain").style.visibility = "visible";
    this.result == "Correct" ? player.winRound() : player.loseRound();
    player.updateStats();
    }
    }

    listenForAnswer() {
    $("answers").addEventListener("click", e => {
    this.checkAnswer(e.target);
    });
    }
    }

    const player = new Player();
    let round = new Round(player);

    /**
    Global Watcher
    */
    $("playAgain").addEventListener("click", () => {
    if (round.result != "") {
    round = new Round();
    }
    });

    /**
    Helper Functions
    */

    function $(e) {
    return document.getElementById(e);
    }

    function shuffle(array) {
    for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }
    return array;
    }

    function createNewTerm(label, descrip){
    if (label != '' & descrip != ''){
    labels.push(label);
    descrips.push(descrip);
    return true;
    }
    else{
    return false;
    }
    }
    function downloadTerms(){
    let terms = {
    labels: labels,
    descrips: descrips,
    }
    download(JSON.stringify(terms, null, 4), 'terms.json');
    }


    function parseJSONLocally() {
    let localFile;
    var x = $("docpicker");
    reader = new FileReader();
    reader.onload = event => {
    localFile = parseLocalFile(event.target.result);
    sendTerms(localFile);
    };
    reader.onerror = error => reject(error);
    reader.readAsText(x.files[0]);
    }

    /**
    * Returns ruleset as global rules object
    * @param {Object} ruleSet
    * @returns {Object} rules
    */
    function sendTerms(file) {
    console.log(file);
    for(lbl in file.labels){
    labels.push(file.labels[lbl]);
    }
    for (desc in file.descrips){
    descrips.push(file.descrips[desc]);
    }
    numOfTerms =labels.length;
    round = new Round(player);

    }

    /**
    * @param {Object} file: stringified JSON
    */
    function parseLocalFile(file) {
    return JSON.parse(file);
    }

    /**
    * Downloads content locally to a file of type app/json
    * @param {String} content: stringified JSON content to be downloaded
    * @param {String} filename: name of downloaded file
    */
    function download(content, filename) {
    var a = document.createElement("a");
    var blob = new Blob([content], { type: "application/json" });
    a.href = window.URL.createObjectURL(blob);
    a.download = filename;
    a.click();
    }

    $('importExportTrigger').addEventListener('click', ()=>{
    $('importExportContainer').classList.toggle('is-hidden');
    })

    $('addTermTrigger').addEventListener('click', ()=>{
    $('addTermContainer').classList.toggle('is-hidden');
    })

    $('addTerm').addEventListener('click', ()=>{
    createNewTerm($('term').value,
    $('definition').value);
    $('term').value='';
    $('definition').value='';
    numOfTerms =labels.length
    round = new Round(player);
    })
    $('export').addEventListener('click', ()=>{
    downloadTerms();
    })
    $('import').addEventListener('click', ()=>{
    parseJSONLocally();


    })
    78 changes: 78 additions & 0 deletions style.scss
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,78 @@
    @import url('https://fonts.googleapis.com/css?family=Major+Mono+Display|Space+Mono&display=swap');
    $primary: rgb(255, 159, 140);
    $inverse: invert($primary);

    .has-background-sas{
    background:$inverse;
    color:$primary;
    }
    .container{
    font-family: 'Space Mono';
    background:$primary;
    color:$inverse;
    min-height:100vh;
    }
    .inverse{
    background:$inverse;
    color:$primary;
    }

    #title{
    padding-top:100px;
    font-family:'Major Mono Display';
    }
    #result{
    padding-top:25px;
    border-top: 5px solid $inverse;

    font-family:'Major Mono Display';
    font-size:3em;
    }
    #def{
    margin-top:60px;
    margin-bottom:60px;
    }
    body{
    background:$inverse;
    }
    .answer{
    margin-top:12px;
    width: auto;
    min-width:60px;
    border-radius:5px;
    padding:12px;
    text-align:center;
    &:hover{
    color:$inverse;
    background:$primary;

    box-shadow:2px -4px $inverse;
    }
    }
    #paContainer{
    margin-top:20px;
    }
    #playAgain{
    color:$primary;
    background:$inverse;
    padding:4px;
    border-radius:4px;
    visibility:hidden;
    margin: 0 auto;
    }
    input[type="text"]{
    font-family:'Space Mono';
    background:$primary;
    color:$inverse;
    &::placeholder{
    color:$inverse;
    }
    }
    textarea.textarea{
    font-family:'Space Mono' ;
    background:$primary;
    color:$inverse;
    &::placeholder{
    color:$inverse;
    }
    }
    2 changes: 2 additions & 0 deletions styles
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" rel="stylesheet" />