koishi-plugin-chess
Version:
Playing chess games in Koishi
81 lines (80 loc) • 2.24 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.update = exports.create = exports.placement = void 0;
const board_1 = require("../board");
exports.placement = 'grid';
function create() {
const { size } = this;
if (size % 2 !== 0 || size === 2)
return '棋盘大小应为不小于 4 的 2 的倍数。';
const mid = size / 2;
this.set(mid - 1, mid - 1, -1);
this.set(mid - 1, mid, 1);
this.set(mid, mid - 1, 1);
this.set(mid, mid, -1);
}
exports.create = create;
const delta = [
[0, -1],
[1, -1],
[1, 0],
[1, 1],
[0, 1],
[-1, 1],
[-1, 0],
[-1, -1],
];
function legal(state, x, y, value) {
let diff = 0n;
for (const [dx, dy] of delta) {
let i = x + dx, j = y + dy;
if (!state.inRange(i, j) || state.get(i, j) !== -value)
continue;
let temp = 0n;
do {
temp |= state.bit(i, j);
i += dx;
j += dy;
} while (state.inRange(i, j) && state.get(i, j) === -value);
if (state.inRange(i, j) && state.get(i, j) === value)
diff |= temp;
}
return diff;
}
function hasLegalMove(state, value) {
for (let i = 0; i < state.size; i++) {
for (let j = 0; j < state.size; j++) {
if (!state.get(i, j) && legal(state, i, j, value))
return true;
}
}
}
function total(length, board) {
let count = 0;
for (let i = 0n; i < length; i++) {
count += board & 1n << i ? 1 : 0;
}
return count;
}
function check(state) {
const length = state.size * state.size;
const bCount = total(length, state.bBoard);
const wCount = total(length, state.wBoard);
return Math.sign(bCount - wCount) || board_1.MoveResult.draw;
}
function update(x, y, value) {
const diff = legal(this, x, y, value);
if (!diff)
return board_1.MoveResult.illegal;
this.wBoard ^= diff;
this.bBoard ^= diff;
this.set(x, y, value);
if (this.isFull)
return check(this);
if (!hasLegalMove(this, -value)) {
if (!hasLegalMove(this, value))
return check(this);
return board_1.MoveResult.skip;
}
}
exports.update = update;