首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tic Tac脚趾完美AI算法:在“创建叉”步骤中的更深层次

Tic Tac脚趾完美AI算法:在“创建叉”步骤中的更深层次
EN

Stack Overflow用户
提问于 2011-11-27 16:34:36
回答 1查看 14K关注 0票数 17

我已经在StackOverflow上读过许多Toe主题。我发现维基百科上的策略适合我的演示项目:

玩家可以发挥完美的抽搐-战术-脚趾,如果他们选择移动的最高优先级在下面的table3。

( 1)赢:如果你有两连胜,打第三局就能得到三连胜。

2)阻挡:如果对手连续两次,打第三次来阻挡他们。

3) Fork:创造一个机会,在那里你可以通过两种方式赢。

4)阻挡对手的叉子:

选项1:连续创建两个,以迫使对手防守,只要这不会导致他们制造叉子或获胜。例如,如果"X“有一个角,"O”有中间,而"X“也有相反的角,"O”就不能打角球才能赢。(在这个场景中玩一个角落会为"X“带来一个分叉。)

选项2:如果有一个配置,对手可以叉子,阻止该叉子。

5)中锋:发挥中锋。

( 6)相对角球:如果对手在角球,则打对方角球。

( 7)空旷角落:玩空角落。

( 8)空的一面:发挥空的一面。

我遵循了这些步骤,电脑从来没有输过。然而,它的攻击方式并不完美。因为我不知道如何做第三步。下面是我在步骤3中所做的工作:扫描每个单元格,检查该单元格上的put标记是否创建了一个分叉,然后将其放在那里。

代码语言:javascript
复制
private void step3() // Create Fork.
{
    int[] dummyField = (int[])field.Clone();
    // Try Level 1 Dummy
    for (int i = 0; i < 9; i++)
    {
        if (dummyField[i] != 0) continue;
        dummyField[i] = 2;
        if (countFork(dummyField, 2) >= 2)
        {
            nextCell = i;
            return;
        }
        dummyField[i] = 0;
    }

}

请给我一些关于这一步的建议。

EDIT1:计数叉将计算计算机有多少叉(计算机的令牌为2,player令牌为1,因为我在步骤4中也使用了该方法,因此countFork函数中有一个令牌参数)。

EDIT2:我说它不完美的原因是这个(CPU首先,它的细胞是蓝色的,人类细胞是红色的)。

如你所见,如果我把顶部的单元格放进去,电脑就赢了。但如果我把右边的格放进去,那就是平局,尽管电脑还是能赢的。

EDIT3:不知道为什么,但是我把第三步评论掉了,电脑播放.完美!我真的很惊讶!这里是我的countFork函数(我需要将这段代码移植到Alice,它不支持二维数组,所以我使用getNumberFromXY将二维数组转换为一维数组):

代码语言:javascript
复制
private int countFork(int[] field, int token)
{
    int result = 0;

    // Vertical
    int cpuTokenCount;
    int spareCell;
    for (int x = 0; x < 3; x++)
    {
        cpuTokenCount = 0;
        spareCell = -1;
        for (int y = 0; y < 3; y++)
        {
            if (field[getNumberFromXY(x, y)] == token)
                cpuTokenCount++;
            else if (field[getNumberFromXY(x, y)] == 0)
                spareCell = getNumberFromXY(x, y);
        }
        if (cpuTokenCount == 2 && spareCell != -1) result++;
    }

    // Horizontal
    for (int y = 0; y < 3; y++)
    {
        cpuTokenCount = 0;
        spareCell = -1;
        for (int x = 0; x < 3; x++)
        {
            if (field[getNumberFromXY(x, y)] == token)
                cpuTokenCount++;
            else if (field[getNumberFromXY(x, y)] == 0)
                spareCell = getNumberFromXY(x, y);
        }
        if (cpuTokenCount == 2 && spareCell != -1) result++;
    }

    // Top-Left To Lower-Right Diagonal
    cpuTokenCount = 0;
    spareCell = -1;
    for (int i = 0; i < 3; i++)
    {
        if (field[getNumberFromXY(i, i)] == token)
            cpuTokenCount++;
        else if (field[getNumberFromXY(i, i)] == 0)
            spareCell = getNumberFromXY(i, i);
    }
    if (cpuTokenCount == 2 && spareCell != -1) result++;

    // Top-Right To Lower-Left Diagonal
    cpuTokenCount = 0;
    spareCell = -1;
    for (int i = 0; i < 3; i++)
    {
        if (field[getNumberFromXY(2 - i, i)] == token)
            cpuTokenCount++;
        else if (field[getNumberFromXY(2 - i, i)] == 0)
            spareCell = getNumberFromXY(2 - i, i);
    }
    if (cpuTokenCount == 2 && spareCell != -1) result++;

    return result;
}

EDIT4:根据soandos修复了错误,并在编辑3更新了代码,现在它运行得很好!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-11-28 05:05:10

我不确定这是否是最优雅的方式,但这里有两个步骤的方式来看待叉子。

如果计算机无法赢得下一轮,而且它不是第一轮或第二轮,则可能会出现分叉(这并不涉及创建分叉的设置,只需找到一个分叉)。

对于每个空单元格,填充它,然后运行步骤1函数(如果一行中有两个)。如果它找到两个地方,恭喜,你有叉子。如果不是,你就不会。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8287084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档