Fri Jul 7 20:44:00 UTC 2023 inscode

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