game/tests/ai.test.js

64 lines
2.3 KiB
JavaScript
Raw Permalink 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.

/* AI 行为测试:node --test tests/ai.test.js */
const { test } = require('node:test');
const assert = require('node:assert');
const E = require('../js/engine.js');
const AI = require('../js/ai.js');
function setStones(game, color, coords) {
for (const [x, y] of coords) game.board[y][x] = color;
}
test('空盘首着落天元', () => {
const g = E.createGame();
assert.deepStrictEqual(AI.nextMove(g, E.BLACK), { x: 7, y: 7 });
});
test('能一手取胜时直接取胜', () => {
const g = E.createGame();
// 白方横向四连(x=4..7, y=5),左端被黑封堵,唯一成五点是 (8,5)
setStones(g, E.WHITE, [[4, 5], [5, 5], [6, 5], [7, 5]]);
setStones(g, E.BLACK, [[3, 5]]);
assert.deepStrictEqual(AI.nextMove(g, E.WHITE), { x: 8, y: 5 });
});
test('对方冲四时必防守', () => {
const g = E.createGame();
// 黑方横向四连(x=3..6, y=9),左端 (2,9) 已被白封堵,白必须在 (7,9) 挡
setStones(g, E.BLACK, [[3, 9], [4, 9], [5, 9], [6, 9]]);
setStones(g, E.WHITE, [[2, 9]]);
assert.deepStrictEqual(AI.nextMove(g, E.WHITE), { x: 7, y: 9 });
});
test('对方活三时封挡端点', () => {
const g = E.createGame();
// 黑方两端开阔的活三,白应落在 (5,7) 或 (9,7) 之一
setStones(g, E.BLACK, [[6, 7], [7, 7], [8, 7]]);
const mv = AI.nextMove(g, E.WHITE);
assert.ok(
(mv.x === 5 && mv.y === 7) || (mv.x === 9 && mv.y === 7),
`期望封挡 (5,7) 或 (9,7),实际落在 (${mv.x},${mv.y})`
);
});
test('己方活三优先于防守对方眠二', () => {
const g = E.createGame();
// 白有活二 (4,8)(5,8),黑只有零散两子;白应继续连子而非远端防守
setStones(g, E.WHITE, [[4, 8], [5, 8]]);
setStones(g, E.BLACK, [[10, 3], [3, 11]]);
const mv = AI.nextMove(g, E.WHITE);
const nearOwn = Math.abs(mv.x - 4) + Math.abs(mv.y - 8) <= 4
|| Math.abs(mv.x - 5) + Math.abs(mv.y - 8) <= 4;
assert.ok(nearOwn, `期望在己方活二附近行棋,实际落在 (${mv.x},${mv.y})`);
});
test('返回的点永远是空位', () => {
const g = E.createGame();
setStones(g, E.BLACK, [[7, 7], [8, 8], [6, 8]]);
setStones(g, E.WHITE, [[7, 8], [8, 6], [6, 6]]);
g.currentPlayer = E.WHITE;
for (let i = 0; i < 20; i++) {
const mv = AI.nextMove(g);
assert.strictEqual(g.board[mv.y][mv.x], E.EMPTY);
}
});