Comments/Ratings for a Single Item
Fergus, I am having problems with the *ask* command. It seems to end up in an eternal loop. When I choose an alternative it merely asks again. I even use a constant to prevent eternal loops, but it doesn't help. (In the following code I use 'skip' for testing purposes): [...] elseif equal moved K; set legal or checkleap origin dest 1 1 checkleap origin dest 1 0; if var legal; if and equal dest c1 equal #wcastletest 0; unsetconst wcastletest; setconst wcastletest 1; if or and equal origin b1 and equal @ space d1 equal R space a1 and equal origin d1 and equal @ space b1 equal R space a1; ask 'Do you want to castle long?' 'y' 'skip' 'n' 'skip'; endif; endif; else; [...] endif; endif; Nor can I get 'askpromote' to work. This generates an eternal loop: if and var legal equal rankname dest 8; askpromote Q R B N; endif; /Mats
Now that I think about it, constants will not work in solitaire mode, because it never writes anything to a log. I am going to work on including constants in the forms that pass variable values. In the meantime, you might write your code to check the contents of the move, which you can check with the thismove keyword in an expression. Since the ask command will append to the move, all you have to check is whether the move is complete. For example, if your short and long castling moves differ on the position the Rook moves to, check the move for a Rook move, calling on ask only if the Rook move isn't present. Doing it this way also stops ask from being used when a player manually enters in the full move.
It looks like I now have constants working in solitaire mode. Still, it can be more effective to test whether ask is required by checking whether the move entered by the player is incomplete. This keeps it from unnecessarily calling ask when it isn't needed. And once the move is completed, it wouldn't have to call ask again.
Thanks, but you really must explain this better in the documentation about ask and askpromote, otherwise it will be an eternal source of frustration. /Mats
Fergus, are you certain that you haven't compromised the function of certain presets now that you have changed how constants function? Today I discovered that my Fischer Placement Chess preset has stopped working. I make use of a constant in it (however, I can change that to a variable). /Mats
Good, however I can make do without constants. My Fischer Placement Chess works excellently now, with automatic pawn promotion, castling, et al. /Mats
isn't randomized. It is a manual method of generating 25 Chess960 positions.
However, I again inserted the old code, which uses a constant. And it has
ceased working. I then changed this constant to a variable, and it works
again.
I suggest that you revert to the old way of how constants function. There
might be many presets that have stopped working now.
The way in which I used the constant is this: I first, in the precode, make
setconst plyturn 1;, then I call unsetconst plyturn; setconst plyturn 2;,
etc., and increment plyturn in order to keep count of which turn it is.
This simple method doesn't work anymore. (I just happened to use it
because you recommended constants in the problems with the ask command.)
/Mats
Okay, I programmed Chess - Test to count plyturns, and after making a few changes to how constants work, I got it to work. You can try it before I change the code to something else. Let me know if it works the same as yours.
Yes, that was how my plycount worked, and it obviously works now. Thanks. /Mats
Fergus, what are these commands 'continuemove' and 'redomove' in the Developer's Guide? They don't seem to be implemented yet(?) /Mats
Twinmove Chess (compulsory) and Twinmove Chess (uncompelled)
These are two attractive presets now, much easier to handle. And
these double-move variants are really interesting.
/Mats
I have just added support for the three-times repetition rule in Chess. When a player creates the same board position for the third time, and all the same moves are available, as in castling and en passant conditions are the same, then the game ends in a draw.
Here is how it is done. At the end of each post-move section, a variable representing the current state of the game is incremented, using code like this:
set posvar join "w" join fencode boardflags; inc #posvar;
In the post-game section, the variable name for the current state of the board is computed, and its value is compared with 3, using code like this:
set posvar join "w" join fencode boardflags; if >= var #posvar 3: say Three Times Repetition! Drawn Game!; drawn; endif;
The code I've shown is for White. For Black, substitute "b" for "w".
I wrote the boardflags operator today. It returns an ordered string of all the flags that are turned on and whose names match coordinate positions. The variable posvar gets set to a long string that will be used as a variable name. #posvar returns the value of posvar, and var #posvar returns the value of the variable whose name is stored in the variable posvar.
I have just added support for the 50 moves rule in Chess. Here is how it was done. I created a counter called nopvc, which means no Pawn or capture, and set it to zero. Whenever a Pawn moved or a piece was captured, it got reset to zero. Otherwise, it got incremented by 1. In the post-game part, I compared its value with 50. This is done after checkmate and stalemate are checked for just in case the 50th move resulted in a checkmate. Also, I realized I was using a global variable for posvar in the code for enforcing three-times repetition. So I removed the code in the post-game part for computing the value of posvar. The value it needs to be has already been set the last time posvar was given a value.
The Chess2 include file is now updated to use a stalemated subroutine that records all legal moves, which allows Game Courier to display the legal moves for a piece when a player clicks to move it. This does not affect the main Chess preset, but it does affect other presets that use the Chess2 include file, such as Hexagonal Chess and Caissa Britannia.
I'm currently working on updating the chess include file to store legal moves for onclick display, but until I get it working, Chess and many other games using this include file may not work properly.
The chess include file is now storing legal moves. To do this, it has had to become less optimized than it used to be. It is now more like the chess2 include, the main difference being that is still uses a specialized function instead of a generalized subroutine to check whether the King is in check. This is more efficient but needs to be changed for games with additional pieces. The functions in the include file cover all pieces in Chess plus the Marshall (K+R) and Archbishop (K+B). While this is working for Chess, I may have to continue working on it later to get it to work right with other games that do castling differently. For the time being, I will leave in old functions and subroutines that might be used in presets or include files that include this one.
I seem to have gotten it to work now. I changed
def P remove #ep checkleap #0 #1 1 1 and == var ep join filename #1 rankname #0 or and checkatwostep #0 #1 0 1 0 1 == rankname #0 #wpr or checkleap #0 #1 0 1 and empty #1 or and islower space #1 checkleap #0 #1 1 1 and > rank #1 rank #0; to this def P remove var ep and checkleap #0 #1 1 1 and == var ep join filename #1 rankname #0 or and checkatwostep #0 #1 0 1 0 1 == rankname #0 #wpr or checkleap #0 #1 0 1 and empty #1 or and islower space #1 checkleap #0 #1 1 1 and > rank #1 rank #0;
Remember that Game Courier reads all of this backwards, and this is just one of two Pawn functions. The first change I made was to the logic of the function. I put an and in front of the second to last operation, checkleap #0 #1 1 1
, so that nothing would be left on the stack when it got to the last operation. Since it still didn't work, I changed #ep
to var ep
. That worked. Now, why would I need var ep
but get away with using #wpr
. The difference is that wpr is effectively a constant, keeping the same value throughout execution of the program. So, when I define the function, wpr
already has the value I will need it to have whenever I use the function. But ep
is a true variable whose value keeps changing. To make sure the function uses its current value, I need to use var ep
instead of #ep
.
The remove
built-in function is a new one for removing a piece from a space. It exits automatically with the value of an assignment to '@'. Most built-in functions do not change anything, focusing instead on returning values. But I wanted to check possible Pawn moves with a function alone instead of using a subroutine.
I changed #wpr and #bpr to var wpr and var bpr, because these values might be changed by a preset that uses the chess include file. As a general rule, you should use the var operator to get the value of a variable in an expression, because using # plugs the current value directly into the expression, but a function may be used multiple times when a variable has different values.
25 comments displayed
Permalink to the exact comments currently displayed.