有人可以解释为什么在尝试在Connect Four板上放置一个计数器时会出现NullPointerException错误:
Exception in thread "main" java.lang.NullPointerException
at Counter.canMakeMove(Counter.java:26)
at Main.main(Main.java:31)
我知道程序尝试引用具有空值的对象时会发生NullPointerException错误,但是我无法理解它从何处派生此空值?
我正在尝试为面向对象的代码编写代码,因此,不胜感激今后的任何评论/提示!
Main.java
import java.io.InputStreamReader;
import java.util.Random;
import java.io.BufferedReader;
import java.io.IOException;
public class Main {
public static void main(String args[])throws IOException{
Board Connect4 = new Board();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Welcome to Connect 4");
System.out.println("There are 2 players red and yellow");
System.out.println("Player 1 is Red, Player 2 is Yellow");
System.out.println("To play the game type in the number of the boardColumn you want to drop you counter in");
System.out.println("A player wins by connecting 4 counters in a row - vertically, horizontally or diagonally");
System.out.println("");
Connect4.printBoard();
outer:
while(true){
int boardColumn = 0;
//Player One Logic ----------------------------------------------------------------
while(true){
System.out.println("");
System.out.println("Player 1, please select your column:");
boardColumn = Integer.parseInt(br.readLine());
if(Connect4.canMakeMove(boardColumn)){
if(Connect4.placeCounter(boardColumn, 1)){
Connect4.printBoard();
System.out.println("");
System.out.println("Congratulations! Player 1 has won the game");
break outer;
}
break;
}
else
System.out.println("Column "+boardColumn+" is already full!!");
}
Connect4.printBoard();
//Player Two Logic ---------------------------------------------------------------
while(true){
System.out.println("");
System.out.println("The Computer has selected a column and played a counter");
System.out.println("");
Random r = new Random();
int num = r.nextInt(7);
boardColumn = num;
if(Connect4.canMakeMove(boardColumn)){
if(Connect4.placeCounter(boardColumn, 2)){
Connect4.printBoard();
System.out.println("");
System.out.println("Unlucky! The Computer has won this game");
break outer;
}
break;
}
else
System.out.println("Column "+boardColumn+" is already full!!");
}
Connect4.printBoard();
if(Connect4.gameDrawn()){
System.out.print("The game has ended in a draw. Please start the game again.");
break;
}
}
}
Board.java
public class Board extends Counter {
static int totalPlayed;
static int[][] gameBoard;
static int widthOfBoard=7;
static int heightOfBoard=7;
public static int [][] getBoard() {
return gameBoard;
}
public static int getWidth() {
return widthOfBoard;
}
public static int getHeight() {
return heightOfBoard;
}
public static int getTotal() {
return totalPlayed;
}
public Board(){
gameBoard = new int[heightOfBoard][widthOfBoard];
totalPlayed=0;
}
public void printBoard(){
for(int i=0;i<gameBoard.length;i++){
for(int j=0;j<gameBoard[0].length;j++){
if(gameBoard[i][j] == 0)
System.out.print(". ");
else
System.out.print(gameBoard[i][j]+" ");
}
System.out.println("");
}
System.out.println("--------------------");
System.out.println("0 1 2 3 4 5 6");
}
}
Counter.Java
public abstract class Counter {
int widthOfBoard = Board.getWidth();
int [][] gameBoard = Board.getBoard();
int heightOfBoard = Board.getHeight();
int totalPlayed = Board.getTotal();
public boolean placeCounter(int boardColumn, int playerNum){
int i=0;
for(i=0;i<widthOfBoard;i++){
if(gameBoard[i][boardColumn] == 1 || gameBoard[i][boardColumn] == 2){
gameBoard[i-1][boardColumn]=playerNum;
break;
}
}
if(i == widthOfBoard)
gameBoard[i-1][boardColumn]=playerNum;
totalPlayed++;
return isConnected(i-1,boardColumn);
}
public boolean canMakeMove(int boardColumn){
return gameBoard[0][boardColumn] == 0;
}
public boolean gameDrawn(){
return totalPlayed == widthOfBoard * heightOfBoard;
}
public boolean isHorizontal(int x, int y) {
int count = 0;
int i=y;
int num=gameBoard[x][y];
//HORIZONTAL.
while(i<widthOfBoard && gameBoard[x][i] == num){
count++;
i++;
}
i=y-1;
while(i>=0 && gameBoard[x][i] == num){
count++;
i--;
}
if(count == 4)
return true;
return false;
}
public boolean isVertical(int x, int y) {
//VERTICAL.
int count=0;
int j=x;
int num=gameBoard[x][y];
while(j<widthOfBoard && gameBoard[j][y] == num){
count++;
j++;
}
if(count == 4)
return true;
return false;
}
public boolean isRightDiagonal(int x, int y) {
//SECONDARY DIAGONAL.
int count=0;
int i=x;
int j=y;
int num=gameBoard[x][y];
while(i<widthOfBoard && j<widthOfBoard && gameBoard[i][j] == num){
count++;
i++;
j++;
}
if(count == 4)
return true;
return false;
}
public boolean isLeftDiagonal(int x, int y) {
//LEADING DIAGONAL.
int count=0;
int i = x;
int j=y;
int num=gameBoard[x][y];
while(i<widthOfBoard && j>=0 && gameBoard[i][j] == num){
count++;
i++;
j--;
}
if(count == 4)
return true;
return false;
}
public boolean isConnected(int x, int y){
isHorizontal(x, y);
isVertical(x, y);
isRightDiagonal(x, y);
isLeftDiagonal(x, y);
return false;
}
}
答案 0 :(得分:1)
将数组移动并将计数器初始化播放到static
块中。这样可以确保在调用任何方法之前先the board is initialized:
static {
gameBoard = new int[heightOfBoard][widthOfBoard];
totalPlayed=0;
}
答案 1 :(得分:1)
首先介绍一些基本的Java编程技巧:
现在,由于问题,您的班级 Board 扩展了抽象类 Counter 。 Counter 类具有以下字段: totalPlayed , gameBoard , widthOfBoard 和 heightOfBoard 。并且抽象类中的所有方法都引用它们。
您的班级 Board 具有所有这些字段的副本,可通过调用super.totalPlayed
等来访问。您不应在您的 Board < / em>类。这就是为什么您的错误发生。抽象类中的 gameBoard 字段为空,但是在您的Board类中,您初始化了一个不同的gameBoard,并且从不设置抽象类使用的那个游戏。