word/memory: mirrored duplication of unpaired images
[sheet.git] / word / memory.js
1 class WordMemory extends WordQuiz {
2         turn(click) {
3                 let target = click.currentTarget;
4                 if (!target.classList.contains('turn')) {
5                         // show an open card
6                         this.turned.push(target);
7                         put(target, '.turn');
8                 }
9                 else if (this.turned.length < 2) {
10                         return; // keep open
11                 }
12
13                 if (this.turned.length <= 1) {
14                         return; // first choice
15                 }
16
17                 // compare two cards
18                 let match = !this.pairs ? this.turned[0].id == this.turned[1].id : (
19                         this.pairs[this.turned[0].id] == this.turned[1].id
20                         || this.pairs[this.turned[1].id] == this.turned[0].id
21                 );
22                 if (!match && !this.turned[0].classList.contains('bad')) {
23                         put(this.turned[0], '.bad'); // indicate failure on first card
24                         return;
25                 }
26
27                 if (match) {
28                         // lock both as correct
29                         this.turned.forEach(card => put(card, '.good![onclick]'));
30                         this.turned = [];
31                         if (Array.from(this.form.children).every(card => card.classList.contains('good'))) {
32                                 put(this.form, '.good');
33                         }
34                         return;
35                 }
36
37                 // fold back earlier cards
38                 this.turned.splice(0, 2)
39                 .forEach(card => put(card, '!.turn!.bad'));
40         }
41
42         load(dataurl) {
43                 if (dataurl) {
44                         super.load(dataurl);
45                 }
46                 else {
47                         this.dataurl = '/data/wordpairs.json';
48                         fetch(this.dataurl).then(res => res.json()).then(pairs => {
49                                 this.pairs = pairs;
50                                 this.setup();
51                         });
52                 }
53         }
54
55         setup() {
56                 this.turned = [];
57                 this.form = document.getElementById('quiz');
58
59                 let cards;
60                 if (this.words) {
61                         cards = this.words.splice(0, 6).map(row => row[2]);
62                         cards.push(...cards.map(val => -val));
63                 }
64                 else {
65                         cards = Object.entries(this.pairs).flat()
66                                 .map(e => e.toString())
67                 }
68
69                 cards.shuffle().forEach(word => {
70                         let ref = Math.abs(word);
71                         put(this.form,
72                                 'figure>img[src=$]<', `/data/word/en/${ref}.jpg`,
73                                 {onclick: e => this.turn(e), id: ref, className: word < 0 ? 'mirror' : ''}
74                         );
75                 });
76         }
77 };