2014-10-05 68 views
0

我一直收到这个 "The Local variable oppMove may not have been initialized"错误,这似乎是唯一让我从真正的测试。我无法弄清楚它为什么不能初始化(至少在我的编程知识上)。“本地变量”名称“可能未被初始化”错误

麦克斯特类

import java.util.*; 

/* Encapsulates a position in a game of Maxit. It is assumed that (1) the 
* upper left hand corner is the initial pivot, (2) the first player adds 
* worths and tries to maximize the sum, and (3) the second player subtracts 
* worths and tries to minimize the sum. */ 
public class Maxit 
{ 
    //************************************************************************* 
    // Public Constants 
    //************************************************************************* 
    public static final int HUMAN = 1; 
    public static final int COMPUTER = 2; 
    public static final int EMPTY = 0; 

    public static final int HUMAN_WINS = 0; 
    public static final int DRAW = 1; 
    public static final int UNCLEAR = 2; 
    public static final int COMPUTER_WINS = 3; 

    //************************************************************************* 
    // Private Properties 
    //************************************************************************* 
    // int [r][c] board where r is the rows and c is the columns 
    private int [][] board; 

    //************************************************************************* 
    // Public Properties 
    //************************************************************************* 
    public int human_score = 0; 
    public int computer_score = 0; 
    public int current_column = 0; 
    public int current_row = 0; 
    public int current_turn = 0; 


    /* Construct a Maxit board with the specified worths, which are assumed to 
    * be in a square matrix. */ 
    public Maxit() 
    { 
    constructBoard(3); 
    } 

    public Maxit (int n) 
    { 
    constructBoard(n); 
    } 

    public Maxit(int [][] worths) 
    { 
    board = worths; 
    } 

    /* Return best move. */ 
    public Move bestMove() 
    { 
    int side = current_turn++; 
    if(current_turn > COMPUTER) 
     current_turn = HUMAN; 
    return chooseBestMove(side, current_row, current_column); 
    } 


    private Move chooseBestMove(int side, int starting_row, int starting_column) 
    { 
     // count++;    // For timing 
     int opp;    // The other side 
     Move oppMove;   // Opponent's best reply 
     int simpleEval;  // Result of an immediate evaluation 
     int bestRow = 0; 
     int bestColumn = 0; 
     int check; 

     if((simpleEval = positionValue()) != UNCLEAR) 
     { 
      return new Move(simpleEval); 
     } 

     if(side == COMPUTER) 
     { 
      opp = HUMAN; check = HUMAN_WINS; 
     } 
     else 
     { 
      opp = COMPUTER; check = COMPUTER_WINS; 
     } 

     for(int row = 0; row < board.length; row++) 
     { 
      for(int column = 0; column < board.length; column++) 
      { 
      if (squareContains(row, starting_column) && column == starting_column) 
      { 
       int n = board[row][starting_column]; 
       choose(row, current_column, EMPTY); 
       oppMove = chooseBestMove(opp , row, starting_column); 
       choose(row, starting_column, n); 
      } 
      else if (squareContains(starting_row, column) && row == starting_row) 
      { 
       int n = board[starting_row][column]; 
       choose(starting_row, column, EMPTY); 
       oppMove = chooseBestMove(opp , starting_row, column); 
       choose(starting_row, column, n); 
      } 

      if(side == COMPUTER && oppMove.value < check 
        || side == HUMAN && oppMove.value > check) 
      { 
       check = oppMove.value; 
       bestRow = row; bestColumn = column; current_row = row; current_column = column; 
      } 
      } 
     } 

     return new Move(check, bestRow, bestColumn); 
    } 


    //************************************************************************* 
    // Standard Accessors 
    //************************************************************************* 

    /** Return who has captured the row r, column c square. */ 
    public int getSquare(int r, int c) 
    { 
     return board[r][c]; 
    } 

    /* Return score. */ 
    public int getScore() 
    { 
     return human_score - computer_score; 
    } 

    /* */ 
    public boolean isTheEnd() 
    { 
    int row_count = 0; 
    int column_count = 0; 
    for (int i = 0; i < board.length; i++) 
    { 
     if(board[current_row][i] == EMPTY) 
     column_count++; 
     if(board[i][current_column] == EMPTY) 
     row_count++; 
    } 
    if(column_count == board.length && row_count == board.length) 
    {return true;} 
    else 
    {return false;} 
    } 

