Question

Recently I came across some article on Chess OOPS design.Following is some snippet from it:

public class Chess {

    ChessBoard chessBoard;
    Player[] player;
    Player currentPlayer;
    List<Move> movesList;
    GameStatus gameStatus;

    public boolean playerMove(CellPosition fromPosition, CellPositionb toPosition, Piece piece); 
    public boolean endGame();
    private void changeTurn();

}
public abstract class Piece {

    Color color;

    public boolean move(CellPosition fromPosition, CellPositionb toPosition);
    public List<CellPosition> possibleMoves(CellPosition fromPosition);
    public boolean validate(CellPosition fromPosition, CellPositionb toPosition);
}

public class Knight extends Piece {

    public boolean move(CellPosition fromPosition, CellPositionb toPosition);
    public List<CellPosition> possibleMoves(CellPosition fromPosition);
    public boolean validate(CellPosition fromPosition, CellPositionb toPosition);

}

I pretty much liked the way classes are constructed but there is something that is confusing me.Now the code here is self explanatory. As per the author, the way it is designed,the "possibleMoves" function in the Piece class will give the list of possible moves and these moves are shown to user and user can select one of the move,which makes sense to me.

Now my question is, let us say we get possible moves by calling possibleMoves function from Piece class. Now since while actually making a move, there is a possibility that a piece can cross another piece in its way, which is not allowed except knight. SO where will we check that?I questioned the designed and the author is saying it should be done in chess class or in some Rule Engine, but my suggestion is to pass Board as a parameter and let the piece decide it as it knows how it will move.Otherwise in chess class or in rule engine we have to put a logic for each piece to check if while making a move it does not cross any other piece and for that we need to replicate the logic of how piece move in Piece class and in Chess/Rule Engine class. What can be the correct way here?

Was it helpful?

Solution

Pass the board to the piece you want a move list from.

You’re correct that the board data needs to be where the moves are. But the board is mutable so it’s a poor choice to make into an objects state. So just pass it as a parameter to a method.

Speaking of immutable, pieces don’t need to know where they are. Let the board keep track of that. All the pieces need to know is what their moves are and what their color is.

Let the board be a 2D array of references to such pieces and talking to them will be a snap. Might seem weird until you introduce a null object piece that has blank as its color. Since it generates no moves you can generate your move list simply by looping the board and calling a line like this:

legalMoves.addAll( board[x][y].generateMoves(x, y, board, turn) );

This way it's polymorphic. You don't have to know what you're talking to. And your objects are immutable. All the stuff that changes gets passed in. Makes debugging a breeze and might even get optimized by the virtual machine.

If you're concerned with history you can use piece types to handle the stranger rules of chess. Kings become MovedKings when moved etc.

I'd go on but I've already talked about chess here a few times. If you're curious this link will get you started.

OTHER TIPS

Logically, a valid move is not something determined by an individual piece, but by the application of the rules to an overall board (consisting of the current placement of many pieces), and also (in the case of castling) by an analysis of previous moves.

You could dispense with the history, by keeping a separate account of castling rights, but this absence of history would also make reversals or review of the gameplay impossible.

The mistake here is to model the individual physical objects (as conventionally understood), as opposed to the conceptual/informational objects (i.e. the board arrangement, the arrangement history, the rule book, and the players who apply the rules, search for valid moves by various search strategies, and ultimately execute a move).

For a true to life representation, it would also be possible for a player to execute an invalid move, and place the burden on the opposing player to challenge it.

Licensed under: CC-BY-SA with attribution
scroll top