Comments/Ratings for a Single Item
sign and - are two seperate operations. The - operator does subtraction. The sign operator indicates whether the result of the subtraction is positive, negative, or zero by returning 1, -1, or 0. In this context, this value is being used as a value for the where operator, which takes three arguments and returns a coordinate. It is the same coordinate each time. The space in question is the diagonal space it must pass through before turning to move in an orthogonal direction. By using sign twice, it has divided the board into four quadrants, and it has identified the only diagonally adjacent space it could have passed through to reach the space legal movement to is being checked for. If this space is empty, it then checks whether orthogonal movement from that space could reach the destination space.
@Fergus
I'm not confident enough to be sure about this, so I'm asking:
Is the following code fine for verifying if a piece that can perform moves only as and alfil and ThreeLeaper (or Trebuchet as is also called) but can both move and capture as a regular knight ?
checkleap #0 #1 3 0 and nor capture nor empty #0 empty #1 or checkleap #0 #1 2 2 and nor capture nor empty #0 empty #1 or checkleap #0 #1 2 1;
As a sorce of inspiration I had used your anglican bishop code in Caissa Britania :)!
Thanks!...
Because the function is going to be used for both actual and potential moves, it has to be able to handle both. For a potential move, #0 will still be occupied, and #1 must be empty, but for an actual move, #0 will be empty, and the move must not be a capture. So, depending on the value of #0, you want to confirm either that #1 is empty or that the move is not a capture. The portion of your code devoted to this looks like this:
and nor capture nor empty #0 empty #1
First, "nor empty #0 empty #1" returns true if #0 and #1 are both false. This value is used as the second value for the next nor. So, "nor capture nor empty #0 empty #1" returns true if #0 and #1 are not both false and it is not a capture. This does not seem to be what you want, since it will always require a false value for capture. But this matters only when #0 is empty, and it could throw off the evaluation of a potential move.
It would be better to use this:
and cond empty #0 not capture empty #1
This returns "not capture" if #0 is empty or "empty #1" if #0 is not empty. The and requires this value to be true for it to continue. Note that this test has to be done only once. So your code can look like this:
checkleap #0 #1 3 0 or checkleap #0 #1 2 2 and cond empty #0 not capture empty #1 or checkleap #0 #1 2 1;
The Bishop in Caissa Britannia had used this code:
def B checkleap #0 #1 1 0 and nor capture nor empty #0 empty #1 or checkride #0 #1 1 1;
Based on what I wrote earlier, this code is incorrect. In a test I ran, this code allowed the Bishop to make a non-capturing orthogonal move, but it did not display it among the available legal moves. So, it seems to be working for actual moves, but it is not working for potential moves. With that in mind, I have changed it to this:
def B checkleap #0 #1 1 0 and cond empty #0 not capture empty #1 or checkride #0 #1 1 1;
Running the same test, this code worked correctly for both potential and actual moves.
Hei Fergus,
About the anglican bishop, I remember noticing somthing as I had played a few games a few months back. Quite a nice game, by the way.
I almost understand the code you posted although I still have trouble with the order of operations as the instructions:
operator p q , p operator q are both valid, and that is a bit troubelling to me.
I know where to read material on this though. If I still have trouble I'll then come back to you :)!
GAME Code uses prefix notation, not infix notation. This means the operator comes first. Where it looks like infix notation, the operator is actually working with only one operand. In particular, the logical operators can work with either one or two operands. This allows you to string them together as though you were using infix notation, but it doesn't work the same way as infix notation would.
Thanks for the explanation Fergus, now it is clear to me :)!
logrude seems to not be repeating the last direction indefinitely. In fact, it has some really weird behavior going on right now.
Show me your code and give me a link to where you are using it, and I will take a look.
This preset for Chu Seireigi shows the bug in action. It defines the Queen as a Metamachy Gryphon with an additional direction to show what happens with repeated non-final directions.
The relevant code is:
map n 0 1 s 0 -1 w -1 0 e 1 0; // Orthogonal directions
map nw -1 1 ne 1 1 sw -1 -1 se 1 -1; // Diagonal directions
def Queen logride #0 #1 (nw n) (nw w) (ne n) (ne e) (sw s) (sw w) (se s) (se e) (nw nw n);
def Queen-Range lograys #0 (nw n) (nw w) (ne n) (ne e) (sw s) (sw w) (se s) (se e) (nw nw n);
The last direction is not repeated indefinitely. It only repeats as many times as the direction before it is repeated.
To properly test whether logride was working correctly, I redefined Queen-Range to include all spaces except the space the piece began on.
def Queen-Range diff spaces #0;
When I did this, I got a very different result. You can see the result here:
https://www.chessvariants.com/play/pbm/play.php?game%3DChu+Seireigi%26settings%3Dstingmovetest2
So, it looks like logride is working correctly, but lograys is not perfectly in sync with logride. I'll have to more closely examine them to see how I can modify lograys to match logride.
If that is the case, then the logical definitions of the Griffon and Aanca should be as follows:
def G logride #0 #1 (nw (n)) (nw (w)) (ne (n)) (ne (e)) (sw (s)) (sw (w)) (se (s)) (se (e));
def GL lograys #0 (nw (n)) (nw (w)) (ne (n)) (ne (e)) (sw (s)) (sw (w)) (se (s)) (se (e));
def A logride #0 #1 (n (nw)) (w (nw)) (n (ne)) (e (ne)) (s (sw)) (w (sw)) (s (se)) (e (se));
def AL lograys #0 (n (nw)) (w (nw)) (n (ne)) (e (ne)) (s (sw)) (w (sw)) (s (se)) (e (se));
This is because of how logride's documentation says it should be used to describe turning riders, as shown below.
logride from to ...
...A turning rider needs directions in a nested pair of parentheses. The directions before the second pair of parentheses indicate the beginning of a turning rider's move, and what comes in the inner pair of parentheses indicates how the turning rider continues to repeat its move.
will we never stop to use "aanca" to mean something else than the Gryphon?
How did this settings file, which I created last night, get edited? I see it has $author set to an empty string instead of to my userid, and Queen-logride has been defined to what Adam proposed it should be after I had already gone to bed.
https://www.chessvariants.com/play/pbm/play.php?game%3DChu+Seireigi%26settings%3Dstingmovetest2
As a test, I tried to steal Adam's stingmovetest file by saving it with my userid, and I got the message:
You (fergus) are not the author (chessshogi) of this settings file. So you may not edit it.
This is the message that should show up, and on inspecting the file, I see that my changes are not in the file. So, I may conclude that I did not overwrite a stringmovetest2 file that Adam had previously created.
As a second test, I created stingmovetest3, and on loading it into an editor, I saw that $author was set to my userid.
As a third test, I saved a modified copy as stingmovetest4 without a userid, and it allowed it.
As a fourth test, I modified it again and saved it with my userid. This time, my userid showed up as the value of $author.
As a fifth test, I modified stingmovetest2 and tried to save it without being signed in. This was not allowed, which is good, because it should not be allowed.
As a sixth test, I signed into a spare account I use for testing, and I tried saving a modified stingmovetest2. My modification went through, and $author is still set to the empty string.
So, it appears there is a security hole in Game Courier. It is possible to create a settings file with an empty Userid, and then anyone who is signed in can edit it. It was probably empty, because I updated the settings file before saving it, and updating it clears the Userid field from the form. Not noticing this, I apparently saved it with any empty value for $author, and not realizing it wasn't his own settings file, Adam edited it without entering his own userid.
I addressed this by filling in the $userid value from the SESSION variable when someone is already signed in. This stops someone from creating a settings file with an empty userid, but it does allow someone to steal a settings file that already has an empty value for $author.
The difference was that logride was using a recursive function, and lograys was not. So, I wrote a recursive function for lograys, and I tested it with a Queen that could move anywhere but its own square. Tests showed that it worked correctly for straight riders, turning riders, and winding riders. So, lograys and logride will now match up.
The innermost direction or series of directions is the one that gets repeated, because it repeats any series of directions given to it within parentheses, and it just gets caught in each deeper loop without any means of returning to the outer loop. But since it stops when it runs out of spaces, it avoids an infinite loop.
I have updated the Griffon and Aanca functions to use features that were not in the language when I originally wrote this page. The mathematical versions now use named variables, and the GL and AL functions also use lambda functions. The logical versions now use the arguments that Adam DeWitt said they should use in an earlier comment.
It seems you forgot to copy the new Griffon logic over to the Griffon-Range function.
The Griffon-Range function currently looks like this:
def Griffon-Range lograys #0 (nw n) (nw w) (ne n) (ne e) (sw s) (sw w) (se s) (se e);
The Griffon-Range function should look like this:
def Griffon-Range lograys #0 (nw (n)) (nw (w)) (ne (n)) (ne (e)) (sw (s)) (sw (w)) (se (s)) (se (e));
It seems you forgot to copy the new Griffon logic over to the Griffon-Range function.
Okay, that's fixed.
21 comments displayed
Permalink to the exact comments currently displayed.
Hi Fergus,
I don't seem to understand squat out of the griffin code :(!
First I don't understand what "sign -" does. I'm thinking that it means that both the rank and file must vary by 1 in absolute value. But I don't see the intricacies :)!
The aanca code seems roughly the same albeit for an abs function :(!
I get the same feeling :)!
So when the time please fill me in to some details, please!