简体   繁体   中英

Need help figuring out Basic Chess movement logic

Sorry for wall of text, but currently stumped. I'm not asking to be "spoon feed" since I have the basic idea down for each piece, it's just I'm having a difficult time on how to finish determining my move logic. Allow me to further explain. I'll be posting my code as well for better reference.

I'm coding with a MVC structure. I have a Model which is a 2D array of BoardSquares. Which those BoardSquares keep track of it's location on the board, what piece is in it (if there is one), what color that piece is (if there is one), and if it's empty. Here's the code for it:

public class BoardSquare {
// Private information stored in each BoardSquare
private boolean isSquareEmpty;
private int row;
private int col;
private String space;
private String pColor;

// Constructor to make an empty space on the board
public BoardSquare(int row, int col) {
    space = "";
    pColor = "";
    this.row = row;
    this.col = col;
    SquareEmpty();
}

//Constructor to get the information of a space with a piece
public BoardSquare(BoardPiece piece, int row, int col) {
    this.space = piece.getModelName();
    this.pColor = Character.toString((piece.getModelName().charAt(0))); 
    this.row = row;
    this.col = col;
    SquareNotEmpty();
}

public String getpColor() {
    String temp = getPieceColor(pColor);
    return temp;
}

//A bunch of auto generated getters/setters...

    // Gets the correct color label for the piece
public String getPieceColor(String info){
    String temp;
    if(info.equalsIgnoreCase("b")){
        temp = "Black";
    }
    else {
        temp = "White";
    }
    return temp;
}

Currently all my Pieces extend an abstract BoardPiece class which has several abstract methods as well, but my piece knows of it's location on the board, it's name, it's color, and the 2D board array for the way I'm generating the valid moves.

I'm generating them by checking the spaces it can move to and seeing if they are empty and adding them to an ArrayList and comparing and seeing if that list contains the inputted destination.

However I'm having problems thinking of how to stop checking if say Black Rook was on the left side of the board and wanted to move all the way to the Right, but there was a Black Pawn to the right of the Rook preventing it from doing so. I'm trying to generically think of it to make my life easier and I can implement it in the other piece classes as well So here's the Rook's code:

public class Rook extends BoardPiece{
private String name = "Rook";
private String color;
private String modelName;

BoardSquare board[][];

// Both should remain 0 - 7
private int row;
private int col;

public Rook (String modelName, int row, int col, String color, BoardSquare[][] field) {
    this.modelName = modelName;
    this.row = row;
    this.col = col;
    this.color = color;
    this.board = field;
}

@Override
void move(BoardSquare target) {
    if(!getPossibleMove(board).contains(target)){
        //Sysout false move
    }

}

@Override
Collection<BoardSquare> getPossibleMove(BoardSquare[][] board) {
    ArrayList<BoardSquare> validMoves = new ArrayList<BoardSquare>();
    for(int i = 0; i < 8; i++){
        // Checks every column of the row that the piece is on
        if(moveValidator(board[row][i])){
            validMoves.add(board[row][i]);
        }
        // Checks every row of the column that the piece is on
        if(moveValidator(board[i][col])){
            validMoves.add(board[i][col]);
        }
    }
    return validMoves;
}

@Override
boolean moveValidator(BoardSquare space) {
    // Removes the current square the piece is on as a valid move
    if(space.getRow() == getRow() && space.getCol() == getCol()){
        return false;
    }
    //Checks if the space is not empty and the piece in the spot is the same color as the piece itself
    if(!space.isEmptySquare() && space.getpColor().equalsIgnoreCase(color)){
        return false;
    }
    return true;
}

Like I said any help or push toward the right direction would be appreciated. Sorry for the wall of text but trying to be as clear as I can so that whoever wants to help can fully understand and see my logic.

EDIT: Forgot to note that the Rook has Auto-generated Getters and Setters as well.

I would approach it the most brute-force and intuitive way possible: think of moving the rook one square at a time as it takes its turn and see if it collides with anything. That is, hop it across every square until it gets to the desired spot and check if it's a valid move at each square.

This is a fine approach because

  • it's easy to understand
  • it's not expensive until your chess board gets massively huge, so brute force isn't a problem.
  • it generalizes to all pieces: rooks have to "slide" to their destination, but knights can "jump" or "teleport" over other pieces to their new location, so don't need the intermediate hops.

This sounds close to your current implementation, but you need to stop tracing when you collide. That is, if there is a black pawn in the way, the columns after that pawn are no longer valid spaces, right? In other words, think of the move as an action that the rook takes instead of an independent state space of possible moves, since some spaces are legal moves except that the rook was previously blocked. You need to know where the rook is from and where it is going to determine valid moves, not just if the space is in the same row.

So, reading your code (thanks for posting the context, by the way, it's quite helpful) really all you need to do is not iterate on each square, but iterate moving through each square, and stop the iteration when you get blocked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM