Sun Jun 25 08:17:00 UTC 2023 inscode

上级 0ee0761d
<script setup>
import { onMounted, reactive, ref } from "vue"
import { checkWin, findBestMove } from "./utils"
// 配置
const con = reactive({
width: 20,
height: 20
})
const lattices = ref([])
let nextPlay = 'isBlack' // isWhite
// let nextPlay = 'isBlack' // isWhite
// 5 连珠的下标
let isWin = []
......@@ -14,57 +15,29 @@ onMounted(confirm)
function confirm() {
const { width, height } = con
nextPlay = 'isBlack'
isWin = []
lattices.value = Array(height).fill([]).map(item => Array(width).fill(null))
}
// 玩家下棋
function playChess(item, r_i, c_i) {
if (isWin.length || item) return
lattices.value[r_i][c_i] = nextPlay
const test = checkWin(lattices.value, nextPlay)
lattices.value[r_i][c_i] = 'isBlack'
const test = checkWin(r_i, 'isBlack')
if (test) {
console.log(test)
isWin = test
return
}
nextPlay = nextPlay === 'isBlack' ? 'isWhite' : 'isBlack'
} else {
}
// AI 生成代码
function checkFiveInARow(board, startX, startY, deltaX, deltaY) {
const rows = board.length;
const cols = board[0].length;
const player = board[startX][startY];
if (!player) {
return null;
}
for (let i = 1; i <= 4; i++) {
const row = startX + i * deltaX;
const col = startY + i * deltaY;
if (row < 0 || row >= rows || col < 0 || col >= cols || board[row][col] !== player) {
return null;
}
}
return [[startX, startY], [startX + deltaX, startY + deltaY], [startX + 2 * deltaX, startY + 2 * deltaY], [startX + 3 * deltaX, startY + 3 * deltaY], [startX + 4 * deltaX, startY + 4 * deltaY]];
}
function robotMove() {
const [bestRow, bestCol] = findBestMove(lattices.value, "isWhite");
lattices.value[bestRow][bestCol] = "isWhite";
function checkWin(board) {
const rows = board.length;
const cols = board[0].length;
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
const positions =
checkFiveInARow(board, row, col, 0, 1) ||
checkFiveInARow(board, row, col, 1, 0) ||
checkFiveInARow(board, row, col, 1, 1) ||
checkFiveInARow(board, row, col, 1, -1);
if (positions) {
return positions;
}
}
const testRobot = checkWin(lattices.value, "isWhite")
if (testRobot) {
isWin = testRobot
}
return null;
}
......
export function checkWin(row, col, pieceType, board) {
const boardSize = board.length;
const directions = [
[1, 0], // 水平方向
[0, 1], // 垂直方向
[1, 1], // 右下方向
[1, -1] // 左下方向
];
for (let i = 0; i < directions.length; i++) {
const [dx, dy] = directions[i];
let count = 1; // 当前位置算一个
let x = row + dx;
let y = col + dy;
// 向正反两个方向扩展,检查是否有连续的五个相同棋子
while (x >= 0 && x < boardSize && y >= 0 && y < boardSize && board[x][y] === pieceType) {
count++;
x += dx;
y += dy;
}
x = row - dx;
y = col - dy;
while (x >= 0 && x < boardSize && y >= 0 && y < boardSize && board[x][y] === pieceType) {
count++;
x -= dx;
y -= dy;
}
if (count >= 5) {
return true; // 出现五连珠,返回胜利
}
}
return false; // 未出现五连珠
}
export const findBestMove = (boardSize, piece) => {
let bestScore = -Infinity;
let bestRow = -1;
let bestCol = -1;
const _row = boardSize.length
const _col = boardSize[0].length
for (let row = 0; row < _row; row++) {
for (let col = 0; col < _col; col++) {
if (boardSize[row][col] === 0) {
boardSize[row][col] = piece;
const score = minimax(boardSize, 0, false, -Infinity, Infinity);
boardSize[row][col] = 0;
if (score > bestScore) {
bestScore = score;
bestRow = row;
bestCol = col;
}
}
}
}
return [bestRow, bestCol];
}
// 最大值搜索算法
function minimax(boardSize, depth, isMaximizingPlayer, alpha, beta) {
const _row = boardSize.length
const _col = boardSize[0].length
if (checkWin(-1, -1, playerPiece)) {
return -1; // 玩家获胜
} else if (checkWin(-1, -1, robotPiece)) {
return 1; // 机器人获胜
} else if (isGameOver()) {
return 0; // 平局
}
if (isMaximizingPlayer) {
let maxScore = -Infinity;
for (let row = 0; row < _row; row++) {
for (let col = 0; col < _col; col++) {
if (boardSize[row][col] === 0) {
boardSize[row][col] = robotPiece;
const score = minimax(depth + 1, false, alpha, beta);
boardSize[row][col] = 0;
maxScore = Math.max(maxScore, score);
alpha = Math.max(alpha, score);
if (alpha >= beta) {
break;
}
}
}
}
return maxScore;
} else {
let minScore = Infinity;
for (let row = 0; row < _row; row++) {
for (let col = 0; col < _col; col++) {
if (boardSize[row][col] === 0) {
boardSize[row][col] = playerPiece;
const score = minimax(depth + 1, true, alpha, beta);
boardSize[row][col] = 0;
minScore = Math.min(minScore, score);
beta = Math.min(beta, score);
if (alpha >= beta) {
break;
}
}
}
}
return minScore;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册