首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Tic Tac脚趾计算机AI

Tic Tac脚趾计算机AI
EN

Code Review用户
提问于 2014-03-17 20:07:45
回答 5查看 12.9K关注 0票数 22

我正在为我的大学项目创建一个TicTacToe游戏,当我完成计算机人工智能的代码时,我最终得到了一大块代码。

它允许计算机做出获胜的移动,阻止玩家获胜,如果计算机不能做出任何获胜的移动或阻止玩家获胜,则可以随意移动。我所拥有的代码包含一系列ifelse if语句。

我想知道是否有可能以任何方式减少这种数量的代码。我尝试将其中一个if语句放入一个方法中,然后多次调用该方法,但由于else语句没有运行,这是不起作用的。

代码语言:javascript
复制
public void AI(){
        count++;
        if(buttons[1].getText().equals("O") && buttons[2].getText().equals("O") && buttons[3].getText().equals("")){
            buttons[3].setText("O");
            buttons[3].setEnabled(false);
        } else if(buttons[4].getText().equals("O") && buttons[5].getText().equals("O") && buttons[6].getText().equals("")){
            buttons[6].setText("O");
            buttons[6].setEnabled(false);
        } else if(buttons[7].getText().equals("O") && buttons[8].getText().equals("O") && buttons[9].getText().equals("")){
            buttons[9].setText("O");
            buttons[9].setEnabled(false);                
        } 

        else if(buttons[2].getText().equals("O") && buttons[3].getText().equals("O") && buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        } else if(buttons[5].getText().equals("O") && buttons[6].getText().equals("O") && buttons[4].getText().equals("")){
            buttons[4].setText("O");
            buttons[4].setEnabled(false);                
        } else if(buttons[8].getText().equals("O") && buttons[9].getText().equals("O") && buttons[7].getText().equals("")){
            buttons[7].setText("O");
            buttons[7].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("O") && buttons[3].getText().equals("O") && buttons[2].getText().equals("")){
            buttons[2].setText("O");
            buttons[2].setEnabled(false);                
        } else if(buttons[4].getText().equals("O") && buttons[6].getText().equals("O") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        } else if(buttons[7].getText().equals("O") && buttons[9].getText().equals("O") && buttons[8].getText().equals("")){
            buttons[8].setText("O");
            buttons[8].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("O") && buttons[4].getText().equals("O") && buttons[7].getText().equals("")){
            buttons[7].setText("O");
            buttons[7].setEnabled(false);                
        } else if(buttons[2].getText().equals("O") && buttons[5].getText().equals("O") && buttons[8].getText().equals("")){
            buttons[4].setText("O");
            buttons[4].setEnabled(false);                
        } else if(buttons[3].getText().equals("O") && buttons[6].getText().equals("O") && buttons[9].getText().equals("")){
            buttons[9].setText("O");
            buttons[9].setEnabled(false);                
        }

        else if(buttons[4].getText().equals("O") && buttons[7].getText().equals("O") && buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        } else if(buttons[5].getText().equals("O") && buttons[8].getText().equals("O") && buttons[2].getText().equals("")){
            buttons[2].setText("O");
            buttons[2].setEnabled(false);                
        } else if(buttons[6].getText().equals("O") && buttons[9].getText().equals("O") && buttons[3].getText().equals("")){
            buttons[3].setText("O");
            buttons[3].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("O") && buttons[7].getText().equals("O") && buttons[4].getText().equals("")){
            buttons[4].setText("O");
            buttons[4].setEnabled(false);                
        } else if(buttons[2].getText().equals("O") && buttons[8].getText().equals("O") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        } else if(buttons[3].getText().equals("O") && buttons[9].getText().equals("O") && buttons[6].getText().equals("")){
            buttons[6].setText("O");
            buttons[6].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("O") && buttons[5].getText().equals("O") && buttons[9].getText().equals("")){
            buttons[9].setText("O");
            buttons[9].setEnabled(false);                
        } else if(buttons[5].getText().equals("O") && buttons[9].getText().equals("O") && buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        } else if(buttons[1].getText().equals("O") && buttons[9].getText().equals("O") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        }

        else if(buttons[3].getText().equals("O") && buttons[5].getText().equals("O") && buttons[7].getText().equals("")){
            buttons[7].setText("O");
            buttons[7].setEnabled(false);                
        } else if(buttons[7].getText().equals("O") && buttons[5].getText().equals("O") && buttons[3].getText().equals("")){
            buttons[3].setText("O");
            buttons[3].setEnabled(false);                
        } else if(buttons[7].getText().equals("O") && buttons[3].getText().equals("O") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("X") && buttons[2].getText().equals("X") && buttons[3].getText().equals("")){
            buttons[3].setText("O");
            buttons[3].setEnabled(false);
        } else if(buttons[4].getText().equals("X") && buttons[5].getText().equals("X") && buttons[6].getText().equals("")){
            buttons[6].setText("O");
            buttons[6].setEnabled(false);                
        } else if(buttons[7].getText().equals("X") && buttons[8].getText().equals("X") && buttons[9].getText().equals("")){
            buttons[9].setText("O");
            buttons[9].setEnabled(false);                
        } 

        else if(buttons[2].getText().equals("X") && buttons[3].getText().equals("X") && buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        } else if(buttons[5].getText().equals("X") && buttons[6].getText().equals("X") && buttons[4].getText().equals("")){
            buttons[4].setText("O");
            buttons[4].setEnabled(false);                
        } else if(buttons[8].getText().equals("X") && buttons[9].getText().equals("X") && buttons[7].getText().equals("")){
            buttons[7].setText("O");
            buttons[7].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("X") && buttons[3].getText().equals("X") && buttons[2].getText().equals("")){
            buttons[2].setText("O");
            buttons[2].setEnabled(false);                
        } else if(buttons[4].getText().equals("X") && buttons[6].getText().equals("X") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        } else if(buttons[7].getText().equals("X") && buttons[9].getText().equals("X") && buttons[8].getText().equals("")){
            buttons[8].setText("O");
            buttons[8].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("X") && buttons[4].getText().equals("X") && buttons[7].getText().equals("")){
            buttons[7].setText("O");
            buttons[7].setEnabled(false);                
        } else if(buttons[2].getText().equals("X") && buttons[5].getText().equals("X") && buttons[8].getText().equals("")){
            buttons[8].setText("O");
            buttons[8].setEnabled(false);                
        } else if(buttons[3].getText().equals("X") && buttons[6].getText().equals("X") && buttons[9].getText().equals("")){
            buttons[9].setText("O");
            buttons[9].setEnabled(false);                
        }

        else if(buttons[4].getText().equals("X") && buttons[7].getText().equals("X") && buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        } else if(buttons[5].getText().equals("X") && buttons[8].getText().equals("X") && buttons[2].getText().equals("")){
            buttons[2].setText("O");
            buttons[2].setEnabled(false);                
        } else if(buttons[6].getText().equals("X") && buttons[9].getText().equals("X") && buttons[3].getText().equals("")){
            buttons[3].setText("O");
            buttons[3].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("X") && buttons[7].getText().equals("X") && buttons[4].getText().equals("")){
            buttons[4].setText("O");
            buttons[4].setEnabled(false);                
        } else if(buttons[2].getText().equals("X") && buttons[8].getText().equals("X") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        } else if(buttons[3].getText().equals("X") && buttons[9].getText().equals("X") && buttons[6].getText().equals("")){
            buttons[6].setText("O");
            buttons[6].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("X") && buttons[5].getText().equals("X") && buttons[9].getText().equals("")){
            buttons[9].setText("O");
            buttons[9].setEnabled(false);                
        } else if(buttons[5].getText().equals("X") && buttons[9].getText().equals("X") && buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        } else if(buttons[1].getText().equals("X") && buttons[9].getText().equals("X") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        }

        else if(buttons[3].getText().equals("X") && buttons[5].getText().equals("X") && buttons[7].getText().equals("")){
            buttons[7].setText("O");
            buttons[7].setEnabled(false);                
        } else if(buttons[7].getText().equals("X") && buttons[5].getText().equals("X") && buttons[3].getText().equals("")){
            buttons[3].setText("O");
            buttons[3].setEnabled(false);                
        } else if(buttons[7].getText().equals("X") && buttons[3].getText().equals("X") && buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("X") && buttons[5].getText().equals("O") && buttons[9].getText().equals("X")) {
            buttons[6].setText("O");
            buttons[6].setEnabled(false);            
        }    

        else if(buttons[3].getText().equals("X") && buttons[5].getText().equals("O") && buttons[7].getText().equals("X")) {
            buttons[4].setText("O");
            buttons[4].setEnabled(false);            
        }

        else if(buttons[5].getText().equals("")){
            buttons[5].setText("O");
            buttons[5].setEnabled(false);                
        }

        else if(buttons[1].getText().equals("")){
            buttons[1].setText("O");
            buttons[1].setEnabled(false);                
        }
        else {
            if(count >= 9)
                checkWin();
            else
                RandomMove();
        }

        checkWin();

    }

