Domaine : match, niveau de l'ordinateur, événements en version 2
Partie de match (score et Crawford dits par le moteur), niveau choisi porté par GameStarted, ordinateur joué comme ComputerTurn de gnubg ; migration des journaux de la version 1 ; scénarios, glossaire, ADR 0007 et 0013 amendés. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c0f827c5ba
commit
339d699488
@@ -0,0 +1,128 @@
|
||||
// Tests du choix de la partie et du match, sans navigateur : réglages de
|
||||
// l'écran « Nouvelle partie », correspondance des niveaux avec ceux de
|
||||
// GNU Backgammon, résumé d'une partie de match enregistrée, adaptateur du
|
||||
// moteur (Match ID d'un match) sur le vrai moteur.
|
||||
//
|
||||
// Copyright (C) 2026 les auteurs d'Ustagammon.
|
||||
// Licence : GPLv3 ou ultérieure (voir LICENSE).
|
||||
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
import { Game } from "../src/domain/game/game.js";
|
||||
import { COMPUTER_LEVELS, computerLevelOf, ENGINE_LEVELS } from "../src/domain/game/level.js";
|
||||
import { firstGameOf, MATCH_LENGTHS, nextGameOf } from "../src/domain/game/match.js";
|
||||
import { START_POSITION } from "../src/domain/game/position.js";
|
||||
import { fixedDice } from "../src/domain/game/roll.js";
|
||||
import { levelOf, summarizeGame } from "../src/domain/game/saved-game.js";
|
||||
import { chosenGame, DEFAULT_SETTINGS, parseSettings } from "../src/ui/settings.js";
|
||||
import { loadNodeEngine } from "./support/node-engine.js";
|
||||
|
||||
test("les six niveaux montrés au joueur, du plus faible au plus fort, et leur niveau de gnubg", () => {
|
||||
assert.deepEqual(COMPUTER_LEVELS, [
|
||||
"beginner",
|
||||
"amateur",
|
||||
"intermediate",
|
||||
"advanced",
|
||||
"expert",
|
||||
"champion",
|
||||
]);
|
||||
assert.deepEqual(
|
||||
COMPUTER_LEVELS.map((level) => ENGINE_LEVELS[level]),
|
||||
["beginner", "casual", "intermediate", "advanced", "0ply", "2ply"],
|
||||
);
|
||||
assert.equal(computerLevelOf("casual"), "amateur");
|
||||
assert.equal(computerLevelOf("3ply"), null);
|
||||
});
|
||||
|
||||
test("réglages de la nouvelle partie : partie libre, Intermédiaire, conseil activé par défaut ; valeurs illisibles ignorées", () => {
|
||||
assert.equal(DEFAULT_SETTINGS.gameKind, "free");
|
||||
assert.equal(DEFAULT_SETTINGS.level, "intermediate");
|
||||
assert.equal(DEFAULT_SETTINGS.masterAdvice, true);
|
||||
// Réglages d'avant l'étape 1c : les valeurs par défaut.
|
||||
const old = parseSettings('{"vibrations": false, "gamesStarted": 4}');
|
||||
assert.equal(old.gameKind, "free");
|
||||
assert.equal(old.matchLength, 5);
|
||||
assert.equal(old.level, "intermediate");
|
||||
const saved = parseSettings(
|
||||
'{"gameKind": "match", "matchLength": 7, "level": "champion", "masterAdvice": false}',
|
||||
);
|
||||
assert.deepEqual(
|
||||
[saved.gameKind, saved.matchLength, saved.level, saved.masterAdvice],
|
||||
["match", 7, "champion", false],
|
||||
);
|
||||
const wrong = parseSettings('{"gameKind": "x", "matchLength": 4, "level": "4ply"}');
|
||||
assert.deepEqual([wrong.gameKind, wrong.matchLength, wrong.level], ["free", 5, "intermediate"]);
|
||||
assert.deepEqual([...MATCH_LENGTHS], [3, 5, 7, 11]);
|
||||
});
|
||||
|
||||
test("la partie choisie : le niveau de gnubg, et la première partie d'un match à 0-0", () => {
|
||||
assert.deepEqual(chosenGame(DEFAULT_SETTINGS), { level: "intermediate" });
|
||||
assert.deepEqual(chosenGame({ ...DEFAULT_SETTINGS, gameKind: "match", level: "expert" }), {
|
||||
level: "0ply",
|
||||
match: { length: 5, score: { player: 0, computer: 0 }, crawford: false },
|
||||
});
|
||||
assert.throws(() => firstGameOf(0), /longueur/);
|
||||
const match = firstGameOf(3);
|
||||
assert.equal(
|
||||
nextGameOf(match, { score: { player: 3, computer: 0 }, over: true, crawford: false }),
|
||||
null,
|
||||
);
|
||||
assert.deepEqual(
|
||||
nextGameOf(match, { score: { player: 2, computer: 0 }, over: false, crawford: true }),
|
||||
{ length: 3, score: { player: 2, computer: 0 }, crawford: true },
|
||||
);
|
||||
});
|
||||
|
||||
test("le résumé d'une partie de match enregistrée porte le match ; celui d'une partie libre n'en a pas", async () => {
|
||||
const engine = await loadNodeEngine();
|
||||
const times = { startedAt: 1, updatedAt: 2 };
|
||||
const free = Game.start(engine, { dice: fixedDice([3, 1]), level: "beginner" });
|
||||
assert.equal(levelOf(free.journal), "beginner");
|
||||
const freeSummary = summarizeGame("a", free.journal, { level: "beginner" }, times);
|
||||
assert.equal(freeSummary.match, undefined);
|
||||
assert.equal(freeSummary.level, "beginner");
|
||||
|
||||
const match = Game.start(engine, {
|
||||
dice: fixedDice([3, 1]),
|
||||
level: "2ply",
|
||||
match: { length: 5, score: { player: 4, computer: 2 }, crawford: true },
|
||||
});
|
||||
const summary = summarizeGame("b", match.journal, { level: levelOf(match.journal) }, times);
|
||||
assert.deepEqual(summary.match, {
|
||||
length: 5,
|
||||
score: { player: 4, computer: 2 },
|
||||
crawford: true,
|
||||
over: false,
|
||||
});
|
||||
});
|
||||
|
||||
test("adaptateur : le Match ID d'un match code la longueur, le score vu du joueur au trait et Crawford", async () => {
|
||||
const engine = await loadNodeEngine();
|
||||
const id = await engine.encodeMatch({
|
||||
value: 1,
|
||||
owner: "centered",
|
||||
match: { length: 5, score: { onRoll: 4, opponent: 2 }, crawford: true },
|
||||
});
|
||||
const decoded = await engine.decodeMatch(id);
|
||||
assert.deepEqual(
|
||||
[decoded.matchLength, decoded.score, decoded.crawford, decoded.jacoby],
|
||||
[5, [4, 2], true, false],
|
||||
);
|
||||
// En partie Crawford, le moteur refuse le videau au joueur au trait.
|
||||
const crawford = await engine.cubeDecision(
|
||||
START_POSITION,
|
||||
{
|
||||
value: 1,
|
||||
owner: "centered",
|
||||
match: { length: 5, score: { onRoll: 2, opponent: 4 }, crawford: true },
|
||||
},
|
||||
0,
|
||||
);
|
||||
assert.equal(crawford.available, false);
|
||||
const after = await engine.matchAfterGame(
|
||||
{ length: 5, score: { onRoll: 3, opponent: 2 }, crawford: false },
|
||||
"onRoll",
|
||||
1,
|
||||
);
|
||||
assert.deepEqual(after, { score: { onRoll: 4, opponent: 2 }, over: false, crawford: true });
|
||||
});
|
||||
Reference in New Issue
Block a user