当前位置: 首页 > 知识库问答 >
问题:

需要帮助调试connect four minimax代码的alpha-beta修剪

阴永福
2023-03-14

我正在使用minimax算法为connect four编写AI。为了增加深度,我正在使用alpha-beta修剪。然而,我的代码得到了错误的结果。我很难找出哪里出了问题。

    /**
  * Makes a turn. Edit this method to make your bot smarter.
  *
  * @return The column where the turn was made.
  */
 public double[] makeTurn(int[][] board, int id, int depth, double alpha, double beta) {
     //Round is the turn number. For the first couple of turns, I just place the disc in the center.
     double empty = 3;
     if(round == 1){
         double[] def = {3, 0};
         return def;
     }

     else if (round <4){

         if(board[4][3]==0){
             empty = 3;
         }
         else if(board[5][4]==0){
             empty = 4;
         }
         else{
             empty =2;
         }

         double[] def = {empty, 0};
         return def;
     }

     if(field.isFull(board)){

         //If the board is full return 0 - no one has an advantage
         double[] def = {0, 0};
         return def;
     }


     //System.out.println(field.toString());

     //best column for maximizing player
     double maxCol = 0;

     //best column for minimizing player
     double minCol = 0;

     //variables to store my score and opponents score in the current state
     double myScore = 0;
     double opponentScore = 0;

     for(int i = 0; i < 7;i++){

         //if column is full ignore it
         if(field.isColumnFull(i, board)){
             //System.out.println("is full");
         }
         else{

             //System.out.println(this.mCols + " " + this.mRows);
             int[][] tempBoard =  new int[this.mRows][this.mCols];
             for(int j = 0; j < mRows; j++){
                 tempBoard[j] = Arrays.copyOf(board[j], mCols);

             }

             //add disc to current column
             this.addDisc(i, id, tempBoard);


             /*If the depth is 0, we are at a leaf,
              * and we just run the heuristic function and
              * return the results.
              */
             if(depth == 0){
                 //System.out.println("here");

                 /*run the heuristic function twice,
                  * once for each player
                  */
                 myScore = getScore(tempBoard, this.myId);
                 opponentScore = getScore(tempBoard, this.opponentId);

                 //System.out.println(myScore + " " + opponentScore);
                 //System.out.println(myScore + " " + opponentScore);

                 /*If the game has ended,
                  * return the scores
                  */
                 if(id == this.myId && myScore ==Integer.MAX_VALUE){
                     myScore = Integer.MAX_VALUE/(maxDepth-depth+1);
                 }
                 else if(opponentScore == Integer.MIN_VALUE && id==this.opponentId){
                     myScore = Integer.MIN_VALUE/(maxDepth+1-depth);
                 }

                 /*If there is no winner in the current state
                  * the difference between the two players score
                  * is the score of the state
                  */
                 else{
                     myScore = (myScore - opponentScore);
                 }

                 //System.out.println(myScore + " " + i);
                 //System.out.println(myScore + " " + opponentScore);

             }

             /*If it is not a leaf node, check if the game has ended,
              * otherwise run a recursive call by decreasing the depth
              */
             else{
                 //System.out.println(depth);
                 if(id==this.myId){
                     if(getScore(tempBoard, this.myId)==Integer.MAX_VALUE){

                         double[] temp = {i, Integer.MAX_VALUE/(maxDepth+1-depth)};
                         //System.out.println(depth + " " + temp[1] + " " +i);
                         return temp;
                     }
                 }

                 else{
                     if(getScore(tempBoard, this.opponentId)==Integer.MIN_VALUE){
                         double[] temp = {i, Integer.MIN_VALUE/(maxDepth+1-depth)};
                         //System.out.println(depth + " " + temp[1] + " " +i);
                         return temp;
                     }
                 }


                 //the score and the respective column is returned
                 double[] res = makeTurn(tempBoard, id%2+1, depth-1, alpha , beta);
                 myScore = res[1];
             }

             if(depth==maxDepth){
                //System.out.println(myScore + " " +  maxCol +" " + i);
                 if(myScore>0){
                     //printBoard(tempBoard);
                 }
             }

             Random r = new Random();
             int prob = r.nextInt(10);


             /*If it is the maximizing players turn
              * update alpha
              */
             if (myScore > alpha && this.myId == id){
                 alpha = myScore;
                 maxCol = i;
             }
             else if(myScore == alpha && maxCol<4 && this.myId == id){
                 if(prob>4){
                     maxCol = i;

                 }
             }

             /*
              * Otherwise update beta
              */
             if(myScore < beta && this.opponentId == id){
                beta = myScore;
                minCol = i;
             }
             else if(myScore == beta && minCol < 4 && this.opponentId == id){
                 if(prob>4){
                     minCol = i;
                 }
             }


             /*This is where the pruning should occur. 
              * Without this the minimax algorithm runs correctly, but there
              * is no pruning. When I add this line, i get improved performance but 
              * incorrect results
              * 
              */
             if (beta<=alpha){
                 break;
             }


         }


     }

     //System.out.println(endTime - startTime);
     //System.out.println("opp max " + opponentMaxScore);
     //System.out.println("my max " + maxScore);
     //System.out.println("max diff " + maxScoreDiff);



     /*
      * Return best value according to player
      */
     double[] ans = new double[2];

     if(id ==  this.myId){
         ans[0] = maxCol;
         ans[1] = alpha;
     }

     else{
         ans[0] = minCol;
         ans[1] = beta;
     }

     //ans[0]= maxCol;
     //ans[1] = myScore;
     return ans;
 }

