我不断得到这个
"The Local variable oppMove may not have been initialized"
错误似乎是阻止我真正测试的唯一因素。我无法弄清楚它为什么不能初始化(至少我的编程知识)。
Maxit class
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);
}
}
答案 0 :(得分: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
答案 1 :(得分: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仍未初始化。
答案 2 :(得分:0)
更改此行:
Move oppMove; // Opponent's best reply
到
Move oppMove = null; // Opponent's best reply
答案 3 :(得分:0)
它希望您初始化它。如果您没有任何初始值,则可以将其初始化为null
。等;
Move oppMove = null;
答案 4 :(得分:0)
由于oppMove
仅在满足某些“if”条件时被初始化,因此编译器会警告您未初始化的值。
初始化为null应解决此问题,但您应该确保在仍然分配给null
的情况下不会抛出NPE