Coup de l'ordinateur : animation, traces et bouton Revoir

Le domaine donne le dernier coup demi-coup par demi-coup (plateaux
intermédiaires du moteur, pions frappés lus sur la barre) ; l'interface
fait glisser les pions puis laisse flèches, pions entourés et fantômes
jusqu'à l'action suivante. Scénario « Voir le coup de l'ordinateur »,
tests unitaires et test dans le navigateur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Pierre MARTIN
2026-11-03 01:53:26 +01:00
co-authored by Claude Opus 5.5
parent 9c241de5c9
commit 7a9b376417
12 changed files with 851 additions and 101 deletions
+51 -2
View File
@@ -10,9 +10,9 @@ import { readFileSync } from "node:fs";
import { test } from "node:test";
import type { BoardSide } from "../src/domain/game/engine.js";
import { appendEvent, EMPTY_JOURNAL } from "../src/domain/game/events.js";
import { START_POSITION } from "../src/domain/game/position.js";
import { parseHalfMoves, START_POSITION } from "../src/domain/game/position.js";
import { createGameStore } from "../src/storage/game-store.js";
import { boardModel, moveTargets, placeOf, pointSlot } from "../src/ui/board-model.js";
import { boardModel, moveTargets, moveTrace, placeOf, pointSlot } from "../src/ui/board-model.js";
import { parseFeature, parseGlossaryEntry, parseGlossaryIndex } from "../src/ui/help-text.js";
import { TEXTS } from "../src/ui/texts.js";
@@ -67,6 +67,55 @@ test("les demi-coups possibles donnent les pions jouables et leurs cases d'arriv
assert.deepEqual(targets.get("p3")?.get("off-player"), { from: 3, to: 0 });
});
test("traces d'un coup simple : une flèche par demi-coup, départs et arrivées", () => {
// L'ordinateur joue 13/9 13/7 dans sa numérotation : ses cases 13, 9 et
// 7 sont les cases 12, 16 et 18 du joueur.
const trace = moveTrace("computer", parseHalfMoves("13/9 13/7"), [false, false]);
assert.deepEqual(trace.arrows, [
{ from: "p12", to: "p16" },
{ from: "p12", to: "p18" },
]);
assert.deepEqual([...trace.left], [["p12", 2]]);
assert.deepEqual(
[...trace.landed],
[
["p16", 1],
["p18", 1],
],
);
assert.equal(trace.hits, 0);
});
test("traces : un pion qui fait étape ne laisse ni fantôme ni cercle à l'étape", () => {
const trace = moveTrace("computer", parseHalfMoves("24/18 18/14"), [false, true]);
assert.equal(trace.arrows.length, 2);
assert.deepEqual([...trace.left], [["p1", 1]]);
assert.deepEqual([...trace.landed], [["p11", 1]]);
assert.equal(trace.hits, 1);
});
test("traces : rentrée depuis la barre avec un pion frappé, sortie de pions", () => {
const entering = moveTrace("computer", parseHalfMoves("bar/22 6/4"), [true, false]);
assert.deepEqual(entering.arrows[0], { from: "bar-computer", to: "p3" });
assert.deepEqual(
[...entering.left],
[
["bar-computer", 1],
["p19", 1],
],
);
assert.equal(entering.hits, 1);
const bearingOff = moveTrace("computer", parseHalfMoves("6/off 5/off"), [false, false]);
assert.deepEqual([...bearingOff.landed], [["off-computer", 2]]);
assert.deepEqual(
[...bearingOff.left],
[
["p19", 1],
["p20", 1],
],
);
});
test("l'aide lit le scénario tel qu'il est écrit dans docs/scenarios/", () => {
const feature = parseFeature(read("docs/scenarios/jouer-une-partie.feature"));
assert.equal(feature.title, "Jouer une partie contre l'ordinateur");