37 lines
1.3 KiB
JavaScript
37 lines
1.3 KiB
JavaScript
|
|
// Логіка міні-ігор — чисті функції, без DOM, тестуються в node.
|
|||
|
|
const MG_SYMBOLS = ['▲', '●', '■', '◆', '✚', '★'];
|
|||
|
|
|
|||
|
|
// Детермінований ГПВЧ (mulberry32)
|
|||
|
|
function mulberry32(seed) {
|
|||
|
|
return function () {
|
|||
|
|
seed |= 0; seed = seed + 0x6D2B79F5 | 0;
|
|||
|
|
let t = Math.imul(seed ^ seed >>> 15, 1 | seed);
|
|||
|
|
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|||
|
|
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Аналітик: згенерувати код доступу довжиною len із MG_SYMBOLS
|
|||
|
|
function seqGen(seed, len) {
|
|||
|
|
const r = mulberry32(seed);
|
|||
|
|
return Array.from({ length: len }, () => Math.floor(r() * MG_SYMBOLS.length));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Введене — коректний префікс коду?
|
|||
|
|
function seqPrefixOk(seq, input) {
|
|||
|
|
return input.every((v, i) => v === seq[i]);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Польовий: позиція маркера 0..100 (трикутна хвиля, період period мс)
|
|||
|
|
function triPos(t, period) {
|
|||
|
|
const ph = ((t % period) + period) % period / period;
|
|||
|
|
return (ph < 0.5 ? ph * 2 : 2 - ph * 2) * 100;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Маркер у зоні [start, start+width]?
|
|||
|
|
function inZone(pos, start, width) {
|
|||
|
|
return pos >= start && pos <= start + width;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (typeof module !== 'undefined') module.exports = { MG_SYMBOLS, mulberry32, seqGen, seqPrefixOk, triPos, inZone };
|