go-learn/packages/ai/src/game.test.ts
sab.code.lab 1c85091186 chore: восстановление репозитория из снапшота v0.3.1
Прежняя git-история утрачена при переносе проекта на машину владельца
(снапшот без .git). Хэши коммитов в docs/reports/* относятся к утраченной
истории.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 09:34:02 +02:00

40 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Партии бот-бот: детерминизм (одинаковый seed → идентичная партия),
* легальность каждого хода и завершение за ≤ 200 ходов (property-style
* на запиненных seedах; проверка легальности — внутри playBotGame через
* applyMove, нелегальный ход = ошибка теста).
*/
import { describe, expect, it } from 'vitest';
import type { AiLevel } from './index.js';
import { playBotGame } from './test-utils.js';
const MAX_MOVES_9x9 = 200;
describe('детерминизм', () => {
it('одинаковый seed → идентичные последовательности ходов (два прогона)', () => {
for (const seed of [7, 42, 2026]) {
const first = playBotGame(seed, 3, 9, MAX_MOVES_9x9);
const second = playBotGame(seed, 3, 9, MAX_MOVES_9x9);
expect(second.moves).toEqual(first.moves);
expect(second.finalState.grid).toEqual(first.finalState.grid);
}
});
});
describe('легальность и завершение (property, запиненные seedы)', () => {
const levels: readonly AiLevel[] = [1, 2, 3];
const cases = Array.from({ length: 12 }, (_, index) => ({
seed: index + 1,
level: levels[index % levels.length] ?? 1,
}));
for (const { seed, level } of cases) {
it(`партия seed=${seed} ур.${level}: все ходы легальны, over за ≤ ${MAX_MOVES_9x9}`, () => {
const game = playBotGame(seed, level, 9, MAX_MOVES_9x9);
expect(game.finalState.over).toBe(true);
expect(game.moves.length).toBeLessThanOrEqual(MAX_MOVES_9x9);
// Партия завершается двумя пасами подряд.
expect(game.moves[game.moves.length - 1]).toBe('pass');
expect(game.moves[game.moves.length - 2]).toBe('pass');
});
}
});