我正在为我的大学项目创建一个TicTacToe游戏,当我完成计算机人工智能的代码时,我最终得到了一大块代码。
它允许计算机做出获胜的移动,阻止玩家获胜,如果计算机不能做出任何获胜的移动或阻止玩家获胜,则可以随意移动。我所拥有的代码包含一系列if和else if语句。
我想知道是否有可能以任何方式减少这种数量的代码。我尝试将其中一个if语句放入一个方法中,然后多次调用该方法,但由于else语句没有运行,这是不起作用的。
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:
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;
}发布于 2014-03-17 20:30:20
是的,你真的需要使用循环和概括这一点!
为了让你学到最多的东西,我不会给出任何精确的代码,但是我会告诉你你需要做什么
for (int x = 0; x < 3; x++)是遍历所有x's (列)的简单方法。index / 3或index % 3计算按钮的行和列(%是‘模’-运算符)。这就是为什么应该使用基于零索引的数组的原因之一。这样计算起来就容易多了。enum用于UNPLAYED、X和O。使用适当的enum可以极大地帮助清理代码。公共枚举PlayedBy { UNPLAYED,X,O;}你经常重复这个部分
buttons[x].setText("O");
buttons[x].setEnabled(false);这是一种应该应用于一种方法的东西:
void setButtonPlayer(JButton position, String player) {
position.setText(player);
position.setEnabled(false);
}现在,您只需使用setButtonPlayer(buttons[4], "O");对按钮4进行移动。如果您使用枚举,您可以使用setButtonPlayer(JButton button, PlayedBy player)。
一旦你稍微清理了一下,我建议你发布一个后续问题,因为那时可能有更多的事情可以清理。
发布于 2014-03-17 20:22:04
当遇到这样的问题时,它有助于实现责任链模式。在这种情况下,您有一个层次结构,包括获胜的移动、防守的移动和随机的移动。
您应该按照以下方式创建一个接口:
public interface TicTacToeStrategy {
public boolean apply(Button[] buttons);
}那么,您应该有许多这种策略的实现..。
类似于:
public ForTheWinStrategy implements TicTacToeStrategy {
public boolean apply(Button[] buttons) {
if (.... there is a winning move) {
apply the winning move
return true;
}
return false;
}
}然后您可以拥有DefensiveStrategy和RandomStrategy。
private static final TicTacToeStrategy[] STRATEGIES = {
new ForTheWinStrategy(),
new DefensiveStrategy(),
new RandomStrategy()
};然后,您的主要代码可以变成:
for(TicTacToeStrategy strategy : STRATEGIES) {
if (strategy.apply(buttons)) {
break;
}
}至于所有的if声明..。你得想办法让他们合理化。
将它们提取到一个函数中是很好的,或者设置一个三行的集合.
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}
}通过上述设置,您可以相对轻松地说:
for (int[] tiaw : THREEINAROW) {
if (2 are us, and one is empty) {
we have a winner!
}
} 发布于 2014-03-18 02:21:34
你基本上都是硬编码的。它不建议硬编码的一切为人工智能。如果你在写更复杂的东西呢?然后,你可能会得到一个案例,你的人工智能完全失败。这就是为什么我认为你应该开发自己的算法或者实现其他人的算法。
对于您的问题,我建议您实现minimax算法,它基本上是递归地检查所有可能的选项来完成游戏。这是伪码:
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。
https://codereview.stackexchange.com/questions/44608
复制相似问题