2014-10-05 3 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

Пожалуйста, сообщите нам точный номер строки, где произошла ошибка. –

+0

Вы не представляете, как сильно это заставляет меня видеть 's + =' для строки в цикле или те последние статические ints вместо enum. –

+1

Возможный дубликат [Как избежать «локальная переменная, возможно, не была инициализирована»?] (Http://stackoverflow.com/questions/1585513/how-to-avoid-the-local-variable-may-not-have -been-initialized) – Joe

ответ

0

Изменить эту строку:

Move oppMove;   // Opponent's best reply 

в

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

Это вызовет NPE, когда ни «squareContains» (строка, start_column) && column == start_column', ни «squareContains» (start_row, column) && row == start_row' не верны. –

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

Sweet! Это исправило эту проблему. Есть и другие вещи, но это не нарушает его. –

0

Он ожидает, что вы его инициализации. Вы можете инициализировать его до null, если у вас нет начальных значений. Подобно;

Move oppMove = null; 
+0

Это вызовет NPE в случае, если ни «squareContains» (строка, start_column) && column == start_column', ни «squareContains» (start_row, column) && row == start_row' не верны. –

+0

Вы абсолютно прав, я дал простое решение, чтобы избежать ошибки компиляции. Тестирование должно производиться им. – quartaela

0

Поскольку oppMove инициализируется только тогда, когда уверен, «если» условия соблюдены, то компилятор предупреждает вас об этом неинициализированного значения.

Initializing в нуль должен решить эту проблему, хотя вы должны убедиться, что оленья кожа бросить NPE для случаев, когда он по-прежнему остается назначен null

+0

Что произойдет, когда инструкция * next * if 'side == COMPUTER && oppMove.value check' запускается тогда? (который также, вероятно, имеет ошибку в нем) –

1

Чтобы объяснить, почему эта ошибка происходит немного больше здесь ваш код:

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 все еще не инициализирована.

Смежные вопросы