为什么我的Connect 4程序中出现NullPointerException?

时间:2019-05-05 20:31:12

标签: java eclipse oop

有人可以解释为什么在尝试在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;

}
}

2 个答案:

答案 0 :(得分:1)

将数组移动并将计数器初始化播放到static块中。这样可以确保在调用任何方法之前先the board is initialized

static {
    gameBoard = new int[heightOfBoard][widthOfBoard];
    totalPlayed=0;
}

答案 1 :(得分:1)

首先介绍一些基本的Java编程技巧:

  • 每个变量名称,引用均应 lowerCamelCase Connect4 -> connect4
  • connect4是Board对象的实例,并且 totalPlayed gameBoard ...字段是 Board 特定的,因此它们不应该是静态的

现在,由于问题,您的班级 Board 扩展了抽象类 Counter Counter 类具有以下字段: totalPlayed gameBoard widthOfBoard heightOfBoard 。并且抽象类中的所有方法都引用它们。

您的班级 Board 具有所有这些字段的副本,可通过调用super.totalPlayed等来访问。您不应在您的 Board < / em>类。这就是为什么您的错误发生。抽象类中的 gameBoard 字段为空,但是在您的Board类中,您初始化了一个不同的gameBoard,并且从不设置抽象类使用的那个游戏