web/ : le moteur tourne dans un Web Worker (module ES) ; la page de test donne le meilleur coup d'une position et son temps de calcul ; la page de mesure chronomètre les positions de référence, mesure la taille téléchargée et la mémoire, compare aux seuils de l'étape 0b et produit un rapport à copier. make bench fait la même mesure sous Node, make deploy-web sert les pages sur le réseau local. Guide de test pour le Fairphone 4 dans docs/guide-test-etape-0.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
72 lines
2.4 KiB
JavaScript
72 lines
2.4 KiB
JavaScript
// page.mjs -- page de test du moteur (index.html) : meilleur coup d'une
|
|
// position, avec son temps de calcul.
|
|
//
|
|
// Copyright (C) 2026 les auteurs d'Ustagammon.
|
|
// Licence : GPLv3 ou ultérieure (voir LICENSE).
|
|
|
|
import { startEngine } from "./engine-client.mjs";
|
|
|
|
const $ = (id) => document.getElementById(id);
|
|
const engine = startEngine();
|
|
|
|
engine.ready.then(
|
|
({ loadMs }) => {
|
|
$("status").textContent = "Moteur prêt, chargé en " + Math.round(loadMs) + " ms.";
|
|
$("best-move").disabled = false;
|
|
},
|
|
(error) => {
|
|
$("status").textContent = "Le moteur n'a pas pu se charger : " + error.message;
|
|
$("status").classList.add("error");
|
|
},
|
|
);
|
|
|
|
// Exemples : les positions de référence avec des dés.
|
|
fetch("wasm/positions.json")
|
|
.then((response) => response.json())
|
|
.then(({ positions }) => {
|
|
for (const p of positions.filter((p) => p.type === "move")) {
|
|
const option = new Option(p.id + " : " + p.description, p.id);
|
|
option.position = p;
|
|
$("example").add(option);
|
|
}
|
|
})
|
|
.catch(() => {}); // la page reste utilisable sans les exemples
|
|
|
|
$("example").onchange = () => {
|
|
const p = $("example").selectedOptions[0].position;
|
|
if (p) {
|
|
$("position-id").value = p.position_id;
|
|
$("match-id").value = p.match_id;
|
|
[$("die1").value, $("die2").value] = p.dice;
|
|
}
|
|
};
|
|
|
|
function showResult(move, details, time) {
|
|
$("move").textContent = move;
|
|
$("details").textContent = details;
|
|
$("time").textContent = time;
|
|
$("result").hidden = false;
|
|
}
|
|
|
|
$("form").onsubmit = async (event) => {
|
|
event.preventDefault();
|
|
$("best-move").disabled = true;
|
|
$("result").hidden = true;
|
|
try {
|
|
const { result, ms } = await engine.bestMove($("position-id").value.trim(),
|
|
$("match-id").value.trim(), [$("die1").value, $("die2").value], $("ply").value);
|
|
const best = result.best_move;
|
|
if (best) {
|
|
showResult(best.move, "Équité " + best.equity.toFixed(3).replace(".", ",")
|
|
+ ", chances de gain " + (100 * best.probabilities.win).toFixed(1).replace(".", ",")
|
|
+ " %, évalué à " + best.ply + " pli(s).", Math.round(ms) + " ms");
|
|
} else {
|
|
showResult("aucun coup possible", "", Math.round(ms) + " ms");
|
|
}
|
|
} catch (error) {
|
|
showResult("erreur", error.message, "");
|
|
} finally {
|
|
$("best-move").disabled = false;
|
|
}
|
|
};
|