Javascript中connect4的Minimax算法
我试图创建一个minimax ai来与游戏connect 4中的人类玩家进行对抗。我编写了minimax函数和它的helper函数,但是当我测试它时,它返回了看似随机的值,或者当玩家在一定数量的移动中没有可能获胜时,它会赢 与伪代码示例相比,我尝试检查递归调用和程序的执行方式,但没有什么不同。我希望代码总是返回-10,如果轮到蓝色玩家并且蓝色玩家已经有3个在一条线上,如果轮到红色玩家并且红色玩家已经有3个在一条线上,则返回10 有时出现的一个问题是,极小极大函数会输出无穷大或-无穷大 代码如下:Javascript中connect4的Minimax算法,javascript,algorithm,minimax,Javascript,Algorithm,Minimax,我试图创建一个minimax ai来与游戏connect 4中的人类玩家进行对抗。我编写了minimax函数和它的helper函数,但是当我测试它时,它返回了看似随机的值,或者当玩家在一定数量的移动中没有可能获胜时,它会赢 与伪代码示例相比,我尝试检查递归调用和程序的执行方式,但没有什么不同。我希望代码总是返回-10,如果轮到蓝色玩家并且蓝色玩家已经有3个在一条线上,如果轮到红色玩家并且红色玩家已经有3个在一条线上,则返回10 有时出现的一个问题是,极小极大函数会输出无穷大或-无穷大 代码如下:
function Disc(player, x){
this.player = player;
this.x = x;
this.draw = function(){
c.beginPath();
c.arc(this.x, 31, 30, 0, 2 * Math.PI, false);
c.fillStyle = player;
c.fill();
c.stroke();
c.fillStyle;
}
this.lock = function(board){
for(rowsDetect = 0; rowsDetect < rows; rowsDetect++){
if(board[rowsDetect][Math.floor(this.x / 70)] != "white"){
board[rowsDetect - 1][Math.floor(this.x / 70)] = this.player;
return;
}
}
board[rows - 1][Math.floor(this.x / 70)] = player;
}
}
function availSpots(board){
availableSpots = [];
for(i = 0; i < columns; i++){
if(board[0][i] == "white"){
availableSpots.push(i);
}
}
return availableSpots;
}
function isWin(board, player){
for(i = 0; i < rows; i++){
for(j = 0; j < columns - 3; j++){
if(
board[i][j] == player &&
board[i][j + 1] == player &&
board[i][j + 2] == player &&
board[i][j + 3] == player
){
return true;
}
}
}
for(i = 0; i < rows - 3; i++){
for(j = 0; j < columns; j++){
if(
board[i][j] == player &&
board[i + 1][j] == player &&
board[i + 2][j] == player &&
board[i + 3][j] == player
){
return true;
}
}
}
for(i = 0; i < rows - 3; i++){
for(j = 0; j < columns - 3; j++){
if(
board[i][j] == player &&
board[i + 1][j + 1] == player &&
board[i + 2][j + 2] == player &&
board[i + 3][j + 3] == player
){
return true;
}
}
}
for(i = 0; i < rows - 3; i++){
for(j = 3; j < columns; j++){
if(
board[i][j] == player &&
board[i + 1][j - 1] == player &&
board[i + 2][j - 2] == player &&
board[i + 3][j - 3] == player
){
return true;
}
}
}
}
function isTerminalNode(node){
return isWin(node, "blue") || isWin(node, "red") || availSpots.length == 0 //is a tie;
}
function minimax(node, depth, maximizingPlayer){
let availableSpots = availSpots(node);
if(depth == 0 || isTerminalNode(node)){
if(isWin(node, "red")){
return 10;
} else if(isWin(node, "blue")){
return -10;
} else if(availSpots.length == 0){
return 0;
}
}
if(maximizingPlayer){
value = -Infinity;
for(col = 0; col < availableSpots.length; col++){
boardCopy = [];
for(i = 0; i < rows; i++){
boardCopy.push([0]);
for(j = 0; j < columns; j++){
boardCopy[i][j] = node[i][j];
}
}
let pieceCopy = new Disc("red", /*x value of scenario where disc is put*/availableSpots[col] * 70); /*multiplied by 70 because in actual game
when placed it needs to draw piece
as well for x value, so x
value is divided by 70 then floored
to get its column*/
pieceCopy.lock(boardCopy);
value = Math.max(value, minimax(boardCopy, depth - 1, false));
}
return value;
} else {
value = Infinity;
for(col = 0; col < availableSpots.length; col++){
boardCopy = [];
for(i = 0; i < rows; i++){
boardCopy.push([0]);
for(j = 0; j < columns; j++){
boardCopy[i][j] = node[i][j];
}
}
// lock function is to drop on connect 4 board
let pieceCopy = new Disc("blue", availableSpots[col] * 70);
pieceCopy.lock(boardCopy);
value = Math.min(value, minimax(boardCopy, depth - 1, true));
}
return value;
}
}
功能光盘(播放器,x){
this.player=player;
这个.x=x;
this.draw=函数(){
c、 beginPath();
c、 弧(这个.x,31,30,0,2*Math.PI,false);
c、 fillStyle=玩家;
c、 填充();
c、 笔划();
c、 填充样式;
}
this.lock=功能(板){
for(rowsDetect=0;rowsDetect
所有变量都应该使用let
或var
正确声明,包括循环索引变量。你能举一些例子吗,因为我尝试使用for循环变量时,它会在运行时冻结网站。let i,j代码>换句话说。这叫做声明。你已经为一些变量设置了它们,但是它们都应该被声明。哪里是.lock
方法定义的?@zer00ne它是在disc构造函数中定义的,我将发布代码。锁定方法位于顶部。