130 lines
4.1 KiB
JavaScript
130 lines
4.1 KiB
JavaScript
/* 规则引擎测试:node --test tests/ */
|
||
const { test } = require('node:test');
|
||
const assert = require('node:assert');
|
||
const E = require('../js/engine.js');
|
||
|
||
// 直接往棋盘上摆子,用于构造测试局面(绕过轮流落子)
|
||
function setStones(game, color, coords) {
|
||
for (const [x, y] of coords) game.board[y][x] = color;
|
||
}
|
||
|
||
test('黑先并且落子后交替行棋', () => {
|
||
const g = E.createGame();
|
||
assert.strictEqual(g.currentPlayer, E.BLACK);
|
||
const r = E.place(g, 7, 7);
|
||
assert.strictEqual(r.ok, true);
|
||
assert.strictEqual(g.currentPlayer, E.WHITE);
|
||
E.place(g, 8, 8);
|
||
assert.strictEqual(g.currentPlayer, E.BLACK);
|
||
});
|
||
|
||
test('横向五连判胜', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.BLACK, [[3, 7], [4, 7], [5, 7], [6, 7]]);
|
||
g.currentPlayer = E.BLACK;
|
||
const r = E.place(g, 7, 7);
|
||
assert.strictEqual(r.win, true);
|
||
assert.strictEqual(g.winner, E.BLACK);
|
||
assert.strictEqual(g.gameOver, true);
|
||
assert.deepStrictEqual(g.winningLine, [
|
||
{ x: 3, y: 7 }, { x: 4, y: 7 }, { x: 5, y: 7 }, { x: 6, y: 7 }, { x: 7, y: 7 },
|
||
]);
|
||
});
|
||
|
||
test('纵向五连判胜', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.WHITE, [[7, 3], [7, 4], [7, 5], [7, 6]]);
|
||
g.currentPlayer = E.WHITE;
|
||
const r = E.place(g, 7, 7);
|
||
assert.strictEqual(r.win, true);
|
||
assert.strictEqual(g.winner, E.WHITE);
|
||
});
|
||
|
||
test('斜向(左上到右下)五连判胜', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.BLACK, [[3, 3], [4, 4], [5, 5], [6, 6]]);
|
||
g.currentPlayer = E.BLACK;
|
||
const r = E.place(g, 7, 7);
|
||
assert.strictEqual(r.win, true);
|
||
});
|
||
|
||
test('斜向(左下到右上)五连判胜', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.BLACK, [[3, 10], [4, 9], [5, 8], [6, 7]]);
|
||
g.currentPlayer = E.BLACK;
|
||
const r = E.place(g, 7, 6);
|
||
assert.strictEqual(r.win, true);
|
||
assert.strictEqual(g.winningLine.length, 5);
|
||
});
|
||
|
||
test('长连(六连)同样判胜', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.BLACK, [[3, 5], [4, 5], [5, 5], [6, 5], [8, 5]]);
|
||
g.currentPlayer = E.BLACK;
|
||
const r = E.place(g, 7, 5);
|
||
assert.strictEqual(r.win, true);
|
||
assert.strictEqual(g.winningLine.length, 6);
|
||
});
|
||
|
||
test('四连不判胜', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.BLACK, [[3, 7], [4, 7], [5, 7], [6, 7]]);
|
||
g.currentPlayer = E.BLACK;
|
||
const r = E.place(g, 9, 9); // 与四连无关的落子
|
||
assert.strictEqual(r.win, undefined);
|
||
assert.strictEqual(g.gameOver, false);
|
||
});
|
||
|
||
test('非法落子被拒绝:已占用', () => {
|
||
const g = E.createGame();
|
||
E.place(g, 7, 7);
|
||
const r = E.place(g, 7, 7);
|
||
assert.strictEqual(r.ok, false);
|
||
});
|
||
|
||
test('非法落子被拒绝:越界', () => {
|
||
const g = E.createGame();
|
||
assert.strictEqual(E.place(g, -1, 0).ok, false);
|
||
assert.strictEqual(E.place(g, 0, -1).ok, false);
|
||
assert.strictEqual(E.place(g, 15, 0).ok, false);
|
||
assert.strictEqual(E.place(g, 0, 15).ok, false);
|
||
});
|
||
|
||
test('对局结束后拒绝继续落子', () => {
|
||
const g = E.createGame();
|
||
setStones(g, E.BLACK, [[3, 7], [4, 7], [5, 7], [6, 7]]);
|
||
g.currentPlayer = E.BLACK;
|
||
E.place(g, 7, 7);
|
||
const r = E.place(g, 10, 10);
|
||
assert.strictEqual(r.ok, false);
|
||
assert.strictEqual(r.reason, '游戏已结束');
|
||
});
|
||
|
||
test('棋盘下满判平局', () => {
|
||
const g = E.createGame();
|
||
// 用 (x + 2y) mod 4 的双色填充,任意方向连续同色不超过 2,不会误判五连
|
||
for (let y = 0; y < E.SIZE; y++) {
|
||
for (let x = 0; x < E.SIZE; x++) {
|
||
if (x === 14 && y === 14) continue;
|
||
const v = ((x + 2 * y) % 4 + 4) % 4;
|
||
g.board[y][x] = v === 0 || v === 1 ? E.BLACK : E.WHITE;
|
||
}
|
||
}
|
||
g.currentPlayer = E.BLACK;
|
||
const r = E.place(g, 14, 14);
|
||
assert.strictEqual(r.draw, true);
|
||
assert.strictEqual(g.gameOver, true);
|
||
assert.strictEqual(g.winner, 0);
|
||
});
|
||
|
||
test('落子历史被完整记录', () => {
|
||
const g = E.createGame();
|
||
E.place(g, 7, 7);
|
||
E.place(g, 8, 8);
|
||
E.place(g, 7, 8);
|
||
assert.strictEqual(g.moveHistory.length, 3);
|
||
assert.deepStrictEqual(g.moveHistory[0], { x: 7, y: 7, player: E.BLACK });
|
||
assert.deepStrictEqual(g.moveHistory[1], { x: 8, y: 8, player: E.WHITE });
|
||
assert.deepStrictEqual(g.moveHistory[2], { x: 7, y: 8, player: E.BLACK });
|
||
});
|