    /* */ 
    public int whoWins() 
    { 
    if (getScore() >= 1) 
     return HUMAN_WINS; 
    else if (getScore() <= -1) 
     return COMPUTER_WINS; 
    else 
     return DRAW; 
    } 

    /** Return string representation of the board. */ 
    public String toString() { 
     String s = ""; 
     for (int r = 0; r < board.length; r++) { 
      for (int c = 0; c < board.length; c++) { 
       s += squareContains(r, c) ? "" + board[r][c] : 
        "_"; 
      } 
      if (r < board.length) s += "\n"; 
     } 
     return s; 
    } 

    /* */ 
    public void constructBoard(int n) 
    { 
    board = new int[n][n]; 
    int stuff = 1; 
    for (int i = 0; i < n; i++) 
     for(int j = 0; j < n; j++) 
    { 
     board[i][j] = stuff++; 
    } 

    int columns = board[0].length; 
    ArrayList<Integer> arr = new ArrayList<Integer>(); 
    //System.out.println("TestA"); 

    for (int i = 0; i < board.length; i++) 
    { 
     for (int j = 0; j < columns; j++) 
     { 
     //System.out.println("Test" + (i + j + 1)); 
     arr.add(board[i][j]); 
     } 
    } 
    //System.out.println("TestB"); 
    Collections.shuffle(arr); 
    int count = 0; //needed to get the number back from arr. 
    for (int i = 0; i < board.length; i++) 
    { 
     for (int j = 0; j < columns; j++) 
     { 
     //System.out.println("Test" + (i + j + 1)); 
     board[i][j] = arr.get(count); 
     count += 1; 
     } 
    } 
    } 

    //************************************************************************* 
    // Standard Mutators 
    //************************************************************************* 
    /* Return true and play the specified move if it is legal; 
    * otherwise, return false. */ 
    public boolean tryMove(Move move) 
    { 
    if (move.row < 0 || move.row > board.length || move.column < 0 
      || move.column > board[0].length || !squareContains(move.row, 
                   move.column)) 
     if(move.row != current_row || move.column != current_column) {return false;} 

    if(current_turn == HUMAN) 
     human_score += board[move.row][move.column]; 
    else { computer_score += board[move.row][move.column]; } 

    board[move.row][move.column] = EMPTY; 
    return true; 
    } 

    /* */ 
    private int positionValue() 
    { 
    if (isTheEnd()) 
     return whoWins(); 
    else 
     return UNCLEAR; 
    } 

    /* */ 
    public void clearBoard() 
    { 
     constructBoard(board.length); 
    } 

    //************************************************************************* 
    // Private Methods 
    //************************************************************************* 
    private boolean squareContains(int row, int column) 
    { 
    return board[row][column] != EMPTY; 
    } 

    private void choose(int row, int column, int value) 
    { 
    board[ row ][ column ] = value; 
    } 
} 

移动类

/* Encapsulate a row, column, and value of a move. If only the 
* row and column are known, then the value is null. If only 
* the value is known (e.g., at the end of the game when no move 
* is possible), then row and column are -1. */ 
public final class Move 
{ 
    public int row; 
    public int column; 
    public Integer value; 

    public Move(int v) 
    { this(v, -1, -1); } 

    public Move(int r, int c) 
    { this(null, r, c); }  

    public Move(Move original) 
    { this(original.value, original.row, original.column); } 

    public Move(Integer v, int r, int c) 
    { value = v; row = r; column = c; } 

    public String toString() 
    { 
    return "(" + row + ", " + column + ", " + value + ")"; 
    } 

    public boolean equals(Object other) 
    { 
    if (other == null || !(other instanceof Move)) return false; 
    Move that = (Move)other; 
    if (row != that.row || column != that.column) return false; 
    if (value == null) return that.value == null; 
    return value.equals(that.value); 
    } 
} 

在此先感谢。

+2

请告诉我们发生错误的确切行号。 – 2014-10-05 03:53:41

+0

你不知道看到一个循环中的字符串s + ='或者那些最终的静态整数而不是枚举有多痛苦。的 – 2014-10-05 03:54:54

+1

