2014-10-05 87 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尚未初始化。