0

所以我的井字游戏的人工智能有一些问题。人工智能是纯粹的防御性的,所以它总是会阻止你。它通常最初适用于我的第一种情况,因此例如,如果我先播放左上角然后播放中上角,它将始终位于右上角。其他情况,比如我玩两条对角线,可能会冻结游戏,或者让我再转一圈。这些问题只有在我实现了我的错误智能 AI 之后才出现。最初,该程序有一个“愚蠢的 AI”,它会选择随机点,正如您将在代码底部看到的那样。此外,我认为问题在于某些阻塞条件可能会相互冲突并导致问题。我怎样才能解决这个问题?相关代码如下: 坐标基于井字格,左上角为(0,

void Game::AIGetNextMoveRand()
{
    //top row
    if(GetSquareState(0,0) == O && GetSquareState(1,0) == O)
    {
        do
        {
            AIMoveX = 2;
            AIMoveY = 0; 
        }
            while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);

    }
    else if(GetSquareState(2,0) == O && GetSquareState(1,0) == O)
    {

        do
        {
            AIMoveX = 0;
            AIMoveY = 0;
        }
            while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    //middle row
    else if(GetSquareState(0,1) == O && GetSquareState(1,1) == O)
    {
        do
        {
        AIMoveX = 2;
        AIMoveY = 1;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(2,1) == O && GetSquareState(1,1) == O)
    {
        do
        {
        AIMoveX = 0;
        AIMoveY = 1;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);    
    }
    // bottom row
    else if(GetSquareState(0,2) == O && GetSquareState(1,2) == O)
    {
        do
        {
            AIMoveX = 2;
            AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(2,2) == O && GetSquareState(1,2) == O)
    {
        do
        {
        AIMoveX = 0;
        AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    // vert 0
    else if(GetSquareState(0,0) == O && GetSquareState(0,1) == O)
    {
        do
        {
        AIMoveX = 0;
        AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(0,2) == O && GetSquareState(0,1) == O)
    {
        do
        {
            AIMoveX = 0;
            AIMoveY = 0;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    // vert 1
    else if(GetSquareState(1,0) == O && GetSquareState(1,1) == O)
    {

        do
        {
            AIMoveX = 1;
            AIMoveY = 2;
        }
            while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(1,2) == O && GetSquareState(1,1) == O)
    {
        do
        {
            AIMoveX = 1;
            AIMoveY = 0;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    //vert 2
    else if(GetSquareState(2,2) == O && GetSquareState(2,1) == O)
    {
        do
        {
            AIMoveX  = 2;
            AIMoveY = 0;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(2,0) == O && GetSquareState(2,1) == O)
    {
        do
        {
            AIMoveX = 2;
            AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    // diagonal 1
    else if(GetSquareState(0,0) == O && GetSquareState(1,1) == O)
    {

        do
        {
            AIMoveX = 2;
            AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(2,2) == O && GetSquareState(1,1) == O)
    {

        do
        {
            AIMoveX = 0;
            AIMoveY = 0;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    //diagonal 2
    else if(GetSquareState(0,2) == O && GetSquareState(1,1) == O)
    {
        do
        {
            AIMoveX = 0;
            AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    else if(GetSquareState(0,2) == O && GetSquareState(1,1) == O)
    {
        do
        {
            AIMoveX = 2;
            AIMoveY = 0;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    // mid 0
    else if(GetSquareState(0,0) == O && GetSquareState(2,0) == O)
    {

        do
        {
            AIMoveX = 1;
            AIMoveY = 0;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    //mid 1
    else if(GetSquareState(1,0) == O && GetSquareState(2,1) == O)
    {
        do
        {
            AIMoveX = 1;
            AIMoveY = 1;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    // mid 2
    else if(GetSquareState(0,2) == O && GetSquareState(2,2) == O)
    {
        do
        {
            AIMoveX = 1;
            AIMoveY = 2;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    //diag 1
    else if(GetSquareState(0,0) == O && GetSquareState(2,2) == O)
    {
        do
        {
            AIMoveX = 1;
            AIMoveY = 1;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }
    //diag 2
    else if(GetSquareState(2,0) == O && GetSquareState(0,2) == O)
    {

        do 
        {
            AIMoveX = 1;
            AIMoveY = 1;
        }
        while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
    }

    else 
    {
    do 
    {
        AIMoveX = rand() % 3;
        AIMoveY = rand() % 3;
    }while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);

    }
    }

void Game::DoAITurnRand()
{
    AIGetNextMoveRand();
    SetSquareState(AIMoveX,AIMoveY,activePlayer);
    EndTurn();
}
4

1 回答 1

1

do while 循环是垃圾。考虑一下,如果您的规则做出了错误的选择(即试图在填充的方格上进行游戏),那么再次做出同样的错误选择将无济于事。事实上,这就是你得到“冻结”的原因。您需要重新组织代码的逻辑。我建议如果你的 AI 选择了一个非法方块,那么你应该回到你的随机选择代码,那么至少你会得到一个合法的举动。

像这样的东西

// no move selected yet
AIMoveX = -1;
AIMoveY = -1;

// AI rules
if(GetSquareState(0,0) == O && GetSquareState(1,0) == O)
{
    AIMoveX = 2;
    AIMoveY = 0; 
}
else if(GetSquareState(2,0) == O && GetSquareState(1,0) == O)
{
    AIMoveX = 0;
    AIMoveY = 0;
}
// lots more rules
...

// check for fallback to random move
if ((AIMoveX == -1 && AIMoveY == -1)             // if no rules applied
    || GetSquareState(AIMoveX,AIMoveY) != EMPTY) // or if the square is not empty
{
    // pick a random square
    do 
    {
        AIMoveX = rand() % 3;
        AIMoveY = rand() % 3;
    }
    while(GetSquareState(AIMoveX,AIMoveY) != EMPTY);
}

我最初将 AIMoveX 和 AIMoveY 设置为 -1 表示尚未选择任何规则。如果在通过所有规则后它们仍然是-1,那么我知道没有选择任何规则,我必须做出随机选择。如果确实选择了一条规则,但它选择了一个非空方格,那么我也会随机选择。我在代码末尾测试了这两个条件。

您必须仔细考虑您编写的代码到底做了什么。仅仅在一个地方放置一个 do while 循环,因为它在另一个地方工作是不对的。

于 2013-04-07T06:21:19.517 回答