可能重复[如何避免“局部变量可能尚未初始化”?](http://stackoverflow.com/questions/1585513/how-to-avoid-the-local-variable-may-not-have -been初始化) – Joe 2014-10-05 05:01:57

回答

0

改变这一行:

Move oppMove;   // Opponent's best reply 

Move oppMove = null;   // Opponent's best reply 
+0

这将导致一个NPE时既不'squareContains(行,starting_column)&&柱== starting_column'也不'squareContains(starting_row,列)&&行== starting_row'是真实的。 – 2014-10-05 03:57:09

1

变化

Move oppMove;   // Opponent's best reply 

Move oppMove = null;   // Opponent's best reply 

这会失败很快,因为您的代码似乎总是不会初始化oppMove,但无论如何您都可以访问它。您应该检查这不是null第一

side == COMPUTER && oppMove.value < check 

oppMove != null && side == COMPUTER && oppMove.value < check 
+0

甜!这解决了这个问题。还有其他的东西是错的,但现在并没有打破它。 – 2014-10-05 04:15:35

0

它希望你对它进行初始化。如果您没有任何初始值,您可以将其初始化为null。喜欢;

Move oppMove = null; 
+0

这将导致在的情况下的NPE既不'squareContains(行,starting_column)&&柱== starting_column'也不'squareContains(starting_row,列)&&行== starting_row'是真实的。 – 2014-10-05 03:55:41

+0

你是绝对正确的,我只给出了最简单的解决方案,以避免编译错误。应该由他进行测试。 – quartaela 2014-10-05 03:58:54

0

由于oppMove某些时候“如果”条件满足时,编译器警告你这个初始化值只初始化。

初始化为空应该可以解决这个问题,但你应该确保在那里仍然分配给null

+0

当side == COMPUTER && oppMove.value check'然后运行? (它也可能有一个bug) – 2014-10-05 03:56:26

1

的情况下犯规罚球NPE要解释为什么这个错误更这里发生的一点是你的代码:

int opp;    // The other side 
    Move oppMove;   // Opponent's best reply 
    int simpleEval;  // Result of an immediate evaluation 
    int bestRow = 0; 
    int bestColumn = 0; 
    int check; 

    if((simpleEval = positionValue()) != UNCLEAR) 
    { 
     return new Move(simpleEval); 
    } 

    if(side == COMPUTER) 
    { 
     opp = HUMAN; check = HUMAN_WINS; 
    } 
    else 
    { 
     opp = COMPUTER; check = COMPUTER_WINS; 
    } 

    for(int row = 0; row < board.length; row++) 
    { 
     for(int column = 0; column < board.length; column++) 
     { 
     if (squareContains(row, starting_column) && column == starting_column) 
     { 
      int n = board[row][starting_column]; 
      choose(row, current_column, EMPTY); 
      oppMove = chooseBestMove(opp , row, starting_column); 
      choose(row, starting_column, n); 
     } 
     else if (squareContains(starting_row, column) && row == starting_row) 
     { 
      int n = board[starting_row][column]; 
      choose(starting_row, column, EMPTY); 
      oppMove = chooseBestMove(opp , starting_row, column); 
      choose(starting_row, column, n); 
     } 

     if(side == COMPUTER && oppMove.value < check 
       || side == HUMAN && oppMove.value > check) 
     { 
      check = oppMove.value; 
      bestRow = row; bestColumn = column; current_row = row; current_column = column; 
     } 
     } 
    } 

正如您在上面看到的那样,Move oppMove行声明了该变量。如果在使用之前它在某个地方给出了价值,这将是很好的。这两个地方就可以收到价值:

if (squareContains(row, starting_column) && column == starting_column) 
     { 
      int n = board[row][starting_column]; 
      choose(row, current_column, EMPTY); 
      oppMove = chooseBestMove(opp , row, starting_column); 
      choose(row, starting_column, n); 
     } 

else if (squareContains(starting_row, column) && row == starting_row) 
     { 
      int n = board[starting_row][column]; 
      choose(starting_row, column, EMPTY); 
      oppMove = chooseBestMove(opp , starting_row, column); 
      choose(starting_row, column, n); 
     } 

由于这些条件并不涵盖所有可能路径的程序代码可以拿,你仍然不能使用这个变量然而。但是,

if(side == COMPUTER && oppMove.value < check 
       || side == HUMAN && oppMove.value > check) 

此条件将返回错误,因为变量oppMove尚未初始化。