Minimax Connect 4 AI 麻烦
Minimax Connect 4 AI trouble
我正在制作 connect 4 AI,但游戏会一直持续到所有 42 个空格都填满。
分数保持每4个连续得1分。
public int[] Max_Value(GameBoard playBoard, int depth){
GameBoard temp = new GameBoard(playBoard.playBoard);
int h = 0, tempH = 999, tempCol=0;
int myDepth = depth - 1;
int[] tempH2 = new int[2];
boolean noChildren = true;
if(myDepth != -1){
for(int i = 0; i < 7; i++){
if(temp.isValidPlay(i)){
count++;
temp.playPiece(i);
noChildren = false;
tempH2 = Min_Value(temp, myDepth);
if(tempH2[1] < tempH){
tempH=tempH2[1];
tempCol = i;
}
temp.removePiece(i);
}
}
}
int[] x = new int[2];
if(noChildren){
h = temp.getHeuristic();
}
else{
h = tempH;
x[0]=tempCol;
}
x[1]=h;
return x;
}
public int[] Min_Value(GameBoard playBoard, int depth){
GameBoard temp = new GameBoard(playBoard.playBoard);
int h = 0, tempH = -999, tempCol=0;
int myDepth = depth - 1;
int[] tempH2 = new int[2];
boolean noChildren = true;
if(myDepth != -1){
for(int i = 0; i < 7; i++){
if(temp.isValidPlay(i)){
count++;
temp.playPiece(i);
noChildren = false;
tempH2 = Max_Value(temp, myDepth);
if(tempH2[1] > tempH){
tempH=tempH2[1];
tempCol = i;
}
temp.removePiece(i);
}
}
}
int[] x = new int[2];
if(noChildren){
h = temp.getHeuristic();
}
else{
h = tempH;
x[0]=tempCol;
}
x[1]=h;
return x;
}
我觉得我只是偶然发现了所有东西,而且感觉代码很糟糕。但是,我以前从未尝试过这样的事情,非常感谢任何意见。我不知道我哪里出错了。对于任何给定状态,我的评估函数只为它可以找到的连续 4 个中的每一个给出 1 分。主函数调用 Min_Value 函数以深度 10 开始。
我正在尝试 return 列以及启发式的值。我希望我已经提供了足够的信息。感谢您的任何见解。
尽管问题中没有说明,但我认为您没有从搜索中得到好的结果,对吗?
无需查看您的 while 代码,我已经可以说您的程序仅在游戏的最后 10 步(最后 10 个空白区域或 10 个强制获胜)期间有效。否则,您的程序将 return 它评估的最后一步或第一步。那是因为你的评估函数,你只处理一次胜利(分别连续 4 次),而不是连续 2 次、陷阱、连续 3 次,等等)。如果它不能强制获胜,它将认为所有动作都是平等的。
这是一个问题,因为从空场开始,只有先手玩家才能获胜,而且只有倒数第二个棋子被放在棋盘上。 (在你的版本中连续强制4)。
并且由于您的搜索深度 (10) 小于最大游戏步数 (42),您的程序将始终执行第一个动作。
如果你的算法的其余部分正确实施,你可以通过简单地改进你的评估函数来解决这个问题,这样它就可以在 "good" 和 "bad" 游戏位置之间有所不同。
好吧,在实施未显示的方法(如评估、游戏移动、删除等)后,我能够对其进行调试。假设这些函数在您的版本中以某种正确的方式实现,错误是如果深度为 -1:
,您实际上从未调用评估函数
你有这个:
[...]if(myDepth != -1)
{/*restofthecode*/}[...]
但是你需要的是这样的:
[...]if(myDepth == -1)
{
return temp.getHeuristic();
}
/*restofthecode*/
[...]
这样,每当您达到深度 -1(极小极大树中的一片叶子)时,将评估棋盘并返回值(这正是您在极小极大中所需要的)。
在两个部分(最小值和最大值)都进行此修改,一切都应该没问题。如果还有其他问题,欢迎追问。
我正在制作 connect 4 AI,但游戏会一直持续到所有 42 个空格都填满。
分数保持每4个连续得1分。
public int[] Max_Value(GameBoard playBoard, int depth){
GameBoard temp = new GameBoard(playBoard.playBoard);
int h = 0, tempH = 999, tempCol=0;
int myDepth = depth - 1;
int[] tempH2 = new int[2];
boolean noChildren = true;
if(myDepth != -1){
for(int i = 0; i < 7; i++){
if(temp.isValidPlay(i)){
count++;
temp.playPiece(i);
noChildren = false;
tempH2 = Min_Value(temp, myDepth);
if(tempH2[1] < tempH){
tempH=tempH2[1];
tempCol = i;
}
temp.removePiece(i);
}
}
}
int[] x = new int[2];
if(noChildren){
h = temp.getHeuristic();
}
else{
h = tempH;
x[0]=tempCol;
}
x[1]=h;
return x;
}
public int[] Min_Value(GameBoard playBoard, int depth){
GameBoard temp = new GameBoard(playBoard.playBoard);
int h = 0, tempH = -999, tempCol=0;
int myDepth = depth - 1;
int[] tempH2 = new int[2];
boolean noChildren = true;
if(myDepth != -1){
for(int i = 0; i < 7; i++){
if(temp.isValidPlay(i)){
count++;
temp.playPiece(i);
noChildren = false;
tempH2 = Max_Value(temp, myDepth);
if(tempH2[1] > tempH){
tempH=tempH2[1];
tempCol = i;
}
temp.removePiece(i);
}
}
}
int[] x = new int[2];
if(noChildren){
h = temp.getHeuristic();
}
else{
h = tempH;
x[0]=tempCol;
}
x[1]=h;
return x;
}
我觉得我只是偶然发现了所有东西,而且感觉代码很糟糕。但是,我以前从未尝试过这样的事情,非常感谢任何意见。我不知道我哪里出错了。对于任何给定状态,我的评估函数只为它可以找到的连续 4 个中的每一个给出 1 分。主函数调用 Min_Value 函数以深度 10 开始。
我正在尝试 return 列以及启发式的值。我希望我已经提供了足够的信息。感谢您的任何见解。
尽管问题中没有说明,但我认为您没有从搜索中得到好的结果,对吗?
无需查看您的 while 代码,我已经可以说您的程序仅在游戏的最后 10 步(最后 10 个空白区域或 10 个强制获胜)期间有效。否则,您的程序将 return 它评估的最后一步或第一步。那是因为你的评估函数,你只处理一次胜利(分别连续 4 次),而不是连续 2 次、陷阱、连续 3 次,等等)。如果它不能强制获胜,它将认为所有动作都是平等的。
这是一个问题,因为从空场开始,只有先手玩家才能获胜,而且只有倒数第二个棋子被放在棋盘上。 (在你的版本中连续强制4)。
并且由于您的搜索深度 (10) 小于最大游戏步数 (42),您的程序将始终执行第一个动作。
如果你的算法的其余部分正确实施,你可以通过简单地改进你的评估函数来解决这个问题,这样它就可以在 "good" 和 "bad" 游戏位置之间有所不同。
好吧,在实施未显示的方法(如评估、游戏移动、删除等)后,我能够对其进行调试。假设这些函数在您的版本中以某种正确的方式实现,错误是如果深度为 -1:
,您实际上从未调用评估函数你有这个:
[...]if(myDepth != -1)
{/*restofthecode*/}[...]
但是你需要的是这样的:
[...]if(myDepth == -1)
{
return temp.getHeuristic();
}
/*restofthecode*/
[...]
这样,每当您达到深度 -1(极小极大树中的一片叶子)时,将评估棋盘并返回值(这正是您在极小极大中所需要的)。
在两个部分(最小值和最大值)都进行此修改,一切都应该没问题。如果还有其他问题,欢迎追问。