编辑:if声明,我已经检查了所有不同的可能性,计算机可以作出一个胜利的移动或阻止球员获胜。

编辑3:

代码语言:javascript
复制
for(int i=0; i<=3; i++){
    if (buttons[i*3].getText().equals("X") && buttons[i*3+1].getText().equals("X") && buttons[i*3+2].getText().equals(""))
        buttons[i*3+2].setText("O");
        win = true;
    }
EN

回答 5

Code Review用户

发布于 2014-03-17 20:30:20

是的,你真的需要使用循环和概括这一点!

为了让你学到最多的东西,我不会给出任何精确的代码,但是我会告诉你你需要做什么

  • 您的数组似乎是基于索引1-9的,我建议使用0到8。数组索引总是从零开始,只是看起来你没有使用它。相反,使用它。
  • 使用for-循环遍历游戏板的行、列和对角线.3行,3列,2对角。for (int x = 0; x < 3; x++)是遍历所有x's (列)的简单方法。
  • 提示:可以使用index / 3index % 3计算按钮的行和列(%是‘模’-运算符)。这就是为什么应该使用基于零索引的数组的原因之一。这样计算起来就容易多了。
  • 您可能需要将enum用于UNPLAYEDXO。使用适当的enum可以极大地帮助清理代码。公共枚举PlayedBy { UNPLAYED,X,O;}
  • 脱钩。这是一个更先进的,没有什么你应该关注的主要。但在未来,它会对你有很大帮助。现在,您的AI知道关于您的视图的一切(view =用户看到的对象)。如果你想让两个人工智能互相竞争,并且只输出到控制台,那该怎么办?如果你想用这个做一个Android应用呢?如果您想要使用GWT创建一个Web应用程序呢?(将来你可能会想要这个!)您应该查看MVC模式和/或使用接口!去解耦你的代码。

