In looking into this, I tested Gross Chess to see if it had the same problem, but before I could tell, I encountered another problem with it. I realized that for a game like Gross Chess it wouldn't do to use bprom and wprom as though they had static values. So I rewrote the fairychess include file and the Gross Chess code to support dynamic values for what a piece is allowed to promote to on a given space.
This makes use of some new functions that end with "-Promote". Here are the default functions for the Pawns:
def White_Pawn-Promote var wprom;
def Black_Pawn-Promote var bprom;
For backwards compatibility with the original way of handling promotions, these just return the value of wprom or bprom. And for additional backwards compatibility, the stalemated subroutine will use these functions only if the piece is not in the promotable array. So, to enable the use of these functions for providing dynamic values for what a piece can promote to, you should unset promotable or set it to an empty array. I added this line to Gross Chess after including the fairychess include file.
unset promotable;
Since the default functions return static values, they need to be rewritten for the particular game they are for. Here are the functions I wrote for Gross Chess:
def White_Pawn-Promote merge intersection var cap elem - rank #0 9 ((B N V W) (B N V W C R S) (B N V W C R S A M Q)) elem - rank #0 9 ((P) (P));
def Black_Pawn-Promote merge intersection var cap elem rank #0 ((b n v w c r s a m q) (b n v w c r s) (b n v w)) elem rank #0 (() (p) (p));
Since what a Pawn may promote to in Gross Chess depends upon the rank it is on, I used the rank value for black (or a value calculated from the rank value for white) as the index for a couple of arrays from which it extracted a particular value. For example, black can promote on ranks 0-2, as they are designated internally. So, this code will return the element of the array with the same index as the rank value:
elem rank #0 ((b n v w c r s a m q) (b n v w c r s) (b n v w))
Since white promotes on ranks 9-11, I subtracted 9 to get a value from 0 to 2 for any rank promotions are allowed on or a number that is out of range for any other rank. So, this works similarly:
elem - rank #0 9 ((B N V W) (B N V W C R S) (B N V W C R S A M Q))
Since the last rank for black is 0, and the last for white is 11, and 11-9 is 2, these list sets of promotion options in the reverse order from each other.
Since promotion options are limited to captured pieces, each function calculates the intersection of the value above with the captured pieces. This looks like this for black:
intersection var cap elem rank #0 ((b n v w c r s a m q) (b n v w c r s) (b n v w))
Finally, I get to the part that is relevant to Obento Chess. Whether it can promote to a Pawn as a way of declining promotion depends on the rank but not on what has been captured. So Pawns were not included in the main lists of promotion options. Instead, it merges the intersection calculated above with the value of another array element. Again, the specific array element is a function of the rank. Here is what it looks like for black:
elem rank #0 (() (p) (p))
Since declining promotion is not an option for black on rank 0, an empty array is provided for the element with an index of 0. This is not necessary for white, as the rank it cannot decline promotion on has a higher index.
elem - rank #0 9 ((P) (P))
For Obento Chess, you might use functions like these:
In looking into this, I tested Gross Chess to see if it had the same problem, but before I could tell, I encountered another problem with it. I realized that for a game like Gross Chess it wouldn't do to use bprom and wprom as though they had static values. So I rewrote the fairychess include file and the Gross Chess code to support dynamic values for what a piece is allowed to promote to on a given space.
This makes use of some new functions that end with "-Promote". Here are the default functions for the Pawns:
For backwards compatibility with the original way of handling promotions, these just return the value of wprom or bprom. And for additional backwards compatibility, the stalemated subroutine will use these functions only if the piece is not in the promotable array. So, to enable the use of these functions for providing dynamic values for what a piece can promote to, you should unset promotable or set it to an empty array. I added this line to Gross Chess after including the fairychess include file.
Since the default functions return static values, they need to be rewritten for the particular game they are for. Here are the functions I wrote for Gross Chess:
Since what a Pawn may promote to in Gross Chess depends upon the rank it is on, I used the rank value for black (or a value calculated from the rank value for white) as the index for a couple of arrays from which it extracted a particular value. For example, black can promote on ranks 0-2, as they are designated internally. So, this code will return the element of the array with the same index as the rank value:
Since white promotes on ranks 9-11, I subtracted 9 to get a value from 0 to 2 for any rank promotions are allowed on or a number that is out of range for any other rank. So, this works similarly:
Since the last rank for black is 0, and the last for white is 11, and 11-9 is 2, these list sets of promotion options in the reverse order from each other.
Since promotion options are limited to captured pieces, each function calculates the intersection of the value above with the captured pieces. This looks like this for black:
Finally, I get to the part that is relevant to Obento Chess. Whether it can promote to a Pawn as a way of declining promotion depends on the rank but not on what has been captured. So Pawns were not included in the main lists of promotion options. Instead, it merges the intersection calculated above with the value of another array element. Again, the specific array element is a function of the rank. Here is what it looks like for black:
Since declining promotion is not an option for black on rank 0, an empty array is provided for the element with an index of 0. This is not necessary for white, as the rank it cannot decline promotion on has a higher index.
For Obento Chess, you might use functions like these:
You could handle promotion for the other promotable pieces with similar functions for each specific piece.