共有1个答案

堵龙野
2023-03-14

我对alpha-beta的理解是,两个玩家都需要检查alpha和beta,并且返回值需要受到alpha和beta的限制。即:

if (this.myId == id && myscore >= beta){
  alpha = beta;
  break;
}
else if (myScore > alpha && this.myId == id){
  alpha = myScore;
  maxCol = i;
}
else ...

...

if(this.opponentId == id && myScore <= alpha){
  beta = alpha;
  break;
}
else if(this.opponentId == id && myScore < beta){
  beta = myScore;
  minCol = i;
}
else ...
 类似资料:
  • 我的程序中有一个有效的negamax算法。然而,我需要程序在时间内找到最佳移动。我做了一些研究,似乎用我的negamax算法进行迭代深化是最好的方法。现在,我启动搜索的函数如下所示: 我想我也应该重新排序之前的最佳移动到儿童列表的前面,但是,我在等待实现,直到我得到基本版本的工作。实际的阿尔法-贝塔函数是这样的: 当我尝试调试时,一切似乎都在按预期工作。然而,当我将迭代深化版本与常规的alphab

  • /**程序可以将十进制转换为二进制并报告是否使用了非法字符*程序不能将二进制转换为十进制*/import java.util.scanner; /***这个类包含一个完整的程序,只有一个main()方法,用于*将非负十进制整数(即以10为基数的整数)转换为*正二进制整数(即以2为基数的整数)。要*转换的值是从命令行读入的。*/public class BaseConversions2{public

  • 首先,如果我搞砸了我的描述,我是新手,基本上我在正确使用node上遇到了麻烦,我跟随了youtube教程,直到老师告诉我们重新运行我们的代码,当我尝试使用他做的代码时,我得到了这个错误。 我搜索了错误中提到的,但找不到文件夹,我认为它是问题的一部分。 我尝试了很多方法,例如使用,这导致了这个cmd日志; 我还尝试删除我的和,但没有结果。 任何帮助都是感激的,并提前表示感谢:) 编辑:这里是pack

  • 我不太明白我在做什么,我做错了什么。请帮我修改/完成我的代码。我应该用你选择的输入数据创建至少3个Student对象,以使用类的构造函数初始化Student对象的所有数据字段。声明ArrayList对象以保存学生对象。将学生对象添加到ArrayList对象。调用Student类的toString方法,使用ArrayList对象中的Student对象打印学生的全名,后跟出生日期和每个学生的地址。 如

  • 我有一个asp.net的mvc 4应用程序,我正在将其部署到Azure,它正在成功部署,但当我从Nuget(邮政0.8.2)添加一个包时,它破坏了我的部署。我需要帮助找出问题所在,以便我可以向项目报告问题。 当我使用该包部署应用程序时,服务器会不断循环: 上午10:10:39角色的实例0正在创建虚拟机 10: 上午11:12-角色Biosign的实例0正在启动虚拟机 上午10:12:50-角色生物