Javascript Otherlo极小极大算法不';t在React.js中工作
我有一个问题,AI玩家总是玩它遇到的第一个可用的移动。我试着让人工智能使用极大极小算法。你觉得我怎么能解决这个问题 以下是代码(带说明): 在显示代码之前先了解一下:Javascript Otherlo极小极大算法不';t在React.js中工作,javascript,reactjs,minimax,Javascript,Reactjs,Minimax,我有一个问题,AI玩家总是玩它遇到的第一个可用的移动。我试着让人工智能使用极大极小算法。你觉得我怎么能解决这个问题 以下是代码(带说明): 在显示代码之前先了解一下: 我试着以这样一种方式来设置它,AI玩家(不管它的颜色是什么)是最大化的玩家。因此,如果玩家回合为白色,但白色是AI玩家,则isMaximizing=true 我想指出这一点,这样就不会混淆玩家在颜色方面的转向和玩家在最大化方面的转向 我最初使用它的地方: // AI Hard - Return Minimax function
- 我试着以这样一种方式来设置它,AI玩家(不管它的颜色是什么)是最大化的玩家。因此,如果玩家回合为白色,但白色是AI玩家,则isMaximizing=true
- 我想指出这一点,这样就不会混淆玩家在颜色方面的转向和玩家在最大化方面的转向
// AI Hard - Return Minimax
function minimaxAI(){
// Here's where the minimax function is initially called
const AI = (ourPlayer === "white") ? "black" : "white"
const squares = history[history.length - 1].slice()
// AI is the maximizing player so we get -Infinity, it'll try to increase the value of bestScore
let bestScore = -Infinity
let bestMove = null
// Perform minimax algorithm for each valid move and pick the best score
// Get the valid moves for the AI player
const AIValidMoves = checkSquaresForSides()[(AI === "black") ? 0 : 1 ]
for (var AIMove=0;AIMove<AIValidMoves.length;AIMove++){
// Play the AI moves and generate the new board
const crds = AIValidMoves[AIMove].turned
crds.unshift(AIValidMoves[AIMove].coordinates)
const newBoard = handleMove(crds, squares,AI,false,false)
// Check minimax for the new board
const score = minimax(newBoard,4,false)
// If score is higher than the current one, replace the highest score and the according coordinates
if (score > bestScore || AIMove === 0) {
bestScore = score
bestMove = crds
}
}
console.log('Final Value:')
console.log(bestScore)
// Play the move(this time on the real board)
const upcomingAI = handleMove(bestMove)
// Set it as the latest of the collection of squares
setHistory(upcomingAI)
// Useless to know for this issue
setStepNumber(upcomingAI.length - 1)
}
//AI硬返回极小极大值
函数minimaxAI(){
//这里是minimax函数最初被调用的地方
常量AI=(我们的玩家==“白色”)?“黑色”:“白色”
常数平方=历史[history.length-1].slice()
//AI是最大化的玩家,所以我们得到了无限,它将试图增加bestScore的价值
设bestScore=-无穷大
设bestMove=null
//对每个有效移动执行minimax算法,并选择最佳分数
//获得AI玩家的有效招式
const AIValidMoves=checkSquaresForSides()[(AI==“黑色”)?0:1]
对于(var AIMove=0;AIMove bestScore | | AIMove==0){
最佳分数
最佳移动=crds
}
}
console.log('最终值:')
console.log(最佳分数)
//玩这个动作(这次是在真正的棋盘上)
const upcomingAI=handleMove(最佳移动)
//将其设置为正方形集合的最新值
设置历史记录(upcomingAI)
//知道这个问题没用
设置步骤编号(upcomingAI.length-1)
}
极小极大算法本身:
function minimax(board, depth, isMaximizing) {
const AI = (ourPlayer === "white") ? "black" : "white"
const stones = setStoneCount(board)
// If there's a winner, return Infinity, 0 or -Infinity depending on whether AI won, it is a tie or our player won
if (stones[0] === 0 || stones[1] === 0 || stones[0] + stones[1] === 64) {
// Return the score of the move if the game is over
let score = (stones[(AI === "black") ? 1 : 0] === 0) ? Infinity : (stones[stones[0] === stones[1]]) ? 0 : -Infinity
return score
} else if (depth === 0) {
// If the maximal depth is reached, then evaluate the current board by counting all the stones for the both sides and subtracting one from the other appropriately
const squares = setStoneCount(board)
let score = 0
if (AI === "black") {
score = squares[0] - squares[1]
} else if (AI === "white") {
score = squares[1] - squares[0]
}
return score
}
if (isMaximizing) {
// Perform minimax if depth !== 0 and isMaximizing, just like we did initially
let bestScore = -Infinity
// Get the valid moves for the maximizing player
const AIValidMoves = checkSquaresForSides()[(AI === "black") ? 0 : 1 ] // AI Moves because isMaximizing = true
for (var AIMove=0;AIMove<AIValidMoves.length;AIMove++){
const crds = AIValidMoves[AIMove].turned
crds.unshift(AIValidMoves[AIMove].coordinates)
const newBoard = handleMove(crds,board,AI,false,false)
// check for isMaximizing
let maximizingNext = !isMaximizing
// If there's no move to make for the one side, player turn might stay the same. Here, I check for those situations
const available = checkSquaresForSides(newBoard)
if (available[0].length === 0) {
if (AI === "white") {
maximizingNext = true
} else {
maximizingNext = false
}
} else if (available[1].length === 0){
if (AI === "black") {
maximizingNext = true
} else {
maximizingNext = false
}
}
// Perform minimax for the new board(depth is one less)
const score = minimax(newBoard,depth - 1,maximizingNext)
// If current score is higher than the highest one caught yet, it should be replaced
if (score > bestScore) {
bestScore = score
}
}
return bestScore
} else {
// Perform minimax if depth !== 0 and isMaximizing
let bestScore = Infinity
// Get the valid squares for the minimizing player
const PlayerValidMoves = checkSquaresForSides()[(AI === "black") ? 1 : 0 ] // Player Moves because isMaximizing = false
// Play each move one-by-one for the minimizing player
for (var playerMove=0;playerMove<PlayerValidMoves.length;playerMove++) {
const crds = PlayerValidMoves[playerMove].turned
crds.unshift(PlayerValidMoves[playerMove].coordinates)
const newBoard = handleMove(crds,board,ourPlayer,false,false)
// check for isMaximizing
let maximizingNext = !isMaximizing
// Just like the previous one, check whether there's an exceptional situation to be considered with the player turn
const available = checkSquaresForSides(newBoard)
if (available[0].length === 0) {
if (AI === "white") {
maximizingNext = true
} else {
maximizingNext = false
}
} else if (available[1].length === 0){
if (AI === "black") {
maximizingNext = true
} else {
maximizingNext = false
}
}
// Perform minimax for the new board
const score = minimax(newBoard,depth - 1,maximizingNext)
// If the current score is lower than the lowest one obtained so far, it should be replaced
if (score < bestScore) {
bestScore = score
}
}
return bestScore
}
}
函数极小极大值(板、深度、最大化){
常量AI=(我们的玩家==“白色”)?“黑色”:“白色”
const stones=setStoneCount(板)
//如果有赢家,返回无穷大、0或-无穷大,这取决于AI赢了,这是平局还是我们的玩家赢了
如果(石头[0]==0 | |石头[1]==0 | |石头[0]+石头[1]==64){
//如果游戏结束,返回移动的分数
让分数=(石头[(AI==“黑色”)?1:0]==0)?无限:(石头[石头[0]==石头[1]])?0:-无限
回击得分
}else if(深度===0){
//如果达到最大深度,则通过计算两侧的所有石头并从另一侧中适当减去一块来评估当前板
常数平方=设置计数(板)
让分数=0
如果(AI==“黑色”){
分数=平方[0]-平方[1]
}否则如果(AI==“白色”){
分数=平方[1]-平方[0]
}
回击得分
}
if(最大化){
//如果深度!==0且isMaximizing,则执行minimax,就像我们最初做的一样
设bestScore=-无穷大
//为玩家获得有效的移动
const AIValidMoves=checkSquaresForSides()[(AI==“black”)?0:1]//AI移动是因为isMaximizing=true
对于(var AIMove=0;AIMove我解决了它,只是将board evaluation部分更改为:
// The initial score
let score = 0
// value board for each square
const sq_val = [
[160, -20, 20, 5, 5, 20, -20, 160],
[-20, -40, -5, -5, -5, -5, -40, -20],
[20, -5, 15, 3, 3, 15, -5, 20],
[5, -5, 3, 3, 3, 3, -5, 5],
[5, -5, 3, 3, 3, 3, -5, 5],
[20, -5, 15, 3, 3, 15, -5, 20],
[-20, -40, -5, -5, -5, -5, -40, -20],
[160, -20, 20, 5, 5, 20, -20, 160]
]
// Our stones' positions are looked for and the according values are added or substracted depending on whether the player found is the maximizing player or the minimizing player(AI Player: Maximizing, Our Player: Minimizing)
for (var row=0;row<8;row++)
for (var col=0;col<8;col++) {
if (board[row][col] === AI) {
score += sq_val[row][col]
} else if (board[row][col] === ourPlayer) {
score -= sq_val[row][col]
}
}
}
// The score is returned
return score
//初始分数
让分数=0
//每平方米的价值板
常数sq_val=[
[160, -20, 20, 5, 5, 20, -20, 160],
[-20, -40, -5, -5, -5, -5, -40, -20],
[20, -5, 15, 3, 3, 15, -5, 20],
[5, -5, 3, 3, 3, 3, -5, 5],
[5, -5, 3, 3, 3, 3, -5, 5],
[20, -5, 15, 3, 3, 15, -5, 20],
[-20, -40, -5, -5, -5, -5, -40, -20],
[160, -20, 20, 5, 5, 20, -20, 160]
]
//根据找到的玩家是最大化玩家还是最小化玩家(AI玩家:最大化,我们的玩家:最小化),我们会查找石头的位置,并添加或删除相应的值
对于(变量行=0;行