【问题标题】:AlphaBeta Pruning TicTacToe is not blocking, is it eval problem?Alpha Beta Pruning Tic Tac Toe 不阻塞,是 eval 问题吗?
【发布时间】:2021-01-19 21:36:18
【问题描述】:

我已经调试了好几天了,但我不知道我在井字游戏和人工智能的这段代码中做错了什么(我知道它不是真正的人工智能,但是......)我选择了因为这是 Alpha-Beta 修剪。它的 7x7 板,因此对于纯 minimax 实现来说太重了。

我的问题是我无法弄清楚为什么 Alpha-Beta 没有阻止玩家停止游戏并等待玩家移动并使用对他有利的正确移动,或者只是简单地平局。

我已经决定棋盘中心的得分(最终得分)比棋盘边缘的得分多。我相信更多地移动到中心将比边缘的移动有更多的成功机会,这就是为什么我制作了评估该移动的 AddScoreToMove 函数。 为了确保 eval 函数将检查板上所有可能的移动,我没有使该函数作为查找第一个 xxx(例如在 row0 和 col0、col1、col2 处)并返回(因为可能有 4X 或 4O)。 4X 或 4O 的得分也比其他得分高得多,应该被视为胜利。
此刻我的PCplayer(O's)是这样玩的

谁能告诉我我做错了什么?这是我的第二个 AI 程序,第一个是在 3x3 板上使用 minimax 的程序,效果很好。

C#代码如下

VB.NET 代码:

Public Class Form1
    Dim board As Char(,) = {
            {" ", " ", " ", " ", " ", " ", " "},
            {" ", " ", " ", " ", " ", " ", " "},
            {" ", " ", " ", " ", " ", " ", " "},
            {" ", " ", " ", " ", " ", " ", " "},
            {" ", " ", " ", " ", " ", " ", " "},
            {" ", " ", " ", " ", " ", " ", " "},
            {" ", " ", " ", " ", " ", " ", " "}}
    Class Move
        Public row, col As Integer
    End Class
    
    Dim BestMoveRow As Integer = 0
    Dim BestMoveCol As Integer = 0
    Dim BestMoveScore As Integer = 0

    Shared player As Char = "X", opponent As Char = "O"

    Shared Function AddScoreToMove(thatMove As Move) As Integer
        Dim row As Integer = thatMove.row
        Dim col As Integer = thatMove.col
        '0 score, move is at border 
        If ((row >= 1 And row <= 5) And col = 0) Then
            Return 0
        ElseIf ((row >= 1 And row <= 5) And col = 6) Then
            Return 0
        ElseIf (row = 0 And (col >= 0 And col <= 6)) Then
            Return 0
        ElseIf (row = 6 And (col >= 0 And col <= 6)) Then
            Return 0
        End If

        '1 score, thatMove is at border +1
        If ((row >= 2 And row <= 4) And col = 1) Then
            Return 1
        ElseIf ((row >= 2 And row <= 4) And col = 5) Then
            Return 1
        ElseIf (row = 1 And (col >= 1 And col <= 5)) Then
            Return 1
        ElseIf (row = 5 And (col >= 1 And col <= 5)) Then
            Return 1
        End If

        '2 score, thatMove is at border +2
        If (row = 2 And col = 2) Then
            Return 2
        ElseIf (row = 2 And col = 4) Then
            Return 2
        ElseIf (row = 2 And (col >= 2 And col <= 4)) Then
            Return 2
        ElseIf (row = 4 And (col >= 2 And col <= 4)) Then
            Return 2
        End If

        '3 Center thatMove 
        If (row = 3 And col <= 3) Then
            Return 3
        End If

        Return 0 'error not added lane

    End Function

    Private Shared Function eval(ByVal b As Char(,)) As Integer



        Dim playerScorerow As Integer = 0
        Dim playerScorecol As Integer = 0
        Dim playerScorecross As Integer = 0
        Dim pcScorerow As Integer = 0
        Dim pcScorecol As Integer = 0
        Dim pcScorecross As Integer = 0
        
        ''EVALUATE rows 
        For row As Integer = 0 To 3
            For col As Integer = 0 To 6
            'initialize moves to evaluate
                Dim move3 As New Move With {
                                        .row = row + 3,
                                        .col = col
                                    }
                Dim move2 As New Move With {
                                        .row = row + 2,
                                        .col = col
                                    }
                Dim move1 As New Move With {
                                        .row = row + 1,
                                        .col = col
                                    }
                Dim move0 As New Move With {
                                        .row = row,
                                        .col = col
                                    }
                                    
                If Not b(row, col) = " " Then 'ITS NOT EMPTY - PLAYER OR PC MOVED HERE
                    Dim moveScore As Integer = AddScoreToMove(move0) 'EVALUATE THAT MOVE 
                    If b(row, col) = b(row + 1, col) Then 'THERE IS 2 X or 2 O
                        Dim move1Score As Integer = AddScoreToMove(move1)
                        If b(row + 1, col) = b(row + 2, col) Then 'THERE IS 3x or 3O
                            Dim move2Score As Integer = AddScoreToMove(move2)
                            If b(row + 2, col) = b(row + 3, col) Then 'THERE IS 4X or 4O
                                Dim move3Score As Integer = AddScoreToMove(move3)
                                If b(row, col) = player Then 'PLAYER HAVE 4X HERE
                                    playerScorerow = Math.Max(playerScorerow, 100 + move3Score + move2Score + move1Score + moveScore) 'GET HIGHEST OF ALL EVALUATIONS OF THAT FOR LOOPS
                                ElseIf b(row, col) = opponent Then 'PC HAVE 4O HERE
                                    pcScorerow = Math.Min(pcScorerow, -100 - move3Score - move2Score - move1Score - moveScore)
                                End If
                            End If
                            If b(row, col) = player Then
                                playerScorerow = Math.Max(playerScorerow, 5 + move2Score + move1Score + moveScore)
                            ElseIf b(row, col) = opponent Then
                                pcScorerow = Math.Min(pcScorerow, -5 - move2Score - move1Score - moveScore)
                            End If
                        End If
                        If b(row, col) = player Then
                            playerScorerow = Math.Max(playerScorerow, 2 + move1Score + moveScore)
                        ElseIf b(row, col) = opponent Then
                            pcScorerow = Math.Min(pcScorerow, -2 - move1Score - moveScore)
                        End If
                    End If
                    If b(row, col) = player Then
                        playerScorerow = Math.Max(playerScorerow, moveScore)
                    ElseIf b(row, col) = opponent Then
                        pcScorerow = Math.Min(pcScorerow, -moveScore)
                    End If
                End If
            Next
        Next

        ''col win
        For row As Integer = 0 To 6
            For col As Integer = 0 To 3
                Dim move3 As New Move With {
                                        .row = row + 3,
                                        .col = col
                                    }
                Dim move2 As New Move With {
                                        .row = row + 2,
                                        .col = col
                                    }
                Dim move1 As New Move With {
                                        .row = row + 1,
                                        .col = col
                                    }
                Dim move0 As New Move With {
                                        .row = row,
                                        .col = col
                                    }
                If Not b(row, col) = " " Then
                    Dim moveScore As Integer = AddScoreToMove(move0)
                    If b(row, col) = b(row, col + 1) Then
                        Dim moveScore1 As Integer = AddScoreToMove(move1)
                        If b(row, col + 1) = b(row, col + 2) Then
                            Dim moveScore2 As Integer = AddScoreToMove(move2)
                            If b(row, col + 2) = b(row, col + 3) Then
                                Dim moveScore3 As Integer = AddScoreToMove(move3)
                                If b(row, col) = player Then
                                    playerScorerow = Math.Max(playerScorerow, 100 + moveScore3 + moveScore2 + moveScore1 + moveScore)
                                ElseIf b(row, col) = opponent Then
                                    pcScorerow = Math.Min(pcScorerow, -100 - moveScore3 - moveScore2 - moveScore1 - moveScore)
                                End If
                            End If
                            If b(row, col) = player Then
                                playerScorerow = Math.Max(playerScorerow, 5 + moveScore2 + moveScore1 + moveScore)
                            ElseIf b(row, col) = opponent Then
                                pcScorerow = Math.Min(pcScorerow, -5 - moveScore2 - moveScore1 - moveScore)
                            End If
                        End If
                        If b(row, col) = player Then
                            playerScorerow = Math.Max(playerScorerow, 2 + moveScore1 + moveScore)
                        ElseIf b(row, col) = opponent Then
                            pcScorerow = Math.Min(pcScorerow, -2 - moveScore1 - moveScore)
                        End If
                    End If
                    If b(row, col) = player Then
                        playerScorerow = Math.Max(playerScorerow, moveScore)
                    ElseIf b(row, col) = opponent Then
                        pcScorerow = Math.Min(pcScorerow, -moveScore)
                    End If
                End If
            Next
        Next

        'NOT FULLY IMPLEMENTED
        'cross win
        For row As Integer = 0 To 3
            For col As Integer = 0 To 3
                If Not b(row, col) = " " Then
                    If (b(row, col) = b(row + 1, col + 1) AndAlso b(row + 1, col + 1) = b(row + 2, col + 2) AndAlso b(row + 2, col + 2) = b(row + 3, col + 3)) Then
                        If b(row, col) = player Then
                            Return +10
                        ElseIf b(row, col) = opponent Then
                            Return -10
                        End If
                    End If
                End If
            Next
        Next

        'NOT FULLY IMPLEMENTED
        'cross win
        For row As Integer = 0 To 3
            For col As Integer = 3 To 6
                If Not b(row, col) = " " Then
                    If (b(row, col) = b(row + 1, col - 1) AndAlso b(row + 1, col - 1) = b(row + 2, col - 2) AndAlso b(row + 2, col - 2) = b(row + 3, col - 3)) Then
                        If b(row, col) = player Then
                            Return +10
                        ElseIf b(row, col) = opponent Then
                            Return -10
                        End If
                    End If
                End If
            Next
        Next


        Dim scoreValues() As Integer = {playerScorerow, playerScorecol, playerScorecross, pcScorerow, pcScorecol, pcScorecross}
        Dim max = scoreValues.OrderByDescending(Function(z) Math.Abs(z)).FirstOrDefault()
        
        Return max
        
    End Function

    Private Shared Function MiniMax(ByVal board As Char(,), ByVal machineMove As Boolean, ByVal depth As Integer) As Integer
        Const alpha As Integer = -10_000
        Const beta As Integer = 10_000
        Return AlphaBetaPruning(board, machineMove, depth, beta, alpha)

    End Function

    Private Shared Function AlphaBetaPruning(ByVal board As Char(,), ByVal machineMove As Boolean, ByVal depth As Integer, ByVal beta As Integer, ByVal alpha As Integer) As Integer
    
        If depth = 0 Then Return eval(board)
        If machineMove Then 'min PC MOVE
            For i As Integer = 0 To 6
                For j As Integer = 0 To 6
                    If board(i, j) = " " Then
                        board(i, j) = opponent
                        Dim score As Integer = Math.Min(AlphaBetaPruning(board, Not machineMove, depth - 1, beta, alpha), eval(board))
                        board(i, j) = " "
                        If score < beta Then
                            Form1.BestMoveRow = i
                            Form1.BestMoveCol = j
                            Form1.BestMoveScore = score
                            beta = score
                        End If
                        If alpha >= beta Then Exit For 'cutoff
                    End If
                Next
            Next
            Return beta
        Else 'max PLAYER MOVE
            For i As Integer = 0 To 6
                For j As Integer = 0 To 6
                    If board(i, j) = " " Then
                        board(i, j) = player
                        Dim score As Integer = Math.Max(AlphaBetaPruning(board, Not machineMove, depth - 1, beta, alpha), eval(board))
                        board(i, j) = " "
                        If score > alpha Then
                            alpha = score
                        End If
                        If alpha >= beta Then Exit For
                    End If
                Next
            Next
            Return alpha
        End If
    End Function
End Class

C#代码

public class Form1
{
    private char[,] board = new[] { { " ", " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " ", " " }, { " ", " ", " ", " ", " ", " ", " " } };
    class Move
    {
        public int row, col;
    }

    private int BestMoveRow = 0;
    private int BestMoveCol = 0;
    private int BestMoveScore = 0;

    private static char player = "X";
    private static char opponent = "O";

    public static int AddScoreToMove(Move thatMove)
    {
        int row = thatMove.row;
        int col = thatMove.col;
        // 0 score, move is at border 
        if (((row >= 1 & row <= 5) & col == 0))
            return 0;
        else if (((row >= 1 & row <= 5) & col == 6))
            return 0;
        else if ((row == 0 & (col >= 0 & col <= 6)))
            return 0;
        else if ((row == 6 & (col >= 0 & col <= 6)))
            return 0;

        // 1 score, thatMove is at border +1
        if (((row >= 2 & row <= 4) & col == 1))
            return 1;
        else if (((row >= 2 & row <= 4) & col == 5))
            return 1;
        else if ((row == 1 & (col >= 1 & col <= 5)))
            return 1;
        else if ((row == 5 & (col >= 1 & col <= 5)))
            return 1;

        // 2 score, thatMove is at border +2
        if ((row == 2 & col == 2))
            return 2;
        else if ((row == 2 & col == 4))
            return 2;
        else if ((row == 2 & (col >= 2 & col <= 4)))
            return 2;
        else if ((row == 4 & (col >= 2 & col <= 4)))
            return 2;

        // 3 Center thatMove 
        if ((row == 3 & col <= 3))
            return 3;

        return 0; // error not added lane
    }

    private static int eval(char[,] b)
    {
        int playerScorerow = 0;
        int playerScorecol = 0;
        int playerScorecross = 0;
        int pcScorerow = 0;
        int pcScorecol = 0;
        int pcScorecross = 0;

        // 'EVALUATE rows 
        for (int row = 0; row <= 3; row++)
        {
            for (int col = 0; col <= 6; col++)
            {
                // initialize moves to evaluate
                Move move3 = new Move()
                {
                    row = row + 3,
                    col = col
                };
                Move move2 = new Move()
                {
                    row = row + 2,
                    col = col
                };
                Move move1 = new Move()
                {
                    row = row + 1,
                    col = col
                };
                Move move0 = new Move()
                {
                    row = row,
                    col = col
                };

                if (!b[row, col] == " ")
                {
                    int moveScore = AddScoreToMove(move0); // EVALUATE THAT MOVE 
                    if (b[row, col] == b[row + 1, col])
                    {
                        int move1Score = AddScoreToMove(move1);
                        if (b[row + 1, col] == b[row + 2, col])
                        {
                            int move2Score = AddScoreToMove(move2);
                            if (b[row + 2, col] == b[row + 3, col])
                            {
                                int move3Score = AddScoreToMove(move3);
                                if (b[row, col] == player)
                                    playerScorerow = Math.Max(playerScorerow, 100 + move3Score + move2Score + move1Score + moveScore); // GET HIGHEST OF ALL EVALUATIONS OF THAT FOR LOOPS
                                else if (b[row, col] == opponent)
                                    pcScorerow = Math.Min(pcScorerow, -100 - move3Score - move2Score - move1Score - moveScore);
                            }
                            if (b[row, col] == player)
                                playerScorerow = Math.Max(playerScorerow, 5 + move2Score + move1Score + moveScore);
                            else if (b[row, col] == opponent)
                                pcScorerow = Math.Min(pcScorerow, -5 - move2Score - move1Score - moveScore);
                        }
                        if (b[row, col] == player)
                            playerScorerow = Math.Max(playerScorerow, 2 + move1Score + moveScore);
                        else if (b[row, col] == opponent)
                            pcScorerow = Math.Min(pcScorerow, -2 - move1Score - moveScore);
                    }
                    if (b[row, col] == player)
                        playerScorerow = Math.Max(playerScorerow, moveScore);
                    else if (b[row, col] == opponent)
                        pcScorerow = Math.Min(pcScorerow, -moveScore);
                }
            }
        }

        // 'col win
        for (int row = 0; row <= 6; row++)
        {
            for (int col = 0; col <= 3; col++)
            {
                Move move3 = new Move()
                {
                    row = row + 3,
                    col = col
                };
                Move move2 = new Move()
                {
                    row = row + 2,
                    col = col
                };
                Move move1 = new Move()
                {
                    row = row + 1,
                    col = col
                };
                Move move0 = new Move()
                {
                    row = row,
                    col = col
                };
                if (!b[row, col] == " ")
                {
                    int moveScore = AddScoreToMove(move0);
                    if (b[row, col] == b[row, col + 1])
                    {
                        int moveScore1 = AddScoreToMove(move1);
                        if (b[row, col + 1] == b[row, col + 2])
                        {
                            int moveScore2 = AddScoreToMove(move2);
                            if (b[row, col + 2] == b[row, col + 3])
                            {
                                int moveScore3 = AddScoreToMove(move3);
                                if (b[row, col] == player)
                                    playerScorerow = Math.Max(playerScorerow, 100 + moveScore3 + moveScore2 + moveScore1 + moveScore);
                                else if (b[row, col] == opponent)
                                    pcScorerow = Math.Min(pcScorerow, -100 - moveScore3 - moveScore2 - moveScore1 - moveScore);
                            }
                            if (b[row, col] == player)
                                playerScorerow = Math.Max(playerScorerow, 5 + moveScore2 + moveScore1 + moveScore);
                            else if (b[row, col] == opponent)
                                pcScorerow = Math.Min(pcScorerow, -5 - moveScore2 - moveScore1 - moveScore);
                        }
                        if (b[row, col] == player)
                            playerScorerow = Math.Max(playerScorerow, 2 + moveScore1 + moveScore);
                        else if (b[row, col] == opponent)
                            pcScorerow = Math.Min(pcScorerow, -2 - moveScore1 - moveScore);
                    }
                    if (b[row, col] == player)
                        playerScorerow = Math.Max(playerScorerow, moveScore);
                    else if (b[row, col] == opponent)
                        pcScorerow = Math.Min(pcScorerow, -moveScore);
                }
            }
        }

        // NOT FULLY IMPLEMENTED
        // cross win
        for (int row = 0; row <= 3; row++)
        {
            for (int col = 0; col <= 3; col++)
            {
                if (!b[row, col] == " ")
                {
                    if ((b[row, col] == b[row + 1, col + 1] && b[row + 1, col + 1] == b[row + 2, col + 2] && b[row + 2, col + 2] == b[row + 3, col + 3]))
                    {
                        if (b[row, col] == player)
                            return +10;
                        else if (b[row, col] == opponent)
                            return -10;
                    }
                }
            }
        }

        // NOT FULLY IMPLEMENTED
        // cross win
        for (int row = 0; row <= 3; row++)
        {
            for (int col = 3; col <= 6; col++)
            {
                if (!b[row, col] == " ")
                {
                    if ((b[row, col] == b[row + 1, col - 1] && b[row + 1, col - 1] == b[row + 2, col - 2] && b[row + 2, col - 2] == b[row + 3, col - 3]))
                    {
                        if (b[row, col] == player)
                            return +10;
                        else if (b[row, col] == opponent)
                            return -10;
                    }
                }
            }
        }


        int[] scoreValues = new[] { playerScorerow, playerScorecol, playerScorecross, pcScorerow, pcScorecol, pcScorecross };
        var max = scoreValues.OrderByDescending(z => Math.Abs(z)).FirstOrDefault();

        return max;
    }

    private static int MiniMax(char[,] board, bool machineMove, int depth)
    {
        const int alpha = -10_000;
        const int beta = 10_000;
        return AlphaBetaPruning(board, machineMove, depth, beta, alpha);
    }

    private static int AlphaBetaPruning(char[,] board, bool machineMove, int depth, int beta, int alpha)
    {
        if (depth == 0)
            return eval(board);
        if (machineMove)
        {
            for (int i = 0; i <= 6; i++)
            {
                for (int j = 0; j <= 6; j++)
                {
                    if (board[i, j] == " ")
                    {
                        board[i, j] = opponent;
                        int score = Math.Min(AlphaBetaPruning(board, !machineMove, depth - 1, beta, alpha), eval(board));
                        board[i, j] = " ";
                        if (score < beta)
                        {
                            Form1.BestMoveRow = i;
                            Form1.BestMoveCol = j;
                            Form1.BestMoveScore = score;
                            beta = score;
                        }
                        if (alpha >= beta)
                            break; // cutoff
                    }
                }
            }
            return beta;
        }
        else
        {
            for (int i = 0; i <= 6; i++)
            {
                for (int j = 0; j <= 6; j++)
                {
                    if (board[i, j] == " ")
                    {
                        board[i, j] = player;
                        int score = Math.Max(AlphaBetaPruning(board, !machineMove, depth - 1, beta, alpha), eval(board));
                        board[i, j] = " ";
                        if (score > alpha)
                            alpha = score;
                        if (alpha >= beta)
                            break;
                    }
                }
            }
            return alpha;
        }
    }
}

【问题讨论】:

  • 你应该调试,监控变量,看看哪里出错了。
  • 7x7 棋盘的游戏规则是什么?
  • @user3386109 在大多数情况下,用 4O 或 4X 获胜是有规则的,但我看到了 5 的变化
  • 当它是一个表单级别的变量时,你为什么要将 board 传递给 AlphaBetaPruning
  • @Mary 这当然是错误的,但不能解决我问的问题;)

标签: c# vb.net algorithm artificial-intelligence minimax


【解决方案1】:

经过另一天的调试,我有点迷路了,但我想出了如何绕过它,这可能是这个问题的真正解决方案。 AlphaBeta 只专注于获胜。这实际上与 eval 函数有关,如果我们对 eval 函数考虑更多因素,那么该函数会更好。 这就是为什么我们有

  1. 基本获胜因素 -> 评估赢得比赛的动作
  2. 阻止敌人因素 -> 拖延游戏
  3. 还有我尚未实施的分叉因素。 相关信息在这里: https://en.wikipedia.org/wiki/Tic-tac-toe#Strategy 并从 https://stackoverflow.com/a/19406575/9283016

简而言之 - 简单评估(仅)获胜的简单 AlphaBeta 函数不考虑游戏时间。 我们必须编写适当的阻塞和分叉函数。

Private Shared Function evalBlock(ByVal b As Char(,)) As Move
    Dim blockingMove As New Move With {
         .row = -1,
        .col = -1
        }

    ''row block
    For row As Integer = 0 To 4
        For col As Integer = 0 To 6
            If Not b(row, col) = " " Then
                If b(row, col) = b(row + 1, col) Then '2 X or 2 O
                    If b(row, col) = player Then
                        If b(row + 2, col) = " " Then
                            blockingMove.row = row + 2
                            blockingMove.col = col
                            Return blockingMove
                        End If
                        If row > 0 Then
                            If b(row - 1, col) = " " Then
                                blockingMove.row = row - 1
                                blockingMove.col = col
                                Return blockingMove
                            End If
                        End If

                    End If
                End If
            End If
        Next
    Next

    ''col block
    For row As Integer = 0 To 6
        For col As Integer = 0 To 4
            If Not b(row, col) = " " Then
                If b(row, col) = b(row, col + 1) Then '2 X or 2 O
                    If b(row, col) = player Then
                        If b(row, col + 2) = " " Then
                            blockingMove.row = row
                            blockingMove.col = col + 2
                            Return blockingMove
                        End If
                        If col > 1 Then
                            If b(row, col - 1) = " " Then
                                blockingMove.row = row
                                blockingMove.col = col - 1
                                Return blockingMove
                            End If
                        End If
                    End If
                End If
            End If
        Next
    Next


    '\ cross block
    For row As Integer = 0 To 4
        For col As Integer = 0 To 4
            If Not b(row, col) = " " Then
                If (b(row, col) = b(row + 1, col + 1)) Then
                    If b(row, col) = player Then
                        If b(row + 2, col + 2) = " " Then
                            blockingMove.row = row + 2
                            blockingMove.col = col + 2
                        End If

                        If (row > 0 And col > 0) Then
                            If b(row - 1, col - 1) = " " Then
                                blockingMove.row = row - 1
                                blockingMove.col = col - 1
                            End If
                        End If
                    End If
                End If
            End If
        Next
    Next


    '/ cross block
    For row As Integer = 0 To 4
        For col As Integer = 2 To 6
            If Not b(row, col) = " " Then
                If (b(row, col) = b(row + 1, col - 1)) Then
                    If b(row, col) = player Then
                        If b(row, col) = " " Then
                            blockingMove.row = row + 2
                            blockingMove.col = col - 2
                        End If
                    End If
                End If
            End If
        Next
    Next

    blockingMove.row = -1
    blockingMove.col = -1
    Return blockingMove

End Function

当然,返回阻挡移动不会做任何事情。在 AlphaBeta 函数中,我们必须为此分配适当的值。所以我发现我们的 AI 会阻止玩家,如果他做了 2 次获胜的动作,并且阻止比获胜更可取。同样,在 2 个玩家移动之后阻止比在 3 个玩家移动之后阻止更有意义,因为如果我们使用 4 移动获胜的规则进行游戏可能会为时已晚。

类似这样的:

                Dim score As Integer = Math.Min(AlphaBetaPruning(board, Not machineMove, depth - 1, beta, alpha), eval(board) + depth)
                Dim BlockingMove As Move = evalBlock(board)
                If BlockingMove.row <> -1 Then
                    Dim blockingMoveScore As Integer = 5000
                    If score < blockingMoveScore Then
                        Form1.BestMoveRow = BlockingMove.row
                        Form1.BestMoveCol = BlockingMove.col
                        Form1.BestMoveScore = score
                    End If
                End If

这就是我在使用我的 AI 进行第一场比赛后输掉的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多