Skip to content

Instantly share code, notes, and snippets.

@henryamster
Created August 3, 2019 04:41
Show Gist options
  • Save henryamster/ac5118b321142f47b18f2de6d0b654d4 to your computer and use it in GitHub Desktop.
Save henryamster/ac5118b321142f47b18f2de6d0b654d4 to your computer and use it in GitHub Desktop.
Generic Match Game
<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>
/**
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();
})
@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;
}
}
<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" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment