45 lines
1.6 KiB
JavaScript
45 lines
1.6 KiB
JavaScript
import { CHROMATIC, NATURAL, getNoteAt, getAnswerChoices } from './music.js';
|
|
import { FRET_COUNT } from './fretboard.js';
|
|
|
|
export function genMode1Question(numStrings, naturalOnly) {
|
|
let stringIdx, fret, note;
|
|
let attempts = 0;
|
|
do {
|
|
stringIdx = Math.floor(Math.random() * numStrings);
|
|
fret = Math.floor(Math.random() * (FRET_COUNT + 1));
|
|
note = getNoteAt(stringIdx, fret, numStrings);
|
|
attempts++;
|
|
} while (naturalOnly && !NATURAL.includes(note) && attempts < 100);
|
|
|
|
const choices = getAnswerChoices(note, naturalOnly);
|
|
return { stringIdx, fret, note, choices };
|
|
}
|
|
|
|
export function genMode2Question(numStrings, naturalOnly) {
|
|
const pool = naturalOnly ? NATURAL : CHROMATIC;
|
|
const targetNote = pool[Math.floor(Math.random() * pool.length)];
|
|
|
|
const rangeLen = Math.random() < 0.5 ? 4 : 5;
|
|
const fretStart = Math.floor(Math.random() * (FRET_COUNT - rangeLen + 1));
|
|
const fretEnd = fretStart + rangeLen;
|
|
|
|
const correctSet = new Set();
|
|
for (let s = 0; s < numStrings; s++) {
|
|
for (let f = fretStart; f <= fretEnd; f++) {
|
|
if (getNoteAt(s, f, numStrings) === targetNote) {
|
|
correctSet.add(`${s},${f}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
return { targetNote, fretStart, fretEnd, correctSet };
|
|
}
|
|
|
|
export function evaluateMode2(selection, correctSet) {
|
|
const allCorrect = [...correctSet].every(k => selection.has(k)) &&
|
|
[...selection].every(k => correctSet.has(k));
|
|
const missed = [...correctSet].filter(k => !selection.has(k)).length;
|
|
const extra = [...selection].filter(k => !correctSet.has(k)).length;
|
|
return { allCorrect, missed, extra };
|
|
}
|