Castling

Pages: 123
@L B I'd still go back to my original solution. As further through development having the enumerated value telling you the name of the piece holds some more uses (e.g determine a draw scenario, figuring out if in check/check mate, scoring, debugging)
@MiiNiPaa http://www.cplusplus.com/forum/lounge/103019/#msg554679
No, this is an anti-pattern.

@Lachlan Easton && @MiiNiPaa http://www.cplusplus.com/forum/lounge/103019/#msg554686
No, I keep track of how many moves a piece has made.

@Lachlan Easton
Yes, board layouts can be customized too.

@Zaita
No, this is an anti-pattern.
@LB
Will your solution work if we decide to add some piece which should not abide "no move" for itself (but not king) and can castle even if king in check?
Or another one which works like king in castling but both it and rook-type piece should not abite "no move" rule?

Zereo wrote:
1: The king/rook involved must not have been moved before. If it has made a move already it can't castle.
2: There must be no pieces between it and the rook.
3: You can not castle when you are in check.
1. I keep track of how many moves a piece has made. — check
2. Easy to check using canMove or something of rook — check
3. There should be some board state which holds this anyway. — check

So main problem is how tho check that both pieces are of type of king and rook without getting their type or checking stored starting positions of said pieces?
Am I got it right?

EDIT: Paradox: if we know that two pieces can castle we can be sure that one of them of type king and other of type rook, and we knows which one is each, so we do know their types, which we must avoid!

Edit2: Ask user "Are you sure that two selected pieces are rook and king and there no situation which prevents from castling?"
Last edited on
I guess it's time that I need to drop a hint. My solution uses the enrollment pattern.
Could you please provide a link describing it. It is unknown to me (maybe there is a different name?).
@L B That's a very narrow minded approach and implies your solution is the "one true solution". Very seldom is something that black and white. The fact that the "enrollment pattern" itself is not listed as a GOF pattern or a commonly used pattern itself would make it an anti-pattern.

The fact that you've implemented a pattern when something simple like using an enum/const would suffice is in itself also an anti-pattern (increased complexity).

Edit:
In object oriented programming, you should never have to know the type of an instance or cast to a specific type reference


I actually disagree with this statement in general. There is no harm in an object knowing what kind of object it is. This is especially helpful if you want to ensure high levels of validation when working with user input. Hell, even knowing the name of the type of the object is handy when generating nice usable error messages. (e.g "The movie scene can not accept a gif image").

Edit2: In fact, thinking about it I cannot even find the source of this statement. Or think of good rationale for imposing such a rule on OOD. It does not appear to be one of the core principles of OOD.
Last edited on
It was a hint, not a direct answer ;) I'll explain it anyway - I like to call it the enrollment pattern because that's what I intuitively think of it doing. I've also heard people call it the subscription pattern or he enlistment pattern. (Edit: it is the Mediator design pattern)

The point of this thread was to find a modular solution that works for various kinds of interactions between varying pieces. Castling is just one kind of interaction, in which kings and rooks take part.

In my solution, you have a base class for different kinds of Interactions. The Castling class extends that. Kinds and Rooks know about the castling class, and all classes know what board they're associated with.

Kings and Rooks 'enroll' or 'subscribe' to the Castling interaction when their individual conditions are met, and they 'unscubscribe' when their fulfillment conditions are no longer valid. They enroll to separate categories of the castling interaction, of course - we still can't be sure they're actually kings and rooks, since the modularity allows e.g. archers to be added into the mix, but we can tell the two parties apart.

Then the fun happens. When one member of each group is enrolled, and the overall interaction condition is met, it becomes a valid move.

Tada! Without any casting, type checking, or other cheating, we've implemented castling in a modular way in chess. I'm implementing it in ChessPlusPlus right now.
Last edited on
Zaita posted while I was typing. I just want to say I don't know why you're being so negative - all I'm going for is modular design, and you can't have that with "something simple like using an enum/const".

Also, I don't know the actual name of the pattern, that's just one name I have heard it called. I'm going through the list of software design patterns right now trying to see which one it is.

EDIT: It's the mediator design pattern. Please don't call it an anti-pattern just because I used a different name for it.
Last edited on
Looks like Observer pattern to me.
I was almost ready to suggest it, but decided that need of pieces to be aware of observer is not worth the cost.

EDIT: Yes, mediator describes it better
Last edited on
@LB I stand by my statement that your solution, while a pattern still adds a lot of complexity to the maintainability of your code base.

You never said the point was to find a modular solution. You asked for solutions.

As you know the full scope of the code base (because chess pieces don't change) I would've favoured the simplest approach from a maintainability point of view. And would've expected my developers too as well.

Patterns for Patterns sake is what this feels like.
I'll also add, while you solution solves 1 problem. My solution considers other applications as well, making the code much more reusable.

For example.
Mediator Pattern (which you have your own name for)
- Solves the castling problem

Simply using a const/enum
- Allows you to determine is castling is allowed based on piece location
- Allows you to identify the types of pieces that have put a player in check/checkmate
- Allows you to identify the King who maybe in check/checkmate
- Allows you to identify which pieces can be returned to board when pawn makes it to the end
- Allows you to log what pieces move where by type
- Allows you to create a replay system by using type
- Allows you to easily output debug/user messages with type
- Allows you to score the game based on type of pieces removed/moved etc
- Allows you to determine actions based on a piece moving in to a location (e.g pawn moving to end of board) without having either another mediator subscription or a method that is only over-ridden by 1 subclass.

My solution while "not a pattern" is not an anti-pattern, does not break OOD principles and considers more problems that may exist in the development of a chess game.
The goal of OOP is modularity.

I intended to state that modularity was required, but I've been dealing with so much of it right now that I kind of forgot. Sorry :p

Zaita wrote:
Patterns for Patterns sake is what this feels like.
A goal of the ChessPlusPlus project is modularity. So, yes - patterns for patterns' sake.
The goal of OOP is modularity.


The goal is OOP is to provide a consistent way to develop applications that would be understandable by a broad collection of individuals so that there is a higher chance of project success.

Modularity is achieved through encapsulation, it's not a goal of OOP.
Food for thought:
These patterns, virtual functions etc. are all extremely interesting; however valid moves have to be generated very fast. Btw, there are well known design patterns for that too.

For instance, the PERFT for FEN (both colours can castle on either side):
r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq -

5 ply (21/2 full moves) look ahead,

Nodes (one per terminal position): about 194 million
Moves (castling): about 5 million
http://chessprogramming.wikispaces.com/Perft+Results (Position 2)

After the (pruned) tree is generated, one can start search and evaluation for the best move.
Last edited on
@LB

Hi! I am myself a chess enthusiast (but a programming newbie).

From what I understand, you already have a Castling class. This class takes two entities as parameters, checks whether castling is possible between them and enrolls them if it is.

What I suggest is (from my limited knowledge of programming) at the start of the game, you have to define the conditions for castling and define the moves for castling as per the entities (whether archers or kings or whatever). For instance, in Fischer Random chess, the castling moves become quite different.

Also, just to remind you:
- castling is possible both on queen side and king side.
- the conditions for castling are slightly more restrictive than what were brought out earlier on this thread:
* Not only the king should not be in check, the final square of the king and the square that the king jumps should also not be in check.

Maybe the simple castling procedure outlined by FIDE rules could give you an idea about how to go about it:
- The king moves two squares in the direction of the respective rook.
- The respective rook occupies the square that the king jumps over.
Last edited on
@Zaita: boy you are a huge fan of posting while I am typing. I didn't see your post with the list.
Zaita wrote:
For example.
Mediator Pattern (which you have your own name for)
- Solves the castling problem

Simply using a const/enum
- Allows you to determine is castling is allowed based on piece location But this is part of my solution
- Allows you to identify the types of pieces that have put a player in check/checkmate I don't see what this is useful for
- Allows you to identify the King who maybe in check/checkmate Our existing code already solved this without the development in this thread
- Allows you to identify which pieces can be returned to board when pawn makes it to the end Except you don't "return" pieces, you add pieces limitlessly. Our design already allows for this.
- Allows you to log what pieces move where by type Our design already does this without the developments in this thread.
- Allows you to create a replay system by using type Our design can already do this if needed.
- Allows you to easily output debug/user messages with type Our design already does this, and this is a duplicate point
- Allows you to score the game based on type of pieces removed/moved etc Our design already allows for this if needed
- Allows you to determine actions based on a piece moving in to a location (e.g pawn moving to end of board) without having either another mediator subscription or a method that is only over-ridden by 1 subclass. Duplicate point, and our design already allows for this without either of your proposed "bad" solutions.

My solution while "not a pattern" is not an anti-pattern, does not break OOD principles and considers more problems that may exist in the development of a chess game.
"Your solution" makes it very difficult to arbitrarily add new kinds of pieces, which is the whole goal of the ChessPlusPlus project.

@JLBorges: unfortunately that doesn't work very well when you want to add arbitrary new pieces.

abhishekm71 wrote:
This class takes two entities as parameters, checks whether castling is possible between them and enrolls them if it is.
No, this is not what happens at all. The rooks and kings specifically enroll themselves or unenroll themselves based on their own requirements.
abhishekm71 wrote:
Also, just to remind you:
- castling is possible both on queen side and king side.
- the conditions for castling are slightly more restrictive than what were brought out earlier on this thread:
* Not only the king should not be in check, the final square of the king and the square that the king jumps should also not be in check.
I was aware of this, and because of our existing design this was not a problem.
abhishekm71 wrote:
Maybe the simple castling procedure outlined by FIDE rules could give you an idea about how to go about it:
- The king moves two squares in the direction of the respective rook.
- The respective rook occupies the square that the king jumps over.
Actually, thanks, Wikipedia took a very long time to explain that the king only moved two spaces :)
> @JLBorges: unfortunately that doesn't work very well when you want to add arbitrary new pieces.

Why wouldn't it? Any new piece also would have rules regarding valid moves that can be made; a PERFT can be generated (and a search tree must be generated) for any board with any kind of pieces. It is a fundamental prerequisite for starting the search/evaluate/prune/select move process.

The problem is bigger if the board size changes (processors are 64-bit). With an 8x8 board, getting all the unoccupied squares on the board can be done in 8 instructions (bitwise or). Checking for free squares for castling can be done with just one more instruction. With a new kind of piece added, the 8 instructions would grow to 9. But change to a 9x9 board, and things get more than twice as expensive.
Are you talking about implementing AI? Because right now our goal is multiplayer.
> Because right now our goal is multiplayer.

Ah! I was completely mistaken.

Made those posts without having realized that it is a toy project. Please treat them as withdrawn; they have no relevance.

Edit: Unsubscribing from this thread. My solution was actually in the code base until LB refactored it out. He has started heavy refactoring of their project despite the fact it's not functional and far from complete. This thread seems to be a waste when the solution was already implemented but he decided to remove it.

https://github.com/cpluspluscom/ChessPlusPlus/blob/master/src/board/Piece.hpp
Last edited on
Pages: 123