你经常重复这个部分

代码语言:javascript
复制
buttons[x].setText("O");
buttons[x].setEnabled(false);

这是一种应该应用于一种方法的东西:

代码语言:javascript
复制
void setButtonPlayer(JButton position, String player) {
    position.setText(player);
    position.setEnabled(false);
}

现在,您只需使用setButtonPlayer(buttons[4], "O");对按钮4进行移动。如果您使用枚举,您可以使用setButtonPlayer(JButton button, PlayedBy player)

一旦你稍微清理了一下,我建议你发布一个后续问题,因为那时可能有更多的事情可以清理。

票数 15
EN

Code Review用户

发布于 2014-03-17 20:22:04

当遇到这样的问题时,它有助于实现责任链模式。在这种情况下,您有一个层次结构,包括获胜的移动、防守的移动和随机的移动。

您应该按照以下方式创建一个接口:

代码语言:javascript
复制
public interface TicTacToeStrategy {
    public boolean apply(Button[] buttons);
}

那么,您应该有许多这种策略的实现..。

类似于:

代码语言:javascript
复制
public ForTheWinStrategy implements TicTacToeStrategy {
    public boolean apply(Button[] buttons) {
        if (.... there is a winning move) {
            apply the winning move
            return true;
        }
        return false;
    }
}

然后您可以拥有DefensiveStrategyRandomStrategy

代码语言:javascript
复制
 private static final TicTacToeStrategy[] STRATEGIES = {
     new ForTheWinStrategy(),
     new DefensiveStrategy(),
     new RandomStrategy()
 };

然后,您的主要代码可以变成:

代码语言:javascript
复制
for(TicTacToeStrategy strategy : STRATEGIES) {
    if (strategy.apply(buttons)) {
        break;
    }
}

至于所有的if声明..。你得想办法让他们合理化。

将它们提取到一个函数中是很好的,或者设置一个三行的集合.

代码语言:javascript
复制
private static final int[][] THREEINAROW = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
    {1, 4, 7},
    {2, 5, 8},
    {3, 5, 9},
    {1, 5, 9},
    {3, 5, 7}
}

通过上述设置,您可以相对轻松地说:

代码语言:javascript
复制
for (int[] tiaw : THREEINAROW) {
    if (2 are us, and one is empty) {
        we have a winner!
    }
} 
票数 13
EN

Code Review用户

发布于 2014-03-18 02:21:34

你基本上都是硬编码的。它不建议硬编码的一切为人工智能。如果你在写更复杂的东西呢?然后,你可能会得到一个案例,你的人工智能完全失败。这就是为什么我认为你应该开发自己的算法或者实现其他人的算法。

对于您的问题,我建议您实现minimax算法,它基本上是递归地检查所有可能的选项来完成游戏。这是伪码:

代码语言:javascript
复制
function minimax(node, depth, maximizingPlayer)
    if depth = 0 or node is a terminal node
        return the heuristic value of node
    if maximizingPlayer
        bestValue := -∞
        for each child of node
            val := minimax(child, depth - 1, FALSE))
            bestValue := max(bestValue, val);
        return bestValue
    else
        bestValue := +∞
        for each child of node
            val := minimax(child, depth - 1, TRUE))
            bestValue := min(bestValue, val);
        return bestValue

(* Initial call for maximizing player *)
minimax(origin, depth, TRUE)

来源:http://en.wikipedia.org/wiki/Minimax

另外,另一个为抽搐tic toe实现minimax的源是:http://www.codeproject.com/Articles/43622/Solve-Tic-Tac-Toe-with-the-MiniMax-algorithm

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

https://codereview.stackexchange.com/questions/44608

复制
相关文章

相似问题

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