From 582ce16be02448e3348ccf76d70e07ea45f7678e Mon Sep 17 00:00:00 2001 From: 63db3122f0950a2aef64df95 <63db3122f0950a2aef64df95@devide> Date: Wed, 28 Jun 2023 03:05:03 +0000 Subject: [PATCH] Auto Commit --- src/App.vue | 9 +++-- src/utils/index.js | 98 ++++++++++++++++++---------------------------- 2 files changed, 44 insertions(+), 63 deletions(-) diff --git a/src/App.vue b/src/App.vue index 3700862..4f9d6f4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -22,15 +22,16 @@ async function playChess(item, row, col) { if (isWin.length || item !== is_empty) return lattices.value[row][col] = is_black 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) { isWin = test return } else { - is_load.value = true - const [x, y] = await robotPlay(lattices.value, is_white, win_size.value) - is_load.value = false + const [x, y] = robotPlay(lattices.value, is_white, win_size.value) 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 + } } } diff --git a/src/utils/index.js b/src/utils/index.js index a20a09d..68da472 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,4 +1,7 @@ export const is_empty = 'isEmpty'; +/** + * 机器人 + */ export const is_white = 'isWhite'; export const is_black = 'isBlack'; export const directions = [ @@ -13,22 +16,23 @@ export const directions = [ * @param {object} param * @param {number} param.row 行 * @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 {number} param.win_size 需要几个棋子才赢 - * @param {[]} [param.direction] 方向 + * @param {[][]} [param.direction] 方向 * @returns */ export function checkWin({ row, col, board, player, win_size, direction }) { const _row = board.length; const _col = board[0].length const pieceType = player ?? board[row][col] + let res = [] const _directions = direction ? [direction] : directions; for (let i = 0; i < _directions.length; i++) { - const res = [[row, col]]; + res = [[row, col]]; const [dx, dy] = _directions[i]; let x = row + dx; let y = col + dy; @@ -48,54 +52,61 @@ export function checkWin({ row, col, board, player, win_size, direction }) { 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 maxScorePos = {}; let maxScore = -1; - const opponent = (player === is_black) ? is_white : is_black; - // 空格位置 + // 空位 const empty_points = _board.map((item, row) => { return item.flatMap((_item, col) => _item === is_empty ? [[row, col]] : []) }).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; const [i, j] = point; // 判断下子后是否获胜 - _board[i][j] = player; - const win = checkWin({ row: i, col: j, board: _board, player, win_size }); - if (win) { - score = Infinity; + _board[i][j] = is_white; + const win = checkWin({ row: i, col: j, board: _board, player: robot, win_size }); + if (win.length >= win_size) { + return [i, j] } else { - // 判断对手是否能在下一步获胜,如果能,则这个点的分数为 0 - _board[i][j] = opponent; - const oppWin = checkWin({ row: i, col: j, board: _board, player: opponent, win_size }); - if (oppWin) { - score = 0; + // 判断对手是否能在下一步获胜 + const oppWin = checkWin({ row: i, col: j, board: _board, player: is_black, win_size }); + if (oppWin.length >= win_size) { + return [i, j] } else { // 计算当前棋盘局面的得分 - const horizontal = countPieces({ row: i, col: j, _board, player, win_size, direction: "horizontal" }); - const vertical = countPieces({ row: i, col: j, _board, player, win_size, direction: "vertical" }); - const diagonalDown = countPieces({ row: i, col: j, _board, player, win_size, direction: "diagonalDown" }); - const diagonalUp = countPieces({ row: i, col: j, _board, player, win_size, direction: "diagonalUp" }); + const horizontal = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("horizontal") }); + const vertical = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("vertical") }); + const diagonalDown = checkWin({ row: i, col: j, board: _board, player: is_black, win_size, direction: getDirection("diagonalDown") }); + 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) { @@ -103,42 +114,11 @@ export function robotPlay(board, player, win_size) { maxScorePos.y = j; maxScore = score; } - }); + }; 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) { switch (direction) { -- GitLab