+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();