index: release v1.18 with only altgr index linked
[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                         this.log('pick', target.id, target.index);
9                 }
10                 else if (this.turned.length < 2) {
11                         return; // keep open
12                 }
13
14                 if (this.turned.length <= 1) {
15                         return; // first choice
16                 }
17
18                 // compare two cards
19                 let match = !this.pairs ? this.turned[0].id == this.turned[1].id : (
20                         this.pairs[this.turned[0].id] == this.turned[1].id
21                         || this.pairs[this.turned[1].id] == this.turned[0].id
22                 );
23                 if (!match && !this.turned[0].classList.contains('bad')) {
24                         put(this.turned[0], '.bad'); // indicate failure on first card
25                         return;
26                 }
27
28                 if (match) {
29                         // lock both as correct
30                         this.turned.forEach(card => put(card, '.good![onclick]'));
31                         this.turned = [];
32                         if (Array.from(this.form.children).every(card => card.classList.contains('good'))) {
33                                 put(this.form, '.good');
34                                 this.stop('done');
35                         }
36                         return;
37                 }
38
39                 // fold back earlier cards
40                 this.turned.splice(0, 2)
41                 .forEach(card => put(card, '!.turn!.bad'));
42         }
43
44         load() {
45                 this.configure();
46                 if (this.preset.pairs) {
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                 else {
54                         super.load();
55                 }
56         }
57
58         setup() {
59                 super.setup();
60                 this.turned = [];
61                 this.form.innerHTML = '';
62                 this.form.className = '';
63
64                 let cards;
65                 if (this.words) {
66                         const aspect = this.form.clientWidth / window.innerHeight;
67                         //TODO image ratio
68                         let count = parseInt(this.preset.n) || 35;
69                         let cols = Math.round(Math.sqrt(count) * aspect**.5);
70                         count = cols * Math.ceil(count / cols);
71                         this.form.style['grid-template-columns'] = `repeat(${cols}, 1fr)`;
72                         cards = this.words.splice(0, count>>1).map(row => row.imgid);
73                         cards.push(...cards.map(val => -val));
74                 }
75                 else {
76                         cards = Object.entries(this.pairs).flat()
77                                 .map(e => e.toString())
78                 }
79
80                 cards.shuffle().forEach((word, seq) => {
81                         let ref = Math.abs(word);
82                         put(this.form,
83                                 'figure>img[src=$]<', `/data/word/32/${ref}.jpg`, {
84                                         onclick: e => this.turn(e),
85                                         id: ref,
86                                         className: word < 0 ? 'mirror' : '',
87                                         index: seq,
88                                 }
89                         );
90                 });
91         }
92 };