Fri Jul 7 20:44:00 UTC 2023 inscode

上级 0cd85653
......@@ -64,6 +64,7 @@ async function playChess(item, row, col) {
setPiece([y, x], is_white)
const testRobo = checkWin({ row: y, col: x, board: lattices.value, player: is_white, win_size: win_size.value })
console.log(testRobo)
if (testRobo) {
isWin = testRobo
}
......
......@@ -11,7 +11,7 @@ import { is_empty, checkWin, is_black, is_white } from "./index"
* @return {[number, number]} 返回机器人回合要落子的坐标
*/
export async function robotPlay(board, player, win_size) {
const content = `这是一个五子棋游戏,${JSON.stringify(board)},只能在"${is_empty}"中选择下一步的位置,"${player}"要下到哪?请不要返回多余的文字,只返回数组,比如["x", "y"]。`
const content = `这是一个五子棋游戏,${JSON.stringify(board)},只能在"${is_empty}"中选择下一步的位置,"${player}"要下到哪?请不要返回多余的文字,只返回数组,比如[x, y]。`
const body = {
messages: [
{
......
......@@ -104,28 +104,39 @@ export function checkWin({ row, col, board, player, win_size }) {
*/
export function robotPlay(board, win_size) {
let maxScorePos = [];
let maxScore = -1;
// 空位 对每个空位进行评分
board.map((item, row) => {
return item.map((_item, col) => {
const scores = board.map((item, row) => {
return item.flatMap((_item, col) => {
if (_item === is_empty) {
let score = 0;
// 评估每个空位置的价值,从八个方向去计算
score = directions.reduce((r, [y, x]) => {
const square = getDirectionScore(board, row, col, [y, x], win_size)
return r + square
}, 0)
// 选取分数最高的空位
if (score >= maxScore) {
maxScorePos = [row, col];
maxScore = score;
}
const score = directions.reduce((r, [y, x]) => {
r[is_black] += getDirectionScore(board, row, col, [y, x], win_size, is_black)
r[is_white] += getDirectionScore(board, row, col, [y, x], win_size, is_white)
return r
}, {
[is_black]: 0,
[is_white]: 0
})
if (score[is_black] == 0 && score[is_white] == 0) return []
return [{
[`${row}_${col}`]: score
}]
} else {
return []
}
})
}).flat(1)
const _scores = scores.sort((black_score, white_score) => {
const [b_s1, b_w1] = Object.values(Object.values(black_score)[0])
const [w_s1, w_w1] = Object.values(Object.values(white_score)[0])
const score1 = b_s1 > b_w1 ? b_s1 : b_w1
const score2 = w_s1 > w_w1 ? w_s1 : w_w1
return score2 - score1
})
return maxScorePos;
console.log(_scores)
return Object.keys(_scores[0])[0].split('_');
}
/**
......@@ -138,13 +149,15 @@ export function robotPlay(board, win_size) {
* 计算公式 10**(n)
*
* 是以一条线的记录积分,一个位置上正负方向为一条线
* 同样是三颗棋子,没有挡住的比挡住一边的分数要大
* 当一个位置上 横 竖 斜 反斜 位置上都有棋子
* 积分最大为 4 * (10**8) = 400000000
* 积分最小为 4 * (10**0) = 4
*
* 连子边界判断
* 连子边界判断,连子分 **** 和 ** **
* 判断单边,双边,连子末尾是否有障碍物
* 相同的棋子数,没有挡住的比挡住的分数要大 10**(n)
*
* 单边,两边空位置多的那边加分 10**(n) =====
*
* 黑白棋棋盘积分判断
* 比较黑白棋的棋盘最高积分,积分大的位置优先下,避免总是在防守
......@@ -171,12 +184,12 @@ function getBoundary(size, num) {
* @param {number} col 列
* @return {{num: number, empty_num: number}} 说明:num: 棋子个数;empty_num: 空格数量
*/
function getJoinInfo(board, row, col, [y, x]) {
function getJoinInfo(board, row, col, [y, x], player) {
const ROW = board.length
const COL = board[0].length
// 连续棋子数
let num = 0
// 一侧到边缘的距离
// 一侧到边缘的空位
let empty_num = 0
// 不包括当前位置
let _row = row + y
......@@ -188,7 +201,7 @@ function getJoinInfo(board, row, col, [y, x]) {
break;
}
// 连珠计数
if (!empty_num && item === is_black) {
if (!empty_num && item === player) {
num += 1
}
// 计算空位数
......@@ -201,7 +214,7 @@ function getJoinInfo(board, row, col, [y, x]) {
return {
num,
empty_num,
empty_num
}
}
function pow(num = 0) {
......@@ -216,25 +229,27 @@ function pow(num = 0) {
* @param {number} win_size 需要几个棋子才赢
* @returns
*/
function getDirectionScore(board, row, col, [y, x], win_size) {
let res = 0
const { num: r_num, empty_num: r_empty_num } = getJoinInfo(board, row, col, [y, x])
const { num: l_num, empty_num: l_empty_num } = getJoinInfo(board, row, col, [y * -1, x * -1])
res = r_num + l_num
// 如果是中间断掉的 1,1; 1,2; 1,3; 2,2
if (r_num !== 0 && l_num !== 0) {
// 两边都有障碍物且小于 win_size
if (r_empty_num === 0 && l_empty_num === 0 && (r_num + l_num) < win_size) {
return 0
}
// 一边有障碍物
if (r_empty_num !== 0 || l_empty_num !== 0) {
// 只判断长的那边有障碍物的
function getDirectionScore(board, row, col, [y, x], win_size, player) {
const { num: r_num, empty_num: r_empty_num } = getJoinInfo(board, row, col, [y, x], player)
const { num: l_num, empty_num: l_empty_num } = getJoinInfo(board, row, col, [y * -1, x * -1], player)
const SIZE = r_num + l_num
// 没有棋子
if (SIZE == 0) return 0
// 两边有障碍物且小于 win_size
if (r_empty_num == 0 && l_empty_num == 0 && (SIZE + 1) < win_size) return 0
// 两边都没障碍物
if (r_empty_num != 0 && l_empty_num != 0) {
// 单边,哪边空位置多,加分
if ((r_num != 0 && l_num == 0 && (l_empty_num + 1) > r_empty_num) || (l_num != 0 && r_num == 0 && (r_empty_num + 1) > l_empty_num)) {
return (10 ** SIZE) * 2
}
}
// TODO:还有其他的判断,以后再做了
// 如果位置不够 win_size,要加上当前位置
return 10 ** res
return 10 ** SIZE
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册