Alpha Beta修剪Tic Tac Toe

时间:2016-04-03 19:49:43

标签: javascript tic-tac-toe

我正在为我的AI课程开展项目,我们需要实施深度限制的极小极大搜索,然后在Ultimate Tic-Tac-Toe或Tic-Tac-Toe-游戏中添加alpha-beta修剪Ception。这个版本的tic-tac-toe是3x3游戏板,由3x3游戏板组成。当您在smallBoards上的空间中进行游戏时,您刚刚玩过的移动对应于对手将要玩的下一个smallBoard。我已经能够找到常规tic tac toe的结果,但由于游戏规则它们并不适用。

如果您在左上角的中央进行游戏,下一位玩家将在bigBoard的中心板上玩牌。提供了这两个动作的图片。红色是第一个球员。

Here's the picture of the first two moves

我们的麻烦在于我们的alpha-beta实现。

关于我们的深度极限极小极大搜索

我们的minimax实现似乎正常工作。当我们尝试实现alpha-beta时,我们的AI代理正确地停止了功能。

我们的minimax实现代码如下:

function evaluateMove(outerX2, outerY2, innerX2, innerY2, depth, isAI, tempBoard)
{
var currentBoard = JSON.parse( JSON.stringify( tempBoard ));
var score = 0;
var bestScore = 0;

var playerZZ;
if (isAI) {
    playerZZ = 2;
}
else {
    playerZZ = 1;
}
if(checkForWin(2, JSON.parse( JSON.stringify( currentBoard )), outerX2, outerY2, innerX2, innerY2))
{
    //AI wins
    return 10;
}
if(checkForWin(1, JSON.parse( JSON.stringify( currentBoard )), outerX2, outerY2, innerX2, innerY2))
{
    //Human wins
    return -10;
}
else if (depth == 2) {
    return 0;
}
if (checkForBoardWin(innerX2, innerY2, 1) || checkForBoardWin(innerX2, innerY2, 2))
{
    if (isAI)
    {
    bestScore = -100;
        for (var X = 0; X < 3; X++)
        {
            for (var Y = 0; Y < 3; Y++)
            {
                for (var x = 0; x < 3; x++)
                {
                    for (var y = 0; y < 3; y++)
                    {
                        if(currentBoard[X][Y][x][y] == 0 && !(checkForBoardWin(X, Y, 1) || checkForBoardWin(X, Y, 2)))
                        {
                            //JAKE: Broken here?
                            currentBoard[X][Y][x][y] = 2
                            score = evaluateMove(X, Y, x, y, depth + 1, false, currentBoard);
                            //var bestScore = -100;
                            if (score > bestScore)
                            {
                                console.log("Line 105: Score = ", score);
                                return score;
                            }
                            else
                            {
                                return bestScore;
                            }
                        }

                    }
                }
            }
        }
    }
    else
    {
    bestScore = 100;
        for (var X = 0; X < 3; X++)
        {
            for (var Y = 0; Y < 3; Y++)
            {
                for (var x = 0; x < 3; x++)
                {
                    for (var y = 0; y < 3; y++)
                    {
                        if(currentBoard[X][Y][x][y] == 0)
                        {
                            currentBoard[X][Y][x][y] = 1
                            score = evaluateMove(X, Y, x, y, depth + 1, false, currentBoard);
                            //bestScore = 100;
                            if (score < bestScore)
                            {
                                console.log("Line 137: Score = ", score);
                                return score;
                            }
                            else
                            {
                                return bestScore;
                            }
                        }

                    }
                }
            }
        }
    }
}
else
{
bestScore = -100;
    if (isAI)
    {
        for(var x = 0; x < 3; x++)
        {
            for (var y = 0; y < 3; y++)
            {
                if(currentBoard[innerX2][innerY2][x][y] == 0)
                {
                    //JAKE: Broken here?
                    currentBoard[innerX2][innerY2][x][y] = 2
                    score = evaluateMove(innerX2, innerY2, x, y, depth + 1, false, currentBoard);
                    //bestScore = -100;
                    if (score > bestScore)
                    {
                        console.log("Line 169: Score = ", score);
                        return score;
                    }
                    else
                    {
                        return bestScore;
                    }
                }

            }
        }
    }
    else
    {
    bestScore = 100;
        for(var x = 0; x < 3; x++)
        {
            for (var y = 0; y < 3; y++)
            {
                if(currentBoard[innerX2][innerY2][x][y] == 0)
                {
                    currentBoard[innerX2][innerY2][x][y] = 1
                    score = evaluateMove(innerX2, innerY2, x, y, depth + 1, true, currentBoard);
                    bestScore = 100;
                    if (score < bestScore)
                    {
                        console.log("Line 195: Score = ", score);
                        return score;
                    }
                    else
                    {
                        return bestScore;
                    }
                }

            }
        }
    }
}
return 0;
}

