Java - манипулирование двумерным массивом влияет на обратный индекс - PullRequest
0 голосов
/ 27 мая 2018

Я пытаюсь изучать Java, применяя свои знания и создавая шахматную игру на Java.На данный момент это строго текст.В моей программе есть функция, которая позволяет мне перемещать фигуру.Все фигуры хранятся в 2D массиве, называемом Board.Проблема, однако, заключается в этой функции, когда я пытаюсь переместить кусок.Если по какой-то причине я перемещаю фигуру («Ладья») с board[7][0] до board[6][0], противоположное этому (board[0][0] до board[1][0]) также перемещается.

Вот доска без каких-либо модификаций, показанная с displayBoard():

ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 
PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK,

Доска после перемещения фигуры:

null, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 
ROOK, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
ROOK, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
null, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 

Только нижняя левая ладья должнаЯ был перемещен.Класс Board.Java:

public class Board {
    public Pieces[][] board = new Pieces[8][8];

    private Pieces[] MainLine = new Pieces[]{Pieces.ROOK, Pieces.KNIGHT, Pieces.BISHOP, Pieces.QUEEN, Pieces.KING, Pieces.BISHOP, Pieces.KNIGHT, Pieces.ROOK};
    private Pieces[] BishopLine = new Pieces[]{Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN};

    public Board(){
        resetBoard();
    }

    private void resetBoard() {
        board = new Pieces[8][8];
        board[0] = MainLine;
        board[board.length - 1] = MainLine;
        board[1] = BishopLine;
        board[board.length - 2] = BishopLine;
    }

    public void displayBoard() {
        for(int rank = 0; rank < board.length; rank++) {
            System.out.println("");
            for(int file = 0; file < board.length; file ++) {
                System.out.print(board[rank][file] + ", ");
            }
        }
        for(int x = 0; x < 3; x++) {
            System.out.println("");
        }
    }

    public Pieces getPiece(int rank, int file) {
        return board[rank][file];
    }

    public void movePiece(int rank, int file, int newRank, int newFile) {
        Pieces temp = getPiece(rank, file);
        board[rank][file] = null;
        board[newRank][newFile] = temp;
    }
}

В моем Основном классе я создаю новый экземпляр доски, отображаю его, перемещаю фигуру movePiece(7, 0, 6, 0) и затем снова отображаю доску.Я полагаю, что основная проблема связана с классом Board.java, и я понятия не имею, что не так или почему это влияет на другие индексы.Может ли кто-нибудь объяснить мне, почему это происходит, или как лучше манипулировать массивом 2D board для дальнейшего достижения моей цели - переместить фигуру в заданную позицию, не затрагивая другие фигуры.

РЕДАКТИРОВАТЬ: Добавлен дополнительный запрашиваемый код -

Main.Java создает экземпляр игры, где в будущем возникнут другие условия, однако это Game.java, который содержит прямую ссылку на Board.Java, поскольку он наследуется от него:

public class Main {
    public static void main(String[] args) {
        Game game = new Game();

        game.displayBoard();
        game.movePiece(7, 0, 6, 0);
        game.displayBoard();

    }
}

Game.java просто вызывает super, который создает доску.Позже он будет содержать дополнительную функциональность:

public class Game extends Board {
    public Game() {
        super();
    }

}

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Проблема заключается в функции resetBoard ().Здесь вы используете одну и ту же ссылку на объект для шахматных фигур обоих игроков.Таким образом, поскольку java передается по значению, то board [7] [0] и board [0] [0] ссылаются на один и тот же объект, и когда одно изменение так же, как и другое.

Для простоты вы можете попробовать что-то вроде ниже

Или создать конструктор копирования в классе частей и вызвать из метода resetBoard

Или переопределить метод clone () в классе частей, чтобы сделатьглубокая копия объекта, чтобы две ссылки не указывали на общий объект.

или используйте Arrays.copyOf (arrayToCopy, length) для создания новой копии.

 private void resetBoard() {
    board = new Pieces[8][8];
    board[0] = new Pieces[]{Pieces.ROOK, Pieces.KNIGHT, Pieces.BISHOP, Pieces.QUEEN, Pieces.KING, Pieces.BISHOP, Pieces.KNIGHT, Pieces.ROOK};
    board[board.length - 1] = new Pieces[]{Pieces.ROOK, Pieces.KNIGHT, Pieces.BISHOP, Pieces.QUEEN, Pieces.KING, Pieces.BISHOP, Pieces.KNIGHT, Pieces.ROOK};
    board[1] = new Pieces[]{Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN};;
    board[board.length - 2] = new Pieces[]{Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN, Pieces.PAWN};;
}
0 голосов
/ 27 мая 2018

Проблема в конструкторе для Board, точнее, метода resetBoard(), вы инициализируете первую строку в том же массиве, что и последняя строка, и аналогично, вторая строка ссылается на тот же массив, что и вторая.до последней строки:

private void resetBoard() {
    board = new Pieces[8][8];

    // board[0] is a reference to MainLine so if we change move
    // into or out of board[0] MainLine will be affected and 
    // we won't be able to start with a fresh board by calling boardReset()
    // board[0] = MainLine;

    // Initialize the first row to a fresh array every time we call
    // reset.
    board[0] = new Pieces[] { 
        Pieces.ROOK, Pieces.KNIGHT, Pieces.BISHOP, Pieces.QUEEN, 
        Pieces.KING, Pieces.BISHOP, Pieces.KNIGHT, Pieces.ROOK
    };

    // This makes the last line and
    // the first line point to the same array
    // You need to create a new array that is a deep copy
    // of the array.
    // board[board.length - 1] = MainLine; 

    // Create new array by copying the original array
    board[board.length - 1] = Arrays.copyOf(board[0], board[0].length);

    // Similarly
    //board[1] = BishopLine;
    Arrays.fill(board[1], Pieces.PAWN);
    board[board.length - 2] = Arrays.copyOf(board[1], board[1].length);

    // You don't need member variables MainLine and BishopLine
    // and you can remove them if you want.
}

Теперь обе строки указывают на разные массивы.Когда вы звоните movePiece(7, 0, 6, 0) Вы должны увидеть

ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 
PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 



ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 
PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
null, null, null, null, null, null, null, null, 
ROOK, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, 
null, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK, 
...