0

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?

rahul sharma
  • 321
  • 1
  • 7

2 Answers2

2

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.

candied_orange
  • 102,279
  • 24
  • 197
  • 315
  • if i understand you statement correctly, then board[x][y] will give piece and generateMoves is implemented by all pieced?Am i correct? – rahul sharma Jan 08 '21 at 22:13
  • @rahulsharma yep. I go into that more in the link. Won a chess tournament with this method. – candied_orange Jan 08 '21 at 22:14
  • yeah it also makes sense, piece should know board configuration for movement.thanks.just in case you want to know, i got this from the design from https://cutt.ly/9jlhtCD. In comment section,i had a long discussion with author:) – rahul sharma Jan 08 '21 at 22:17
  • 1
    It’s certainly not the only way. But it’s the best OO way to do chess that I know. – candied_orange Jan 08 '21 at 22:19
  • @candied_orange, I find your approach very curious. It adduces a variety of "pieces", and piece exchanges, that don't actually exist in the game of chess as we know it, and dispenses with things that do exist in chess, like the move history (which is either kept formally as a list, or at least stored in memory by the player, not embedded into a set of alternative pieces, including also notions such as piece "tails", and "empty" pieces). If we were playing the game of Just a Minute, I'd have challenged you on *deviating from the English language as we know it*! – Steve Jan 09 '21 at 00:16
  • @Steve keep move history in a hashset and it’s easier to detect if you’re about to offer a draw. – candied_orange Jan 09 '21 at 00:19
  • @candied_orange, certainly I wouldn't challenge your technical implementation. I merely observe that the conceptual model expressed in the source code, seems to differ substantially from either the physical or the conceptual objects involved in any real game of chess. The most obvious manifestation of which, is that your model employs more so-called *pieces* than would be legal in a real game of chess, and it involves touchings and exchanges that would not be legal in a real game of chess (at least if they were applied to the game board itself, and not to separate equipment). (1/2) – Steve Jan 09 '21 at 00:46
  • @Steve in the real game of chess you express a second queen by turning a rook upside down. Please understand that I’m talking about the model. Not stuff the user sees. – candied_orange Jan 09 '21 at 00:53
  • I think it would be fairer to describe your model as that of a *chess calculator* - a form of novel ancillary equipment used to calculate chess moves - rather than as a model of the standard equipment of a chess game. (2/2) – Steve Jan 09 '21 at 00:53
  • @Steve if models aren’t different from the real thing they aren’t models. They’re the real thing. – candied_orange Jan 09 '21 at 00:56
  • @candied_orange, definitely. That's what I'm saying, that you're describing a model for a *chess calculator*, not a model of a chess game, by which I mean something that attempts (by the analogies which are drawn between physical objects and OO objects) to stay faithful to the familiar ordinary equipment of a chess game. – Steve Jan 09 '21 at 01:05
  • The reason I think this is interesting, and important, is because it shows that many of the objects you employ, cannot be straightforwardly inferred from looking at the real game or equipment. It's a genuine result of creativity. And nor does your calculator closely reflect, in its intermediary workings, the overt workings of a real chess game. This is different from how OO was once taught, that you should simply model what you see, and model what those things do - nobody doing that, would conceive of a "null piece" , for example, because no such piece exists or can be placed on a real board. – Steve Jan 09 '21 at 01:16
  • @Steve yes in those days inheritance was though of as the same thing as polymorphism. Turns out it’s just one way to do it. Chess used to be a game whose state was something you could see at a glance. Then they changed the rules. – candied_orange Jan 09 '21 at 01:19
  • @Steve so if I want to remember that a pawn can move two places rather than just one by making it a different class (rather than asking where it is) I think that’s ok even if that would look strange if done in real life. – candied_orange Jan 09 '21 at 01:37
  • @candied_orange, indeed. In a real game, it is the players who store such information in their mental model, separately from the physical state of the board. In your calculator, such information is embedded into the diverse pieces actually placed on the board, and such pieces are thus touched and exchanged in ways that would be illegal in a real game. It's interesting to consider why this is more efficient, because each piece is an indirection to a specialised method that calculates valid moves, rather than having to analyse the piece and find the relevant method each time! – Steve Jan 09 '21 at 02:26
  • 1
    @Steve it's really a simple idea: store as much game state in the board as I can. This way what's at a square controls behavior. It can't enforce every history sensitive rule but castling, opening pawn moves, and en passant can be modeled this way. And it's a lot faster than grinding through the old board positions. – candied_orange Jan 09 '21 at 16:30
1

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.

Steve
  • 6,998
  • 1
  • 14
  • 24
  • but piece should be able to tell the moves,right?So it should be responsibility of individual piece to tell valid moves.Thats what i think – rahul sharma Jan 08 '21 at 22:34
  • Why do you think that? – user253751 Jan 08 '21 at 22:52
  • @rahulsharma, when did the piece last tell you what moves it could make? It's the application of the *rule book* to the *board* which tells you the valid moves, and ultimately it is the *players* that decide. Even if the piece can nominally be asked for valid moves which involve only itself, it must still logically defer to the rule book and the board as a whole to get the actual answer - and castling involves *two* pieces being moved as an atomic operation within one turn. – Steve Jan 09 '21 at 00:00
  • okay i did not consider castling thing and I assume in one turn only one piece will be involved.player can make a move and then we can validate is one things, we telling player that only these moves are possible is another and the above design follows the later.The rule book has rules for each piece, and that is that each piece is capturing – rahul sharma Jan 09 '21 at 09:08