Прежняя git-история утрачена при переносе проекта на машину владельца (снапшот без .git). Хэши коммитов в docs/reports/* относятся к утраченной истории. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
40 lines
1.9 KiB
TypeScript
40 lines
1.9 KiB
TypeScript
/**
|
||
* Партии бот-бот: детерминизм (одинаковый 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');
|
||
});
|
||
}
|
||
});
|