关于我们的Alpha-Beta修剪实施:

我们的评估移动函数包含一些变量,X2和Y2组成了我们正在评估的bigBoard中移动的四维数组坐标。我们遵循this wikipedia page的伪代码。不幸的是我们的人工智能在左上角播放,直到它没有更多的选择这样做,在这种情况下它会在电路板的左侧播放。在过去的几天里,我和我的小组一直在梳理头发。

代码如下。

function evaluateMove(outerX2, outerY2, innerX2, innerY2, depth, isAI, tempBoard)
{
var currentBoard = JSON.parse( JSON.stringify( tempBoard ));
var score = 0;
var bestScore = 0;

var playerZZ;
if (isAI) {
    playerZZ = 2;
}
else {
    playerZZ = 1;
}
if(checkForWin(2, JSON.parse( JSON.stringify( currentBoard )), outerX2, outerY2, innerX2, innerY2))
{
    //AI wins
    return 10;
}
if(checkForWin(1, JSON.parse( JSON.stringify( currentBoard )), outerX2, outerY2, innerX2, innerY2))
{
    //Human wins
    return -10;
}
else if (depth == 2) {
    return 0;
}
if (checkForBoardWin(innerX2, innerY2, 1) || checkForBoardWin(innerX2, innerY2, 2))
{
    if (isAI)
    {
    bestScore = -100;
        for (var X = 0; X < 3; X++)
        {
            for (var Y = 0; Y < 3; Y++)
            {
                for (var x = 0; x < 3; x++)
                {
                    for (var y = 0; y < 3; y++)
                    {
                        if(currentBoard[X][Y][x][y] == 0 && !(checkForBoardWin(X, Y, 1) || checkForBoardWin(X, Y, 2)))
                        {
                            //JAKE: Broken here?
                            currentBoard[X][Y][x][y] = 2
                            score = evaluateMove(X, Y, x, y, depth + 1, false, currentBoard);
                            //var bestScore = -100;
                            if (score > bestScore)
                            {
                                console.log("Line 105: Score = ", score);
                                return score;
                            }
                            else
                            {
                                return bestScore;
                            }
                        }

                    }
                }
            }
        }
    }
    else
    {
    bestScore = 100;
        for (var X = 0; X < 3; X++)
        {
            for (var Y = 0; Y < 3; Y++)
            {
                for (var x = 0; x < 3; x++)
                {
                    for (var y = 0; y < 3; y++)
                    {
                        if(currentBoard[X][Y][x][y] == 0)
                        {
                            currentBoard[X][Y][x][y] = 1
                            score = evaluateMove(X, Y, x, y, depth + 1, false, currentBoard);
                            //bestScore = 100;
                            if (score < bestScore)
                            {
                                console.log("Line 137: Score = ", score);
                                return score;
                            }
                            else
                            {
                                return bestScore;
                            }
                        }

                    }
                }
            }
        }
    }
}
else
{
bestScore = -100;
    if (isAI)
    {
        for(var x = 0; x < 3; x++)
        {
            for (var y = 0; y < 3; y++)
            {
                if(currentBoard[innerX2][innerY2][x][y] == 0)
                {
                    //JAKE: Broken here?
                    currentBoard[innerX2][innerY2][x][y] = 2
                    score = evaluateMove(innerX2, innerY2, x, y, depth + 1, false, currentBoard);
                    //bestScore = -100;
                    if (score > bestScore)
                    {
                        console.log("Line 169: Score = ", score);
                        return score;
                    }
                    else
                    {
                        return bestScore;
                    }
                }

            }
        }
    }
    else
    {
    bestScore = 100;
        for(var x = 0; x < 3; x++)
        {
            for (var y = 0; y < 3; y++)
            {
                if(currentBoard[innerX2][innerY2][x][y] == 0)
                {
                    currentBoard[innerX2][innerY2][x][y] = 1
                    score = evaluateMove(innerX2, innerY2, x, y, depth + 1, true, currentBoard);
                    bestScore = 100;
                    if (score < bestScore)
                    {
                        console.log("Line 195: Score = ", score);
                        return score;
                    }
                    else
                    {
                        return bestScore;
                    }
                }

            }
        }
    }
}
return 0;
}

谢谢。

0 个答案:

没有答案