Thank you for your donations!   Download the book!   Public source code repository  

This is The Avocado!

With capital T. And capital A. Compared to which Sparta is a very mild chamomile.

No matter how you try to slice it, you'll end up in an unbreakable kernel. And, if you try to force it, you'll end up with just a few annoying, inedible bits, and kernel still barely scratched. That is an avocado. 

Good engineering practice, and really the only one to enable reasonable rate of progress, is to divide any problem into smaller and smaller bits, until you can build from solutions to the smallest problems, up to the whole. And, of course, you'll want least possible amount of special cases, since those ruin your division into smaller and smaller bits.

Enter The Avocado Croatian Chess. Its algebraic notation features mild context-sensitive grammar (I was reasonable about it). It also has external data (game status, and chessboard, more precisely positions and tags of all pieces on it) not just as a dependency, but as a context; because to be able to parse any ply in a cascading move, one has to apply all previously parsed plies to chessboard, since those are changing positions and tags of pieces. To top it off, it also features self-evident, reasonable requirement for a convenient notation, i.e. almost all movement can be noted with just a piece + destination field (+ side-effects, if present).

For trance-journey, the same applying to context chessboard thing has to be done for steps, since those are also changing positions, tags. Congratulations, this is a very first special case, and to handle it via unified interface, now every step of every ply has to be applied to a context chessboard. In fact, there is barely any rule that doesn't have a special case, making any unified interface a nightmare to implement. While it might look like a self-inflicted pain (which it is), the matter of fact is that special cases are the meat of the game, without them it would be just a scaling game. I have to confess, I was thinking about ditching the whole Croatian Chess shebang, and regress to scaled-up Classical Chess, just by copying 3 side figures, and accompanying Pawns a few times over, resulting in 14 x 14, 20 x 20, and finally 26 x 26 chessboard, with no special cases pain. While that might do for a while, it's ultimately boring, and brings nothing new to the table.

Now you see why you can't just take notation alone and try to parse it, you'll need live chessboard (positions, tags), and game status (who is on the move). You can't even say if move notation taken alone is valid, some plies aren't legal, depending if e.g. activation of pieces are made on step- versus capture-fields. I could've opted to do most of validity tests, and forego those which can't be done without chessboard, but that would pose at least three problems. First, most tests would be done, but some, seemingly arbitrarily, would be missing. As a consequence, validity would be restricted, and non-intuitive compared to what most users (me including) would expect. And there is a problem that validity checks are done on notation, and would be repeated again during parsing, now with greater scope since chessboard is available, and most likely again while actually applying movement of pieces, side-effects to chessboard.

So, it seems to me that whole game engine has to be put upside-down, like a pyramid with a pointy-bit at the very bottom. That means, most of work done so far is actually useless, and it should be deleted. Better to start from scratch, then try to salvage garbage; this includes almost all of tests application. Next, movement data has to be considered correct, so there would be no wasting time trying to validate it. This is probably the hardest part of implementation, as it too goes against well ingrained engineering practices, where all of user inputs are considered invalid, until proven otherwise. Both major components (parsing, applying move) would have to produce user-readable error messages. Actually, there would be only one major component, as the only difference between parsing and applying notation would be on the last leg, when the latest context chessboard is returned from parser, or it's set as a new live chessboard, and game status updated accordingly, if applying a move.

On top of all that, a few days ago I found out that activation rules are not thought through, or at very least, not formulated exactly. Problem is that Pyramid can't be activated on a step-fields directly, but currently it can be done in a cascade indirectly, via Wave, and with no restrictions. Since activation is a keystone of the whole lot, I'll have to do it before any coding can take place. Needless to say, I'll also have to revisit every single example in the book which includes activations, and change those accordingly.

In short, I have done very little so far, a lot of book rewriting has to be done, before any real coding work could commence.

No comments:

Post a Comment