Conseil du maître : rang cité seulement pour un coup proche ou une imprécision au 2e ou 3e choix ; 1d faite, plan clos

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Pierre MARTIN
2026-11-10 05:36:11 +01:00
co-authored by Claude Opus 5.5
parent 4fa54ad3f3
commit c7a54a8c81
7 changed files with 49 additions and 153 deletions
+8 -6
View File
@@ -73,7 +73,7 @@ export const PHRASE_KEYS: readonly string[] = [
"coup.douteux",
"coup.mauvais",
"coup.tres-mauvais",
"coup.tres-mauvais.loin",
"coup.loin",
"fait.frappe",
"fait.frappe-plusieurs",
"fait.point",
@@ -145,13 +145,15 @@ function moveWords(phrases: MasterPhrases, advice: MoveAdvice): MasterWords {
base = fill("coup.meilleur");
fact = selfFact(phrases, advice.eventId, advice.played.notation, advice.playedFacts);
} else {
// Le rang n'est cité que pour un bon coup non meilleur ou une
// imprécision, au 2e ou 3e choix : il mesure mal la gravité d'une
// erreur, et le classement est dans les chiffres du moteur.
const near = advice.rank <= 3;
const key = {
good: "coup.proche",
doubtful: "coup.douteux",
good: near ? "coup.proche" : "coup.loin",
doubtful: near ? "coup.douteux" : "coup.loin",
bad: "coup.mauvais",
// Une grosse erreur ne cite son rang que s'il est proche (2e ou
// 3e choix) ; plus loin, le classement est dans les chiffres.
veryBad: advice.rank <= 3 ? "coup.tres-mauvais" : "coup.tres-mauvais.loin",
veryBad: "coup.tres-mauvais",
}[verdict];
base = fill(key);
fact = differenceFact(phrases, advice);
+8 -8
View File
@@ -121,14 +121,14 @@ export function createAdviceView(options: AdviceViewOptions): AdviceView {
verdictLine.append(icon(VERDICT_ICONS[words.verdict]));
element(verdictLine, "span", { text: `${words.word} · ${words.context}` });
title.textContent = words.title;
element(sheet, "p", {
id: "explain-phrase",
className: "explain-phrase",
// Le titre dit déjà le coup du maître : la phrase ne le répète pas.
text: words.phrase.startsWith(`${words.title}. `)
? words.phrase.slice(words.title.length + 2)
: words.phrase,
});
// Le titre dit déjà le coup du maître : la phrase ne le répète pas
// (et disparaît si elle ne disait que lui).
const rest = words.phrase.startsWith(`${words.title}.`)
? words.phrase.slice(words.title.length + 1).trim()
: words.phrase;
if (rest !== "") {
element(sheet, "p", { id: "explain-phrase", className: "explain-phrase", text: rest });
}
const body = element(sheet, "div", { className: "explain-body" });
const boardBox = element(body, "div", { className: "explain-board-box" });
+12 -12
View File
@@ -163,25 +163,25 @@ test("le coup du maître est nommé, et le fait qui distingue les coups vient du
assert.deepEqual(worst.bestFacts.madePoints, [5]);
const said = masterWords(phrases, worst);
assert.equal(said.title, "J'aurais joué 8/5 6/5");
assert.equal(
said.phrase,
"J'aurais joué 8/5 6/5. Votre 24/23 13/10 était le 2e choix. Mon coup fait votre point 5.",
);
assert.equal(said.phrase, "J'aurais joué 8/5 6/5. Mon coup fait votre point 5.");
});
test("grosse erreur : le rang n'est cité que pour un 2e ou 3e choix", async () => {
test("le rang n'est cité que pour un bon coup non meilleur ou une imprécision, au 2e ou 3e choix", async () => {
const engine = await loadNodeEngine();
const worst = (await adviceOn(
engine,
await playOpening(engine, [3, 1], "24/23 13/10"),
)) as MoveAdvice;
for (const rank of [2, 3, 4, 7, 15]) {
const { phrase } = masterWords(phrases, { ...worst, rank });
if (rank <= 3) {
assert.ok(phrase.includes(`était le ${rank}e choix`), phrase);
} else {
assert.ok(!phrase.includes("choix"), phrase);
assert.equal(phrase, "J'aurais joué 8/5 6/5. Mon coup fait votre point 5.");
for (const skill of ["none", "doubtful", "bad", "veryBad"] as const) {
for (const rank of [2, 3, 4, 7, 15]) {
const { phrase } = masterWords(phrases, { ...worst, skill, rank });
const cited = (skill === "none" || skill === "doubtful") && rank <= 3;
if (cited) {
assert.ok(phrase.includes(`le ${rank}e choix`), `${skill} ${rank} : ${phrase}`);
} else {
assert.ok(!phrase.includes("choix"), `${skill} ${rank} : ${phrase}`);
assert.equal(phrase, "J'aurais joué 8/5 6/5. Mon coup fait votre point 5.");
}
}
}
});