Comments/Ratings for a Single Item
Well, it works! but how to enforce that first white’s move must be by Superpiece?
how to enforce that first white’s move must be by Superpiece
in the pre-game section add setflag firstmove;
and in post-move 1 add
if != #mover S and flag firstmove:
die "You must move the S on your first turn";
unsetflag firstmove;
endif;
if capture and match $old (bl br):
capture where $dest direction $origin $dest;
endif;
I put this in the post move, but when it runs it captures the piece at $dest rather than the specified location. It works correctly if I change it to
if capture and match $old (bl br):
set x where $dest direction $origin $dest;
capture #x;
endif;
but I don't see why it would make a difference
But how to set firstmove
flag only on the first move? Otherwise it doesn’t let White to move anything but S if flag is in Pre-Move section, and entirely anything if is in Pre-Game section.
Sorry, I really messed that up. This actually seems to work, if you put it in post-move 1. You don't need the flag.
if != #mover S and == movenum 1:
die "You must move the S on your first turn";
endif;
![Editor](/index/editor.gif)
It must be in the Pre-Game section, not the Pre-Move section. It was just that the unset should not have been within the if-clause, but done unconditionally.
Thanks it works!
For a multi-part move, does the post-move code run just once for the whole thing or once for each part?
For a multi-part move, does the post-move code run just once for the whole thing or once for each part?
Once for the whole thing. To handle multi-part moves, you can rewind the move and handle one part at a time. For details, you can read How to Program Multi-Move Variants for Game Courier or review the code for either Marseillais Chess or Extra Move Chess.
Why doesn't chess need to do that to handle promotions?
Why doesn't chess need to do that to handle promotions?
Promotions are a different type of move than regular moves. Instead of moving a piece from one location to another, a promotion changes the last piece to move to another piece. So, it does not change the values of $origin and $dest. To check whether a promotion has happened, you can compare the value of $moved, which was set when the piece moved from one location to another, with what currently occupies the space moved to (space $dest). When they are different, a promotion has happened, and you can deploy code for testing whether it was a legal promotion.
I'm sure there's a reason for this, but why is it that having legality defined for move highlighting isn't enough to have legal moves enforced?
I'm sure there's a reason for this, but why is it that having legality defined for move highlighting isn't enough to have legal moves enforced?
-
Rule enforcement was a feature before showing legal moves was. Instead of replacing the standard method for rule enforcement, calculating all possible legal moves ahead of time was done as an extra step.
-
Additionally, moves sometimes had side effects that were not explicitly mentioned in the notation for a move, such as en passant capture in Chess or changing the side of a piece and placing it in hand for Shogi. This imposed the requirement of running code for the actual move when it was made.
-
Because calculating all possible legal moves is more expensive than just calculating whether one move is legal, it is done only in the Post-Game section. So, if rule enforcement depended upon the calculation of all possible moves for each turn, it would work only in on-going games made one move at a time, or it would have to be repeatedly done in the Post-Move sections, which would prolong the calculation of whether a series of moves were all legal. The way it currently works, it evaluates the legality of a series of moves much more efficiently than it would if it had to calculate all possible moves after each move. For the sake of efficiency, which kind of matters in an interpreted language written in another interpreted language, it makes sense to calculate all possible legal moves only when there is a choice of which move to make. For past moves, calculating all this is just overkill.
[Edit: combined 3 and 4]
Why this instruction: setsystem legalmoves ((e5 a1) (e5 b1) (e5 c1) (e5 d1) (e5 e1) (e5 g1) (e5 h1) (e5 i1) (e5 j1)); gives the error: e5-b1, which is listed as a legal move, is not a well-formed move.
Here is the preset in question.
A well-formed legal move should include the piece, but since e5 is empty, the compose_move function is not finding any piece to include in the move. Make sure each of your legal moves is from an occupied space.
In the explanation of the rank unary operator it says that it returns the file. Probably an copy-paste error.
In the explanation of the rank unary operator it says that it returns the file. Probably an copy-paste error.
Okay, I fixed that.
I just made a modification to unless, because it was returning 1 for "a unless true" instead of nothing like "a onlyif false" would. The reason for this is that in each case, it was returning the first value after unless or onlyif, but onlyif was returning it if false, and unless was returning it if true. So, I have changed unless to return false when it has a single true argument. This allows something like "print a unless true" to work as expected and print nothing.
In checking over which logical functions behaved the same as onlyif and unless, I determined that these should be and and nor. The documentation already correctly identified onlyif as behaving like and with only one argument, but it mistakenly said that unless behaved like or. I have now corrected this to say that it operates like nor.
However, in tests I ran, "m nor false" was returning 1 instead of m. I discovered there was a bug in the logic for nor. The part concerning only one argument had read like this:
if ($op2 === NULL) {
if ((((array)$op1 === $op1) && polish($op1, $linenum, $substitutions)) || ($op1 == true))
$output = array(false);
$input = array();
}
There were a few problems with this. First, if $op1 was an array containing a false expression, it would then evaluate ($op1 == true). Second, if $op1 wasn't equal to true, it would return false even if $op1 was a non-empty value. Third, "$input = array()" would execute even if the previous conditional were false, because without braces, it was not actually in the scope of the if-statement. So I changed the code to this:
if ($op2 === NULL) {
if ((array)$op1 === $op1) {
if (polish($op1, $linenum, $substitutions)) {
$output = array(false);
$input = array();
}
}
elseif ($op1 != false) {
$output = array(false);
$input = array();
}
}
This code eliminates the issues I described above, and it allows "print m nor false" to print m just like "print g unless false" prints g.
I made similar changes to nand. I'll look into whether I should do the same for and and or, as each has a similar disjunctive condition, but it's too late at night to spend time thinking about it now.
I'm not sure if it's mentioned in the documentation, but the logical operators can evaluate expressions in parentheses, but unless and onlyif do not. So, for these two, (false) evaluates to true, whereas it should evaluate to false for the logical operators. I will test things out better tomorrow to make sure the logical operators are behaving correctly.
I have now undone the corrections I made to nor and nand, and I have removed support for using them with single arguments. The reason I wanted to do this was because "x nand y" would not always return the same truth value as "nand x y", and "x nor y" would not always return the same truth value as "nor x y". I also used grep to check the settings files and include files for single argument uses of nand or nor, and I didn't find any. So I went ahead with the change and made updates to the documentation. This helps remove the possibility that someone could use them to write confusing, obfuscated code. No such issue exists with and and or, as "x and y" will always return the same truth value as "and x y", and "x or y" will always return the same truth value as "or x y".
I did make corrections to and and or similar to the changes described below, but I used ?: instead of if-statements. This did correct how or behaved for or (false), though it didn't change the results I got with and.
![Editor](/index/editor.gif)
I would think x nand y should produce the same value as nand x y by definition, the only difference being that y (and thus its possible side effects) would not be executed if the value of x already fixes the outcome (i.e equals false).
I would think x nand y should produce the same value as nand x y by definition, the only difference being that y (and thus its possible side effects) would not be executed if the value of x already fixes the outcome (i.e equals false).
First, remember that the order of operation is from back to front. So you meant to say, "the only difference being that x (and thus its possible side effects) would not be executed if the value of y already fixes the outcome (i.e equals false)."
If y is false in "x nand y", it would exit the expression with a value of true without evaluating x. But if y is true, it would evaluate x. If x is false, then "nand x y" would be true, but "x nand y" would return the value of x, which would be false.
![Editor](/index/editor.gif)
That is a completely unexpected implementation of nand. I would expect x nand true to evaluate to not x. What you describe would be x or not y. I think it is a mistake to call that nand.
I would expect x nand true to evaluate to not x. What you describe would be x or not y.
Remember that GAME Code uses polish (a.k.a. prefix) notation, not infix notation. So, in GAME Code, x nand y would be two separate expressions, not a single expression, and it would indeed be equivalent to x or not y.
I think it is a mistake to call that nand.
This is why I decided to no longer allow nand to be used with just a single argument.
25 comments displayed
Permalink to the exact comments currently displayed.
You have to indicate that in the FEN of the preset. (I think by a dash.)