0

我正在尝试将 3x3 tic tac toe 算法转换为 5x5 tic tac toe 算法。我搜索了很多算法,但每次我修改代码时,计算机都会从第一行开始,然后从该行的每一列开始。

这是我在网上找到的代码

公共类井字游戏{

 /* the board */
 private int board[][];
 /* empty */
 public static final int EMPTY = 0;
 /* player one */
 public static final int ONE = 1;
 /* player two */
    public static final int TWO = 2;

 public TicTacToeAI() {
  board = new int[3][3];
 }

 /* get the board value for position (i,j) */
 public int getBoardValue(int i,int j) {
  if(i < 0 || i >= 3) return EMPTY;
  if(j < 0 || j >= 3) return EMPTY;
  return board[i][j];
    }

 /* set the board value for position (i,j) */
 public void setBoardValue(int i,int j,int token) {
  if(i < 0 || i >= 3) return;
  if(j < 0 || j >= 3) return;
  board[i][j] = token;
    }

 /* calculate the winning move for current token */
 public int []nextWinningMove(int token) {

  for(int i=0;i<3;i++)
   for(int j=0;j<3;j++)
    if(getBoardValue(i, j)==EMPTY) {
     board[i][j] = token;
     boolean win = isWin(token);
     board[i][j] = EMPTY;
     if(win) return new int[]{i,j};
    }

  return null;
    }

    public int inverse(int token) {
  return token==ONE ? TWO : ONE;
 }

    /* calculate the best move for current token */
    public int []nextMove(int token) {

        /* lucky position in the center of board*/
        if(getBoardValue(1, 1)==EMPTY) return new int[]{1,1};

        /* if we can move on the next turn */
        int winMove[] = nextWinningMove(token);
        if(winMove!=null) return winMove;

        /* choose the move that prevent enemy to win */
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                if(getBoardValue(i, j)==EMPTY)
                {
                    board[i][j] = token;
              boolean ok = nextWinningMove(inverse(token)) == null;
                    board[i][j] = EMPTY;
                    if(ok) return new int[]{i,j};
                }

        /* choose available move */
        for(int i=0;i<3;i++)
            for(int j=0;j<3;j++)
                if(getBoardValue(i, j)==EMPTY)
                    return new int[]{i,j};

        /* no move is available */
        return null;
    }

 /* determine if current token is win or not win */
 public boolean isWin(int token) {
      final int DI[]={-1,0,1,1};
      final int DJ[]={1,1,1,0};

      for(int i=0;i<3;i++)
           for(int j=0;j<3;j++) {

            /* we skip if the token in position(i,j) not equal current token */
            if(getBoardValue(i, j)!=token) continue;

                for(int k=0;k<4;k++) {
                     int ctr = 0;
                                 while(getBoardValue(i+DI[k]*ctr, j+DJ[k]*ctr)==token) ctr++;

                     if(ctr==3) return true;
            }
      }
      return false;
    }

}

这是我修改的代码:

 /* the board */
 private int board[][];
 /* empty */
 public static final int EMPTY = 0;
 /* player one */
 public static final int ONE = 1;
 /* player two */
    public static final int TWO = 2;

 public TicTacToeAI() {
  board = new int[5][5];
 }

 /* get the board value for position (i,j) */
 public int getBoardValue(int i,int j) {
  if(i < 0 || i >= 5) return EMPTY;
  if(j < 0 || j >= 5) return EMPTY;
  return board[i][j];
    }

 /* set the board value for position (i,j) */
 public void setBoardValue(int i,int j,int token) {
  if(i < 0 || i >= 5) return;
  if(j < 0 || j >= 5) return;
  board[i][j] = token;
    }

 /* calculate the winning move for current token */
 public int []nextWinningMove(int token) {

  for(int i=0;i<5;i++)
   for(int j=0;j<5;j++)
    if(getBoardValue(i, j)==EMPTY) {
     board[i][j] = token;
     boolean win = isWin(token);
     board[i][j] = EMPTY;
     if(win) return new int[]{j,i};
    }

  return null;
    }

    public int inverse(int token) {
  return token==ONE ? TWO : ONE;
 }

    /* calculate the best move for current token */
    public int []nextMove(int token) {

        /* lucky position in the center of board*/
        if(getBoardValue(2, 2)==EMPTY) return new int[]{2,2};

        /* if we can move on the next turn */
       int winMove[] = nextWinningMove(token);
        if(winMove!=null) return winMove;

        /* choose the move that prevent enemy to win */
        for(int i=0;i<5;i++)
            for(int j=0;j<5;j++)
                if(getBoardValue(i, j)==EMPTY)
                {
                    board[i][j] = token;
              boolean ok = nextWinningMove(inverse(token)) == null;
                    board[i][j] = EMPTY;
                    if(ok) return new int[]{i,j};
                }

        for(int i=1;i<4;i++)
            for(int j=1;j<4;j++)
                if(getBoardValue(i, j)==EMPTY)
                    return new int[]{i,j};
                /* choose available move */
                else{
                    for(i=0;i<5;i++)
                        for(j=0;j<5;j++)
                            if(getBoardValue(i, j)==EMPTY)
                                return new int[]{i,j};

                }
        /* no move is available */
        return null;
    }

 /* determine if current token is win or not win */
public boolean isWin(int token) {
      final int DI[]={-1,0,1,1,1,0};
      final int DJ[]={1,1,1,0,-1,0};

      for(int i=0;i<5;i++)
           for(int j=0;j<5;j++) {

            // we skip if the token in position(i,j) not equal current token 
            if(getBoardValue(i, j)!=token) continue;

                for(int k=0;k<5;k++) {
                     int ctr = 0;
                                 while(getBoardValue(i+DI[k]*ctr, j+DJ[k]*ctr)==token) ctr++;

                     if(ctr==4) return true;
            }
      }
      return false;
    } 

}

感谢帮助

4

1 回答 1

2

原始程序使用的策略仅适用于 3x3 井字棋——它不会超越自己的下一步行动,因此无法完成五步链。(如果它以某种方式连续获得四个,它可以完成一个链条,并且它会被对手阻挡一排,但它不能做任何更复杂的事情。)你需要设计一个新的策略来做到这一点工作。

于 2013-04-21T20:58:02.683 回答