fairy-stockfish / Fairy-Stockfish

chess variant engine supporting Xiangqi, Shogi, Janggi, Makruk, S-Chess, Crazyhouse, Bughouse, and many more
https://fairy-stockfish.github.io/
GNU General Public License v3.0
628 stars 197 forks source link

Zonal boards #843

Open HGMuller opened 4 days ago

HGMuller commented 4 days ago

This enhancement suggestion is triggered by the announcement of a variant-design contest on pychess.org. The theme is 'zonal boards', and one suggestion was to have pieces that move differently in one zone than in another. But some doubt has risen whether Fairy-Stockfish can do that.

The most straightforward implementation of this would consider it promotion on entering one zone, and demotion on leaving it. Now demotion is not a different mechanic from promotion, just another name depending on how the player values the pieces. So it seems that (mandatory) Shogi-like promotions could do the trick: type A promotes to B, and type B promotes to A. Provided that A and B use different (in this case complementary) promotion zones. When they would both use the same zone, you would get Kyoto-Shogi-like behavior. (Especially when the promotion zone would be the entire board.)

So the enhancement would be to allow specification of a promotion zone per piece type.

In the Interactive Diagram I have implemented an even more general concept: for each piece type one can define a 'morph board'. Which for each board square defines to what the piece type changes when the piece moves there, whether moving there is forbidden, or whether it leads to an immediate or a delayed win. This is very versatile, and can be used to define irregular promotion zones, different promotions on different squares, capture-the-flag or king-of-the-hill victory conditions...

A similar mechanism is the 'capture matrix', which does not map (mover type, destination) to a new type, but maps (mover type, victim type) to a (colored) type. This can be used to define mandatory promotion on capture, forbid certain captures (e.g. to define a Stratego-like capture hierarchy), or trigger other special effects (like 'explosion' or 'burning') in a type-specific way.

All this might be quite easy to implement, and it has proven to be extremely versatile.

HGMuller commented 2 days ago

Let me elaborate a bit on how the 'morph board' works in the Interactive Diagram, in the hope this will provide some inspiration. We should basically see it as a device to define a lot of rules in the configuration file in a compact, unified way. It controls promotion, board access and special winning conditions in a type-specific way.

A morph parameter for a given piece type is a board image (e.g. ranks separated by slashes, squares on the rank by commas, or not at all if the symbols on the rank are guaranteed to be single characters). Each square can contain a piece ID, a (numerical) reference to a 'promotion set' or a punctuation symbol indicating a game result.

A single piece ID indicates mandatory promotion to that type. It combines the function of FSF's parameters promotedPieceType and promotionRegion. With the added flexibility that it defines the promotion region just for the piece type to which the morph parameter applies, and that the type promoted to can be made dependent on where the promotion takes place. If FSF would handle promotion through a lookup table[movingColoredType][toSquare] there would be backward compatibility when the promoted version of the piece as specified in promotedPieceType would fill the entire promotionRegion for that color. An explicit morph parameter could then overrule that.

The Interactive Diagram has a parameter promoChoice, which is the equivalent of FSF's promotionPieceTypes. Except that you cannot only define a single 'pieceSet', but a number of sets (e.g. separated by slashes). Instead of specifying a piece, the morph table can refer to such a set. This would for instance allow different promotion choice on different ranks for the same piece, or different 'pawn types' to offer different choices. Backward compatibility is achieved by filling the morph table for all the types specified in promotionPawnTypes for the part specified in promotionRegion for their color with the primary promotion set defined by promotionPieceTypes.

For convenience there is a special symbol for indicating Shogi-style promotion (i.e. choice between staying the same or promoting to the type defined in promotedPieceTypes), so that you don't have to explicitly create piece sets for all of those. In FSF this could be used in combination with a promotedPieceType specifying how pieces promote, possibly in combination with an empty promotionRegion, leaving specification of the region in a type-specific way to the morph parameter.

Similarly, there is a symbol for mandatory Shogi promotion. One could have simply written the ID of the promoted type there, but in Shogi such IDs are often multi-character (e.g. '+L'), and then would force comma separation.

A square can be indicated as inaccessible to the applicable piece type. This could be seen as that moving there immediately terminates the game as a loss. Useful in Xiangqi. Note that this doesn't mean the square is impassible for sliders. There could be a symbol for that too. Promotion and inaccessibility are mutually exclusive, so there was no harm in specifying those within the same morph parameter.

Finally square can be designated as winning game terminations. (They must then be accessible, and promotion would no longer make sense as you would never get to move the promoted piece.) There are two flavors of this: immediate wins (i.e. by any pseudo-legal move) and delayed wins (tested after the opponent's move, so by legal moves only). For backward compatibility the morph table of the FlagPiece would get its FlagRegion filled with immediate or delayed wins depending on FlagPieceSafe.