Sono un nuovo blocco HTML.
/*
(function (root, factory) {
if (typeof module === 'object' && module.exports) module.exports = factory();
else root.BARRAGE = factory();
})(typeof self !== 'undefined' ? self : this, function () {
var LETTERE = 'ABCDEFGHKLMNPRSTVXZ'.split('');
var COLORI = { rosso: '#c0392b', blu: '#1f5fa8', verde: '#1e8449', nero: '#12202e' };
/* PRNG deterministico (mulberry32): stesso seed => stessa sequenza,
su qualunque motore JavaScript, browser o Node. */
function rng(a) {
return function () {
a |= 0; a = (a + 0x6D2B79F5) | 0;
var t = Math.imul(a ^ (a >>> 15), 1 | a);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
}
/* p = {seed, colonne, righe, densita, regola, distrattori} */
function costruisciMatrice(p) {
var r = rng(p.seed);
var pool = LETTERE.slice();
for (var i = pool.length - 1; i > 0; i--) { // shuffle deterministico
var j = Math.floor(r() * (i + 1));
var tmp = pool[i]; pool[i] = pool[j]; pool[j] = tmp;
}
var targets, coloreTarget = null;
if (p.regola === 'doppia') targets = [pool[0], pool[1]];
else if (p.regola === 'congiunzione') { targets = [pool[0]]; coloreTarget = 'rosso'; }
else targets = [pool[0]];
var distr = pool.slice(2);
var n = p.colonne * p.righe, celle = [];
for (var k = 0; k < n; k++) { var isT=r() < p.densita, ch, col; if (p.regola==='congiunzione' ) { ch=isT ? targets[0] : (r() < 0.5 ? targets[0] : distr[Math.floor(r() * distr.length)]); col=isT ? 'rosso' : ['blu', 'verde' , 'nero' ][Math.floor(r() * 3)]; } else { ch=isT ? targets[Math.floor(r() * targets.length)] : distr[Math.floor(r() * distr.length)]; col=p.distrattori> 0 ? ['nero', 'blu', 'verde', 'rosso'][Math.floor(r() * 4)] : 'nero';
}
celle.push({ i: k, ch: ch, col: col, target: isT,
riga: Math.floor(k / p.colonne), colonna: k % p.colonne });
}
return { celle: celle, targets: targets, coloreTarget: coloreTarget,
nTarget: celle.filter(function (c) { return c.target; }).length };
}
function media(a) { return a.length ? a.reduce(function (x, y) { return x + y; }, 0) / a.length : null; }
function ds(a) {
if (a.length < 2) return null; var m=media(a); return Math.sqrt(a.reduce(function (s, x) { return s + (x - m) * (x - m); }, 0) / (a.length - 1)); } /* Ricalcolo autoritativo. `eventiGrezzi`=[{ms, idx}]. L'esito NON viene letto dal client: viene dedotto dalla matrice. */ function calcolaMetriche(matrice, eventiGrezzi, durataMs, colonne) { var mappa={}, i; for (i=0; i < matrice.celle.length; i++) mappa[matrice.celle[i].i]=matrice.celle[i]; var ordinati=eventiGrezzi.slice().sort(function (a, b) { return a.ms - b.ms; }); var visti={}, eventi=[]; for (i=0; i < ordinati.length; i++) { var e=ordinati[i], c=mappa[e.idx]; if (!c) continue; // indice inesistente: scartato if (visti[e.idx]) continue; // doppio click sulla stessa cella: ignorato if (e.ms < 0 || e.ms> durataMs + 5000) continue; // fuori finestra: scartato
visti[e.idx] = 1;
eventi.push({ ms: Math.round(e.ms), idx: e.idx, riga: c.riga, colonna: c.colonna,
carattere: c.ch, colore: c.col,
esito: c.target ? 'corretto' : 'falso_allarme' });
}
var corretti = eventi.filter(function (x) { return x.esito === 'corretto'; });
var falsi = eventi.filter(function (x) { return x.esito === 'falso_allarme'; });
var omissioni = matrice.nTarget - corretti.length;
var t = corretti.map(function (x) { return x.ms; }).sort(function (a, b) { return a - b; });
var iri = []; for (i = 1; i < t.length; i++) iri.push(t[i] - t[i - 1]); var mIri=media(iri), sIri=ds(iri); var meta=colonne / 2; var omesse=matrice.celle.filter(function (c) { return c.target && !visti[c.i]; }); var omSx=omesse.filter(function (c) { return c.colonna < meta; }).length; var tSx=matrice.celle.filter(function (c) { return c.target && c.colonna < meta; }).length; var mezzo=durataMs / 2; var h1=corretti.filter(function (x) { return x.ms < mezzo; }).length; var durataS=durataMs / 1000; var acc=matrice.nTarget ? corretti.length / matrice.nTarget : 0; var prec=(corretti.length + falsi.length) ? corretti.length / (corretti.length + falsi.length) : null; return { eventi: eventi, metriche: { durata_s: +durataS.toFixed(2), target_totali: matrice.nTarget, corretti: corretti.length, omissioni: omissioni, falsi_allarmi: falsi.length, accuratezza: +(acc * 100).toFixed(1), precisione: prec===null ? null : +(prec * 100).toFixed(1), indice_efficienza: +((corretti.length - falsi.length) / Math.max(durataS / 60, 0.01)).toFixed(1), iri_medio_ms: mIri===null ? null : Math.round(mIri), iri_ds_ms: sIri===null ? null : Math.round(sIri), omissioni_sx: omSx, omissioni_dx: omesse.length - omSx, target_sx: tSx, target_dx: matrice.nTarget - tSx, corretti_1a_meta: h1, corretti_2a_meta: corretti.length - h1 } }; } return { LETTERE: LETTERE, COLORI: COLORI, rng: rng, costruisciMatrice: costruisciMatrice, calcolaMetriche: calcolaMetriche }; });