Greg
Greg

Reputation: 33

Programming a chess game in Java, and gameOver boolean not working

I'm trying to make a chess game in Java that can be played on the console. For each move, the game asks the player for a piece, (for example 12 for the piece in the second row, third column) and a final location (for example 32 for the fourth row, third column). Everything is working perfectly, including tests to see if the move is illegal and if a given player is in check, but my gameOver boolean seems to be changing the value of my board array before the first move is asked for.

Here is the relevant code. From my main method:

public static void main(String[] args) {
    int[][] board = {   {12, 13, 14, 15, 16, 14, 13, 12},
                        {11, 11, 11, 11, 11, 11, 11, 11},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {0,  0,  0,  0,  0,  0,  0,  0},
                        {21, 21, 21, 21, 21, 21, 21, 21},
                        {22, 23, 24, 25, 26, 24, 23, 22}
                    };
    Scanner scan = new Scanner(System.in);
    boolean oneTurn = true;
    while(!(gameOver(oneTurn, board))) {
        printBoard(board);
        System.out.println(((oneTurn) ? "1's" : "2's") +  " turn");
        System.out.print("What piece? ");
        int origin = scan.nextInt();

The gameOver boolean, which tests to see if there are any moves the current player can make that are legal and won't put the player in check:

public static boolean gameOver(boolean oneTurn, int[][] board) {
    for (int a = 0; a<8; a++) {
        for(int b = 0; b<8; b++) {
            for (int c = 0; c<8; c++) {
                for(int d = 0; d<8; d++) {
                    if(board[a][b] / 10 == (oneTurn ? 1 : 2) && !(illegal(oneTurn, 10*a+b, 10*c+d, board)) && !(illegalCheck(oneTurn, 10*a+b, 10*c+d, board))) return false;
                }
            }
        }
    }
    return true;
}

The check method, which tries to find a legal move the other player can do that will eliminate the king:

public static boolean check(boolean oneTurn, int[][] board) {
    int king = kingNum(oneTurn, board);
    for (int a = 0; a<8; a++) {
        for(int b = 0; b<8; b++) {
            if(board[a][b] / 10 == (oneTurn ? 2 : 1) && !(illegal(!oneTurn, 10*a+b, king, board))) return true;
        }
    }
    return false;
}

The illegalCheck method, which tests to see if a move will put the player in check. I think this is where the problem lies. I tried to make a separate newBoard so that the original board wouldn't change, but it still creates the problem.

public static boolean illegalCheck(boolean oneTurn, int origin, int dest, int[][] board) {
    int[][] newBoard = board;
    newBoard[dest / 10][dest % 10] = board[origin / 10][origin % 10];
    newBoard[origin / 10][origin % 10] = 0;
    if(check(oneTurn, newBoard)) return true;
    else return false;
}

When I run the program for the first time, the first output I get is this:

    |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |
_____________________________________________

0   | 1R |    | 1B | 1Q | 1K | 1B | 1N | 1R |
_____________________________________________

1   | 1P | 1P | 1P | 1P | 1P | 1P | 1P | 1P |
_____________________________________________

2   |    |    |    |    |    |    |    |    |
_____________________________________________

3   |    |    |    |    |    |    |    |    |
_____________________________________________

4   |    |    |    |    |    |    |    |    |
_____________________________________________

5   |    |    |    |    |    |    |    |    |
_____________________________________________

6   | 2P | 2P | 2P | 2P | 2P | 2P | 2P | 2P |
_____________________________________________

7   | 2R | 2N | 2B | 2Q | 2K | 2B | 2N | 2R |
_____________________________________________

1's turn
What piece? 

The first legal move found by gameOver is the knight moving, so I think that's why the knight isn't showing up on the first board. When I put the printBoard method before the boolean test, the board prints perfectly.

I just began learning to program recently, so I would appreciate any advice about why this would be happening. It could be something blatantly obvious that I'm missing. Let me know if there are other details I can provide. Thank you!

Upvotes: 3

Views: 1539

Answers (3)

Jeffrey Bosboom
Jeffrey Bosboom

Reputation: 13653

When you write

int[][] newBoard = board;
newBoard[dest / 10][dest % 10] = board[origin / 10][origin % 10];
newBoard[origin / 10][origin % 10] = 0;

you're creating newBoard as a new reference to the same array object as board, and then proceeding to modify the array. You can copy it instead like this:

int[][] newBoard = new int[8][];
for (int i = 0; i < newBoard.length; ++i)
    newBoard[i] = board[i].clone();

Java's multidimensional arrays are arrays of references to other arrays (because arrays are objects), so first we create a new top-level array, then assign copies of the subsidiary arrays into it. (There are a bunch of rules about Object.clone() and Cloneable, but all you have to know here is that cloning an array makes a new array with the same values. For multidimensional arrays this is a shallow copy (the copy refers to the same subsidiary arrays), so we can't just call board.clone() and be done with it.)

Upvotes: 1

emerino
emerino

Reputation: 1120

I would recommend using a debugger and setting some breakpoints so you can see what exactly is going on, that way you won't be guessing.

More info on debugging sessions with java: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jdb.html

Upvotes: 0

emsworth
emsworth

Reputation: 1171

If you believe it is due to the copy of the array, try System.arraycopy in illegalCheck.

Upvotes: 1

Related Questions