Comments/Ratings for a Single Item
Fergus,
This might be an unusual request, but is it possible to clear the moves previously set as legal?
I'm trying to leverage code you have already written in the chess include file to determine that a position is a stalemate, so that I can display a message that even though the position is a stalemate, the King still needs to move (as Kings are allowed to move into check in this variant).
The setlegal is useful to determine the stalemate, but complicates other situations for me, so I rather not see the legal moves when a player clicks on a piece on the board (but I still want to benefit from the setlegal moves functionality to determine stalemate (and checkmate) )
Is there an easy way to wipe out the legal moves array as a command to be used in the Pre-Move sections of a preset?
Thanks.
This might be an unusual request, but is it possible to clear the moves previously set as legal?
Yes, use setsystem legalmoves ();
I'm trying to leverage code you have already written in the chess include file to determine that a position is a stalemate, so that I can display a message that even though the position is a stalemate, the King still needs to move (as Kings are allowed to move into check in this variant).
You should copy the subroutine into your preset and modify it to not check whether the King is in check. Then it would accurately report on legal moves in the game.
Is there an easy way to wipe out the legal moves array as a command to be used in the Pre-Move sections of a preset?
Since legal moves are normally calculated in the Post-Move section, there would be nothing to wipe out in the Pre-Move sections.
Fergus,
I created a rules enforcing preset for Makruk, which is working well:
Now I'm trying to copy the rules in this preset onto another Makruk preset that uses a different set of pieces:
http://play.chessvariants.com/pbm/play.php?game%3DMakruk+%28Thai+chess%29%26settings%3DAlfaerie4r
Unfortunately the latter is not working as expected. I have been doing some troubleshooting, and I think I have identified the issue.
For this preset, instead of a Ferz and Elephant, I'm using upside down pieces Q180 and B180, as well as upside down pawns to represent the promoted pawns (P180).
After making the neccesary changes, I cannot get the preset to calculate the legal moves for these upside down pieces.
I changed the upside down pawn (P180) for a Banner (BA), and the rules worked for the Banner.
My guess is that the logic for the stalemated function does not recognize numbers as part of the code for the piece, which would explain why it would work for a promoted pawn with the shape of a Banner (BA) but not for an upside down pawn (P180) which has numbers as part of the name code of the piece.
This will be a problem if I use Silver generals which have a non-letter code: S! and s!.
I believe the problem is with the onlyupper and onlylower nullary operators. These operators should ignore non-alpha characters.
Can you review the definition of these operators and the stalemate function to make it more generic?
Thanks
Jose
I'm not going to change onlyupper and onlylower, because that could break scripts, and it would make them less efficient than they need to be for normal use. But you can get what you want using the aggreate function with some lambda functions. These check only the first character in a piece label. Just create your own stalemated subroutine that uses them.
Instead of onlyupper, use "aggregate lambda (#0 onlyif isupper char #0 0) pieces"
Instead of onlylower, use "aggregate lambda (#0 onlyif islower char #0 0) pieces"
Hi Fergus,
Thanks for the suggestion. I tried, but now nothing works. The moves are not calculated for any of the pieces, but the Kings, and now the Kings are allowed to capture their own pieces.
http://play.chessvariants.com/pbm/play.php?game%3DMakruk+%28Thai+chess%29%26settings%3DAlfaerie4r
Can you please check the preset and tell me where I went wrong?
Thanks.
My tests indicate that the code I gave you is working as it should. But in addition to these, you should change the friend function to check only the first character. Just replace "#0" with "char #0 0" for each definition of friends.
Still not working.
I'm going to use the following definition for new onlyupper and onlylower functions:
def onlylower2 aggregate lambda (#0 onlyif islower char #0 0) pieces;
def islower2 ???
The problem is that onlyupper and onlylower each returned an array of pieces that was indexed to coordinates, and the lambda functions I gave you return arrays that are numerically indexed. So, forget about the lambda functions, delete the definitions for the friends functions, replace "fn friends" with "pieces" and modify the part of the code that makes sure the piece isn't the King to also make sure it is a friend.
if == #from #king or not fn friend #piece:
continue;
endif;
I will try to decipher your recomendation later.
Is there any chance that you can add 4 new functions (onlyupper2, onlylower2, isupper2 and islower2) that work identical to their current counterparts, but that only tests the 1st character?
This way the current code for any of the presets can be very easily updated to use new piece-sets, without any major modifications.
Thanks.
I have just created a new function called filter. Like aggregate, it takes a lambda function and an array as arguments, and it returns an array. Unlike aggregate, it returns both the key and the value of any array element for which the Lambda function evaluates as true, and it can use both the key and the value in the Lambda function. In the Lambda function, #0 stands for the key, #1 for the value. When the value is an array, #1 is the first element in the array, #2 the second, and so on. While aggregate returns the value of the Lambda function for each true call of it, filter just returns the key and value from the original array. So there is no need to include the return value in the Lambda function when using filter. So, you can ignore what I said in my last message and make these substitutions in your code:
Instead of onlyupper, use "filter lambda (isupper char #1 0) pieces"
Instead of onlylower, use "filter lambda (islower char #1 0) pieces"
If you use any piece labels that do not begin with an alphabetic character, these will work better:
Instead of onlyupper, use "filter lambda (fnmatch "*[A-Z]*" #1) pieces"
Instead of onlylower, use "filter lambda (fnmatch "*[a-z]*" #1) pieces"
I also created a regmatch function, which you can use if you are familiar with regular expressions. It works like fnmatch except that the first argument should be a regular expression instead of a wildcard pattern.
Instead of onlyupper, use "filter lambda (regmatch "/[A-Z]/" #1) pieces"
Instead of onlylower, use "filter lambda (regmatch "/[a-z]/" #1) pieces"
For the friend functions, you can use what I already gave you, or you can use one of these pairs:
fnmatch "*[A-Z]*" #0
fnmatch "*[a-z]*" #0
regmatch "/[A-Z]/" #0
regmatch "/[a-z]/" #0
Thanks for your response and the new functions Fergus.
To keep things simple (I'm an old programmer, not too familiar with the lambda terminology), I just want four replacement functions (that I can use as black boxes) for the existing ones, so that I can do minimal changes to the presets.
Can I use this definition for the new functions I'm looking for?
def onlyupper2 filter lambda (regmatch "/[A-Z]/" #1) pieces
def onlylower2 filter lambda (regmatch "/[a-z]/" #1) pieces
def isupper2 regmatch "/[A-Z]/" #0
def islower2 regmatch "/[a-z]/" #0
Thanks for your help.
store;
local from piece to;
def friends filter lambda (regmatch "/[A-Z]/" #1) pieces;
def nofriends noupper;
def friend isupper #0;
else:
def friends filter lambda (regmatch "/[a-z]/" #1) pieces;
def nofriends nolower;
def friend islower #0;
endif;
def checked any lambda . . . . "fn space #0 #0 " #0 " unless samecase space #0 space " #0 spaces;
sub checked king:
my from piece;
if isupper cond empty #king moved space #king:
def enemies filter lambda (regmatch "/[a-z]/"Â #1) pieces;
else:
def enemies filter lambda (regmatch "/[A-Z]/" #1) pieces;
endif;
for (from piece) fn enemies:
if fn #piece #from #king:
return #from;
endif;
next;
return false;
endsub;
It turns out that nofriends was never used by the subroutine. So I just deleted the lines that assign it a value.
Thanks Fergus.
How about samecase?
I was just updating my previous comment.
And the checked function is never used. Only the checked subroutine is used, and that doesn't have samecase in it. The checked function was a forgotten attempt to replace the checked subroutine with a function.
OK, thanks for the clarification.
But I give up. I'm following your suggestions, but the results are still not as expected.
Let me know when you entertain to create new onlyupper, onlylower, isupper and islower functions that only consider the first character; and I will try to update the presets again.
Wouldn't the best answer be to just create custom piece sets for Makruk? Then the pieces can all be represented by appropriate single-character notation. And if the different Makruk piece sets are added to a group, then each player can play with the piece set of his choice without affecting the other player. (And, of course, circumvents the current issue.)
Yes, this is what people should be doing. The alfaerie-many set was not started by me, and I do not endorse its use or recommend using its arcane notation for pieces. I keep it around only because some games do use it.
In fact, now that I realize this is just Makruk and not some weird variant of it with new pieces, I should point out that presets should not be made simply for the sake of using different graphics. That's what piece sets are for. Use of the alfaerie-many set may give freedom of choice to the designer, but it robs it from the players. For a game like Makruk, it is best to use standardized single-letter notation and to provide multiple sets to suit different preferences.
OK, Thanks.
Having said that, not being able to do what I was trying to do for Makruk takes away the ability for players to develop automated presets for variants that may use these non-totally-alpha pieces. (P180, b180, etc.)
Right now the curent set of functions just do not easily support writing rules for presets that mix pieces that have non alpha chracters, with others that don't.
If I had a new variant that used regular pieces and a silver general (S! and s!), I would have the same problem, or be forced to use a diferent piece.
The four functions that I have been suggesting would make a vast amount of code already written totally reusable for a wide variety of applications.
The point is that piece labels never have to have non-alpha characters, because you can always make a set that assigns whatever piece images you want to entirely alphabetic notation. The use of non-alphabetic notation is an artifact of one set trying to include way more than 26 pieces. It is not an inherent quality of the pieces that the alfaerie-many set used non-alphabetic characters in its notation. They are just images assigned to particular notation by a set file.
OK Fergus.
I'll create a new Alfaerie-Makruk piece set.
The alfaerie-many set was not started by me, and I do not endorse its use or recommend using its arcane notation for pieces. I keep it around only because some games do use it.
I agree that Alfaerie-many should not be used for established games for a couple of different reasons, but I'm still glad it's available. Sometimes we're just experimenting with ideas or playtesting them. Frequently when I'm working on a new idea, I'll use Game Courier to lay out the pieces and move them around by myself. For this purpose, alfaerie-many fits the bill perfectly. It's also the only good way (so far as I know) to see all the pieces available so I know if I need to draw a new one or not. Without that, I could be duplicating effort. Actually, for all I know there could be more Alfaerie pieces out there that aren't in the many set, but they might as well not exist, since I'd never find them.
P.S. I sent you an email. Thanks :)
24 comments displayed
Permalink to the exact comments currently displayed.
I just corrected an error in this tutorial. It previously displayed Post-Game code that would fail to find legal moves in some instances. This has been replaced with code that works every time.