From: Mischa POSLAWSKY Date: Mon, 25 Oct 2021 20:57:11 +0000 (+0200) Subject: word/memory: card game to find matching pairs X-Git-Tag: v1.13~122 X-Git-Url: http://git.shiar.nl/sheet.git/commitdiff_plain/819787ff54335a68b34b7d9729f6d7e28870d8ac word/memory: card game to find matching pairs Another quiz concept well suited to this image dataset. Initially populated with distinct sets of grebes (currently the only untranslated references) to experiment with variance as a somewhat unique selling point. --- diff --git a/Makefile b/Makefile index ad2f7a0..0742e97 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ sitemap.xml: tools/mksitemap light.css: tools/stripcss base.css $(call cmdsave,$^) -word: word/put.js data/wordlist.en.json data/wordlist.nl.json data/wordlist.ru.json +word: word/put.js data/wordlist.en.json data/wordlist.nl.json data/wordlist.ru.json data/wordpairs.json word/put.js: $(download) tools/wget-ifmodified https://github.com/kriszyp/put-selector/raw/master/put.js $@ @@ -73,9 +73,12 @@ data/wordlist.en.inc.pl: tools/mkwordlist data/wordlist.version.txt $(call cmdsave,$<) data/wordlist.%.inc.pl: tools/mkwordlist data/wordlist.version.txt $(call cmdsave,$< $*) -data/wordlist.%.json: data/wordlist.%.inc.pl +data/word%.json: data/word%.inc.pl $(call cmdsave,perl -MJSON=encode_json -E "print encode_json(do \$$ARGV[0])" ./$<) +data/wordpairs.inc.pl: data/wordlist.version.txt + @perl -I. -MShiar_Sheet::DB -MData::Dump=pp -E 'say pp(Shiar_Sheet::DB->connect->select("word w JOIN word a ON w.id=a.ref" => "w.id, a.id", {"a.lang"=>undef})->map or exit 1)' >$@ + .SECONDARY: data/font/%.ttf data/font/%.ttf: find /usr/share/fonts/truetype/ ~/.fonts/ -iname "$(@F)" | head -1 | xargs -i ln -sf {} $@ diff --git a/word/memory.js b/word/memory.js new file mode 100644 index 0000000..0e523a1 --- /dev/null +++ b/word/memory.js @@ -0,0 +1,56 @@ +class WordMemory { + turn(click) { + let target = click.currentTarget; + if (!target.classList.contains('turn')) { + // show an open card + this.turned.push(target); + put(target, '.turn'); + } + else if (this.turned.length < 2) { + return; // keep open + } + + if (this.turned.length <= 1) { + return; // first choice + } + + // compare two cards + let match = this.pairs[this.turned[0].id] == this.turned[1].id + || this.pairs[this.turned[1].id] == this.turned[0].id; + if (!match && !this.turned[0].classList.contains('bad')) { + put(this.turned[0], '.bad'); // indicate failure on first card + return; + } + + if (match) { + // lock both as correct + this.turned.forEach(card => put(card, '.good![onclick]')); + this.turned = []; + return; + } + + // fold back earlier cards + this.turned.splice(0, 2) + .forEach(card => put(card, '!.turn!.bad')); + } + + constructor() { + this.dataurl = '/data/wordpairs.json'; + fetch(this.dataurl).then(res => res.json()).then(pairs => { + this.turned = []; + this.pairs = pairs; + this.form = document.getElementById('quiz'); + this.cards = Object.entries(pairs).flat() + .map(e => e.toString()) + .sort(() => {return .5 - Math.random()}) // shuffle + this.cards.forEach(word => { + put(this.form, + 'figure>img[src=$]<', `/data/word/en/${word}.jpg`, + {onclick: e => this.turn(e), id: word} + ); + }); + }); + } +}; + +new WordMemory(); diff --git a/word/memory.plp b/word/memory.plp new file mode 100644 index 0000000..d12cc75 --- /dev/null +++ b/word/memory.plp @@ -0,0 +1,48 @@ +<(../common.inc.plp)><: + +Html({ + raw => <<'EOT', + + + +EOT +}); +say '

memory

';