Auto Commit

上级 8e79dd18
...@@ -22,15 +22,16 @@ async function playChess(item, row, col) { ...@@ -22,15 +22,16 @@ async function playChess(item, row, col) {
if (isWin.length || item !== is_empty) return if (isWin.length || item !== is_empty) return
lattices.value[row][col] = is_black lattices.value[row][col] = is_black
const test = checkWin({ row, col, board: lattices.value, player: is_black, win_size: win_size.value }) const test = checkWin({ row, col, board: lattices.value, player: is_black, win_size: win_size.value })
console.log(test)
if (test.length >= win_size.value) { if (test.length >= win_size.value) {
isWin = test isWin = test
return return
} else { } else {
is_load.value = true const [x, y] = robotPlay(lattices.value, is_white, win_size.value)
const [x, y] = await robotPlay(lattices.value, is_white, win_size.value)
is_load.value = false
lattices.value[x][y] = is_white lattices.value[x][y] = is_white
const test = checkWin({ row: x, col: y, board: lattices.value, player: is_white, win_size: win_size.value })
if (test.length >= win_size.value) {
isWin = test
}
} }
} }
......
export const is_empty = 'isEmpty'; export const is_empty = 'isEmpty';
/**
* 机器人
*/
export const is_white = 'isWhite'; export const is_white = 'isWhite';
export const is_black = 'isBlack'; export const is_black = 'isBlack';
export const directions = [ export const directions = [
...@@ -13,22 +16,23 @@ export const directions = [ ...@@ -13,22 +16,23 @@ export const directions = [
* @param {object} param * @param {object} param
* @param {number} param.row 行 * @param {number} param.row 行
* @param {number} param.col 列 * @param {number} param.col 列
* @param {(isEmpty|is_white|is_black)[]} param.board 棋盘 * @param {(is_empty|is_white|is_black)[]} param.board 棋盘
* @param {is_white|is_black} [param.player] 当前棋子类型 * @param {is_white|is_black} [param.player] 当前棋子类型
* @param {number} param.win_size 需要几个棋子才赢 * @param {number} param.win_size 需要几个棋子才赢
* @param {[]} [param.direction] 方向 * @param {[][]} [param.direction] 方向
* @returns * @returns
*/ */
export function checkWin({ row, col, board, player, win_size, direction }) { export function checkWin({ row, col, board, player, win_size, direction }) {
const _row = board.length; const _row = board.length;
const _col = board[0].length const _col = board[0].length
const pieceType = player ?? board[row][col] const pieceType = player ?? board[row][col]
let res = []
const _directions = direction ? [direction] : directions; const _directions = direction ? [direction] : directions;
for (let i = 0; i < _directions.length; i++) { for (let i = 0; i < _directions.length; i++) {
const res = [[row, col]]; res = [[row, col]];
const [dx, dy] = _directions[i]; const [dx, dy] = _directions[i];
let x = row + dx; let x = row + dx;
let y = col + dy; let y = col + dy;
...@@ -48,54 +52,61 @@ export function checkWin({ row, col, board, player, win_size, direction }) { ...@@ -48,54 +52,61 @@ export function checkWin({ row, col, board, player, win_size, direction }) {
y -= dy; y -= dy;
} }
if (res.length < win_size) { // 出现五连珠,返回胜利
return res; // 出现五连珠,返回胜利 if (res.length >= win_size) {
return res;
} }
} }
// 当前空位,可以结成多少颗连珠
return res; // 未出现五连珠 return res;
} }
// TODO: 机器人下棋 /**
export function robotPlay(board, player, win_size) { * 机器人下棋位置
* @param {(is_empty|is_white|is_black)[][]} board 棋盘
* @param {is_white} robot 机器人
* @param {number} win_size 赢棋的棋子颗数
* @returns {number[]}
*/
export function robotPlay(board, robot, win_size) {
// 深度复制一份棋盘 // 深度复制一份棋盘
const _board = JSON.parse(JSON.stringify(board)) const _board = JSON.parse(JSON.stringify(board))
const maxScorePos = {}; const maxScorePos = {};
let maxScore = -1; let maxScore = -1;
const opponent = (player === is_black) ? is_white : is_black; // 空位
// 空格位置
const empty_points = _board.map((item, row) => { const empty_points = _board.map((item, row) => {
return item.flatMap((_item, col) => _item === is_empty ? [[row, col]] : []) return item.flatMap((_item, col) => _item === is_empty ? [[row, col]] : [])
}).flat(1) }).flat(1)
// 对每个空位进行评分 // 对每个空位进行评分
empty_points.forEach((point) => { for (let e_i = 0; e_i < empty_points.length; e_i++) {
const point = empty_points[e_i]
let score = 0; let score = 0;
const [i, j] = point; const [i, j] = point;
// 判断下子后是否获胜 // 判断下子后是否获胜
_board[i][j] = player; _board[i][j] = is_white;
const win = checkWin({ row: i, col: j, board: _board, player, win_size }); const win = checkWin({ row: i, col: j, board: _board, player: robot, win_size });
if (win) { if (win.length >= win_size) {
score = Infinity; return [i, j]
} else { } else {
// 判断对手是否能在下一步获胜,如果能,则这个点的分数为 0 // 判断对手是否能在下一步获胜
_board[i][j] = opponent; const oppWin = checkWin({ row: i, col: j, board: _board, player: is_black, win_size });
const oppWin = checkWin({ row: i, col: j, board: _board, player: opponent, win_size }); if (oppWin.length >= win_size) {
if (oppWin) { return [i, j]
score = 0;
} else { } else {
// 计算当前棋盘局面的得分 // 计算当前棋盘局面的得分
const horizontal = countPieces({ row: i, col: j, _board, player, win_size, direction: "horizontal" }); const horizontal = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("horizontal") });
const vertical = countPieces({ row: i, col: j, _board, player, win_size, direction: "vertical" }); const vertical = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("vertical") });
const diagonalDown = countPieces({ row: i, col: j, _board, player, win_size, direction: "diagonalDown" }); const diagonalDown = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("diagonalDown") });
const diagonalUp = countPieces({ row: i, col: j, _board, player, win_size, direction: "diagonalUp" }); const diagonalUp = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("diagonalUp") });
score = Math.max(horizontal, vertical, diagonalDown, diagonalUp); score = Math.max(horizontal.length, vertical.length, diagonalDown.length, diagonalUp.length);
} }
} }
_board[i][j] = isEmpty; // 恢复棋盘状态 _board[i][j] = is_empty; // 恢复棋盘状态
// 选取分数最高的空位 // 选取分数最高的空位
if (score > maxScore) { if (score > maxScore) {
...@@ -103,42 +114,11 @@ export function robotPlay(board, player, win_size) { ...@@ -103,42 +114,11 @@ export function robotPlay(board, player, win_size) {
maxScorePos.y = j; maxScorePos.y = j;
maxScore = score; maxScore = score;
} }
}); };
return [maxScorePos.x, maxScorePos.y]; return [maxScorePos.x, maxScorePos.y];
} }
// 计算某个位置在某个方向上的连续棋子个数
function countPieces({ row, col, board, player, win_size, direction }) {
const _row = board.length;
const _col = board[0].length;
const pieceType = player ?? board[row][col];
const [dx, dy] = getDirection(direction);
let x = row + dx;
let y = col + dy;
let count = 0;
while (x >= 0 && x < _row && y >= 0 && y < _col && board[x][y] === pieceType) {
count++;
x += dx;
y += dy;
}
x = row - dx;
y = col - dy;
while (x >= 0 && x < _row && y >= 0 && y < _col && board[x][y] === pieceType) {
count++;
x -= dx;
y -= dy;
}
if (count < win_size - 1) {
count = 0; // 不足以形成连续的五个棋子,得分清零
}
return count;
}
// 获取某个方向的偏移量 // 获取某个方向的偏移量
function getDirection(direction) { function getDirection(direction) {
switch (direction) { switch (direction) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册