Check out Symmetric Chess, our featured variant for March, 2024.


[ Help | Earliest Comments | Latest Comments ]
[ List All Subjects of Discussion | Create New Subject of Discussion ]
[ List Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Comments/Ratings for a Single Item

EarliestEarlier Reverse Order LaterLatest
Game Courier Developer's Guide. Learn how to design and program Chess variants for Game Courier.[All Comments] [Add Comment or Rating]
Aurelian Florea wrote on Wed, Oct 31, 2018 07:39 PM UTC:

Ok, thanks !


🕸📝Fergus Duniho wrote on Wed, Nov 27, 2019 04:17 PM UTC:

It looks like the documentation for copyfn had been incorrect. It had said the new name could go on the left. But like with copy, the new name goes on the right, and the name of what is being copied goes on the left. Since this is how I prefer it to work, I'm glad the mistake was in the documentation, not in the code for the command. That means I can correct the documentation without breaking any code.


Aurelian Florea wrote on Mon, Feb 24, 2020 08:13 AM UTC:

@Fergus,

Hello!

In the chess2 include file what is the sub castlepos supposed to do?


🕸📝Fergus Duniho wrote on Mon, Feb 24, 2020 05:21 PM UTC:

It is used to evaluate possible castling moves without producing error messages. If you search for it, you will find it being used in the stalemated subroutine.

 


Aurelian Florea wrote on Mon, Feb 24, 2020 05:24 PM UTC:

Fergus, thanks. I was missing it.


Aurelian Florea wrote on Tue, Mar 10, 2020 12:37 PM UTC:

Fergus,

I have 3 things I'm needy about and can't do. These are not questions as if it would only be about some sideway task I could ask you and do it myself, but things to take a look if you have the time.

1. fast castle subroutine. Fast castle means castling in any place between rook and the king with the rook moving to the king's place. A pseudocode would be:

if the king and rook have not been moved

then if the destination field is empty 

then if the king is not in check then move the king to destination, move the rook to source.

2. lyon movement code for chu shogi. Chu shogi is not that different of orthodox chess and it's implementation should be rather mundane. The only problem is the lyon. This seems to me over my current ability.

3.movement code for the joker (also, jester, fool, imitator). This piece imitates the last move of the opponent. For years I'm thinking about it, but just observing the it has to do something with the moved variable was not much from me. I need that for apothecary chess which is a mouth full anyway, so I'd really apreciate your help.


🕸📝Fergus Duniho wrote on Tue, Mar 10, 2020 06:30 PM UTC:

I was recently thinking about how to do a Chameleon piece with the new fairychess include file, though I haven't done anything yet. Here's what could work. Use a global variable to keep track of the last piece moved by the previous player. For example, put "set lastpiece $moved;" at the end of the Post-Move sections. Then define the piece like so:

def Joker fn const alias #lastpiece #0 #1;
def Joker-Range fn join const alias #lastpiece "-Range" #0;
If you're not using aliases for any pieces, you can omit the "alias" keyword. For earlier include files, the principle would be the same, but the code would be different.


🕸📝Fergus Duniho wrote on Tue, Mar 10, 2020 08:35 PM UTC:

I don't yet have a clear idea of what you mean by fast castling. Are the King and Rook just swapping places? If that's what's going on, Game Courier has a swap command that should prove useful.


🕸📝Fergus Duniho wrote on Tue, Mar 10, 2020 08:41 PM UTC:

I don't play Chu Shogi, but I'm aware that the Lion moves twice. I have programmed Marseillais Chess and Extra Move Chess, which both allow double moves more generally. These include the ability to prompt the player for a second move before completing that player's turn. While I have programmed double moves on the scale of a whole game, I have not done it for an individual piece. You might have to program the game in general to handle double moves by a single piece.

Actually, I have done this for Pawn promotions in Chess. So, you might be able to do it for the Lion more easily than I thought. You want to look into the continuemove command.


Greg Strong wrote on Wed, Mar 11, 2020 12:49 AM UTC:

"Fast castling" isn't just the King and Rook changing places - the Rook goes to the King square but the King can go anywhere in between so long as it is not attacked.  But squares in between can be attacked and need not even be empty.

This comes from Kevin Pacey's Waffle Chess.  Here is his description:

A king that has never moved, and is not in check, can 'leap' once a game, along the first rank, to any unattacked empty square between it and an unmoved rook, followed by said rook 'leaping' to the king's initial square so as to complete castling in one single move. It does not matter if any squares in between are occupied or under attack.


🕸📝Fergus Duniho wrote on Wed, Mar 11, 2020 01:25 AM UTC:

The difficulty in programming fast castling is that a King might castle by moving just one space, and that needs to be distinguished by a regular King move. When this has come up in other games that allowed the King to castle by moving one space, the solution was to give that castling move to the Rook.


Aurelian Florea wrote on Thu, Mar 12, 2020 09:51 AM UTC:

Thanks Fergus for the input and Greg for the clarification!....


H. G. Muller wrote on Fri, Mar 13, 2020 08:08 AM UTC:

Just an idea: some chess GUIs allow 'reverse' entry of moves, by first clicking the destination square, and then the piece that should go there. (Usually in combination with some 'auto-complete' mode, where the move is executed immediately if only a single piece could reach the clicked empty square, and pieces that you click move immediately if there is only one place they could go.)

If you would in general allow the origin and destination of a move to be swapped, the difference could in exceptional cases (such as fast castling) be given a special meaning. Such as the reverse order (empty square x King) would indicate the castling, and move the Rook as a side effect.


🕸📝Fergus Duniho wrote on Fri, Mar 13, 2020 02:35 PM UTC:

Something like that would make it easier to do fission moves in Fusion Chess. However, what you suggest for one-space castling would also require a difference in notation between the two moves.


🕸📝Fergus Duniho wrote on Fri, Mar 13, 2020 08:23 PM UTC:

So far, I have programmed the square-table rendering method to handle moves by entering the destination first. It works like this. When you click or tap on the destination first, it highlights the pieces that can move there. If you then click or tap on one of those pieces, it will then complete the move. But no matter what order you begin in, it will put the notation in the correct order. So, this doesn't change what notation can be entered through clicking or tapping.


H. G. Muller wrote on Fri, Mar 13, 2020 11:08 PM UTC:

Indeed, this is how it should normally work. Notation should be unique. But if this mechanism is used as a kludge to indicate a move has a possible side effect, you could leave the squares swapped in the notation to indicate that side effect.


🕸📝Fergus Duniho wrote on Sat, Mar 14, 2020 12:13 AM UTC:

There is already a simple solution available, which is to give the castling move to the Rook when the King moves one space. It's best to not allow players to enter reverse notation with mouse clicks, because it would rarely have any use, and it would more frequently just mess up regular moves. Also bear in mind that the JavaScript used to make moves is a simple client-side mechanism that cannot connect with the server-side code used for enforcing rules except by submitting a form. It does not have the rules programmed into it, and it has to operate on its own, its only data being a list of legal moves and a representation of the board.


H. G. Muller wrote on Sat, Mar 14, 2020 09:49 AM UTC:

Ah yes, you are right! In fact this is what Jocly uses, in Wildebeest Chess. That is for free castling, but it would be equally suitable for fast castling.


🕸📝Fergus Duniho wrote on Sat, Mar 14, 2020 05:19 PM UTC:

Now that you mention it, that's the game I did it that way for with Game Courier.

I have made a few tweaks to how clicking on an empty space first works. When there is only one legal move to that space, it highlights that space, fills it in as a move by the piece that can move there, and let's you complete the move by clicking on the same space again. To cancel the move, click on the piece rather than on the space. If multiple pieces can move to the same space, it highlights each of them, and you have to complete the move by clicking on one of them. You can cancel the move by clicking on any empty space.


🕸📝Fergus Duniho wrote on Sat, Mar 28, 2020 02:02 AM UTC:

I removed thespaces, since I couldn't find any use of it. Unlike spaces, which returned the keys to the $space array, it returned the $space array itself. In place of it, I made $space a readable and writable system variable.

I removed the answered operator and made $answered a readable and writable system variable. This variable gets set by ask and askpromote when they are answered. It is useful for writing code that stops asking the same question again and again after it has already been answered. I am going to update the White_Pawn and Black_Pawn functions to use it, so that I don't have to resort to the kludge of inserting "P-dest" or "p-dest" when a Pawn doesn't promote.

I just documented the baseurl operator. It returns the baseurl of the the Game Courier script.

I added and just documented the capturedpieces operator. This calculates and returns an associative array of the currently captured pieces. This replaces the use of $capturedpieces as a readable system variable with the system operator. It may still be overwritten with setsystem though, and it may also be accessed as a variable with a dollar sign before it. But this will return a value only if it has already been set, since Game Courier does not set the $capturedpieces variable until it has run through all the moves in a game.

 


Aurelian Florea wrote on Sat, Mar 28, 2020 01:45 PM UTC:

Fergus,

In the fairy chess file you write for the charging knight :

def Black_Charging_Knight cond > rank #0 rank #1 (checkleap #0 #1 1 2) (checkleap #0 #1 1 1 or checkleap #0 #1);

Is it the case that you missed the directions (1 0) for the final case?

def Black_Charging_Knight cond > rank #0 rank #1 (checkleap #0 #1 1 2) (checkleap #0 #1 1 1 or checkleap #0 #1 1 0);


🕸📝Fergus Duniho wrote on Fri, Apr 3, 2020 05:46 PM UTC:

I modified cond to work properly, and I updated the section on recursive functions. Since cond mimics the operation of ?: in PHP, I had written it using ?:. I rewrote it using if and else, and it is now able to work in recursive functions, because it no longer evaluates code that it shouldn't evaluate.


🕸📝Fergus Duniho wrote on Mon, May 25, 2020 12:46 PM UTC:

There are two ways of getting the value of a variable. One is to prepend the variable name with the # symbol. This works by replacing the #var_name with its value during preprocessing. This is useful for commands that do not provide any evaluation of expressions. It can be used on any line, regardless of the command.

The other way works only in expressions, and it is to precede the variable name with the keyword var. In some instances, it doesn't matter which you use. But in function definitions it does. Consider these lines of code:

def test1 join "a" #v;
def test2 join "b" var v;
print fn test1;
print fn test2;
set v x;
def test3 join "c" #v;
print fn test1;
print fn test2;
print fn test3;
set v y;
print fn test1;
print fn test2;
print fn test3;

Here is their output:

a#v

b

a#v

bx

cx

a#v

by

cx

As you can tell from examining the output, the method of prepending a variable name with # works only when a function is defined, and it will insert the current value of that variable into the function definition without enabling the function to use the most recent value of the variable on subsequent function calls. But the var keyword will always retrieve the current value of the variable everytime the function is called. For this reason, it is important to use the var keyword in function definitions whenever there is any chance that its value may change. The preprocessing method of retrieving variable values may be used in a function definition only for variables that have already been set and will not change.

The same should apply to prepending constant names with @ or prepending system variables with $. You're probably okay prepending a constant name with @, because its value is not supposed to change. Some system variables change regularly, and some do not. For those that do change, it is better to use the system keyword to retrieve their value in function definitions.


Aurelian Florea wrote on Sun, May 31, 2020 08:56 AM UTC:

I cannot find the definition of where here, as it is used in the definition of griffin and aanca.

Edit I have found it now. Sorry for the spam :(!


🕸📝Fergus Duniho wrote on Thu, Jul 23, 2020 09:25 PM UTC:

I fixed a bug in the pop command. When it pops off an array element from an array, it is supposed to remove it from the array, not just copy it to a variable. I fixed it so that it will modify the array when it pops off a value.


Greg Strong wrote on Fri, Jul 24, 2020 12:46 AM UTC:

I'm making a rule-enforcing preset for Shatranj Kamil X and I'm almost done but for one minor annoyance I don't understand.

In addition to pawn promotion, the Ferz also automatically promotes to a W on the last rank.  So, in Post-Move I added:

if and == $moved F == rank $dest 9:
  add W $dest;
endif;

This works fine, except that after the promotion, it shows the Ferz in the "captured pieces" which isn't really accurate.  So I added a line:

if and == $moved F == rank $dest 9:
  add W $dest;
  setelem capturedpieces F dec elem F capturedpieces;
endif;

I think this should work but it does not...  Any thoughts appreciated.


🕸📝Fergus Duniho wrote on Fri, Jul 24, 2020 02:31 AM UTC:

I changed subroutines to copy arguments as my variables instead of local variables. This removes the ability of child subroutines to see the arguments passed to parent subroutines. I made this change for the following reasons:

  1. my scope variables are accessed more quickly than local scope variables.
  2. I never made use of the ability that treating arguments as local variables conferred.
  3. This ability would be useless in recursive subroutines, since a recursively called subroutine will have the same parameters as its parent subroutine.
  4. Using this ability makes code harder to follow. It is usually keeps things clearer when you pass as arguments the specific values that a subroutine needs.

[Edit: While three of the reasons still apply, it turns out that I did previously make use of the ability of child functions to see arguments passed to parent subroutines. This broke some code, and I switched it back to how it was.]


🕸📝Fergus Duniho wrote on Fri, Jul 24, 2020 02:38 AM UTC in reply to Greg Strong from 12:46 AM:

The capturedpieces array is generated automatically after all moves have been played through. So, it is not available for you to tinker with in the code. Instead, you have to construct the entire capturedpieces array. When you have already created it in your code, it doesn't get automatically generated from your final game position.


Greg Strong wrote on Fri, Jul 24, 2020 02:42 AM UTC:

Ok. After reading this comment I was wondering how it was that promoting a pawn in Chess doesn't make the pawn a "captured piece", but it turns out that it actually does (and I just never noticed). So I guess I do not need to worry about this since the behavior of promoting the ferz is consistent with how pawn promotion works.


🕸📝Fergus Duniho wrote on Tue, Aug 4, 2020 02:13 AM UTC:

Here's a result I find surprising. First the code I ran:

def countdown fn countdown dec #0 onlyif #0;
def coontduwn fn coontduwn dec #a onlyif #a =a;
sub countdown cnt:
  if #cnt:
    return sub countdown dec #cnt;
  else:
    return #0;
  endif;
endsub;
stopwatch reset;
print fn countdown 10000;
stopwatch;
stopwatch reset;
print fn coontduwn 10000;
stopwatch;
stopwatch reset;
gosub countdown 1000;
stopwatch;
stopwatch reset;
set a 10000;
do while #a:
  dec a;
loop;
print #a;
stopwatch;

Then the results:

0

Elapsed time: 0.12341594696045 seconds

0

Elapsed time: 0.14718699455261 seconds

Elapsed time: 0.50130391120911 seconds

0

Elapsed time: 0.17237901687622 seconds

The first two tests show that function recursion is slightly faster with native subroutine variables instead of with user variables. That's not surprising, because there is more overhead in using user variables.

It's also not surprising that function recursion is faster than subroutine recursion. Though I do wonder why it's by such a high margin. I had to reduce the countdown by a factor of 10 just to test subroutine recursion speed, and it still took more time than function recursion. While using a user variable may be a factor, it is even slower than the coontduwn function that uses user variables.

What is surprising is the last result, which shows that a do loop was slower than function recursion. The countdown is the same, but the loop took more time.


🕸📝Fergus Duniho wrote on Tue, Aug 4, 2020 02:28 AM UTC in reply to Fergus Duniho from 02:13 AM:

The do while loop calls the same PHP function as function recursion does each time it iterates the loop, because it uses it to evaluate the expression after while. Plus, it has a bit more overhead for operating the looping mechanism. So, that may explain why it's slower.

I just added this code:

stopwatch reset;
foreach a fn range 0 10000:
next;
stopwatch;

And it got the fastest result:

Elapsed time: 0.039952039718628 seconds

It saved a lot of time by never trying to evaluate a as an expression.


🕸📝Fergus Duniho wrote on Tue, Aug 4, 2020 01:27 PM UTC in reply to Fergus Duniho from 02:13 AM:

Since the subroutine had a wrong variable name in it, I did it again and got slightly better results. First, the corrected code:

sub countdown cnt:
  if #cnt:
    return sub countdown dec #cnt;
  else:
    return #cnt;
  endif;
endsub;
stopwatch reset;
gosub countdown 1000;
stopwatch;

Then the result:

Elapsed time: 0.50052809715271 seconds

Trying again with var instead of #:

sub countdown cnt:
  if var cnt:
    return sub countdown dec var cnt;
  else:
    return var cnt;
  endif;
endsub;
stopwatch reset;
gosub countdown 1000;
stopwatch;

Elapsed time: 0.51695919036865 seconds

This slowed it down slightly. The curious thing is that #cnt calls evalvar() first, and this then calls getuservar(), whereas var cnt calls getuservar() directly. Based on this, I was expecting it to be faster. Factors that could explain the opposite result are #cnt is handled while parsing the line, while var cnt is handled by evaluating an expression, and var cnt is a longer string than #cnt, which means reading the line takes longer.

Trying var cnt with a function:

def countdown fn countdown dec var a onlyif var a =a;
stopwatch reset;
print fn countdown 10000;
stopwatch;

Elapsed time: 0.20279908180237 seconds

This also slowed things down, and it was by a lot more compared to the earlier result, which was 0.14718699455261. In the function for evaluating polish notation expressions, evaluation of prepended variables is handled before operators, but the extra line parsing shouldn't make as much of a difference, because the function definition is executed only once.


🕸📝Fergus Duniho wrote on Sat, Aug 8, 2020 12:50 AM UTC:

I added a section on Control Flow in Functions.


H. G. Muller wrote on Sat, Aug 8, 2020 05:23 AM UTC:

I have some problems using sort. I have an array sqrs with 3 squares in it, and want to know what the middle square is. I had expected this could be done by

set sqrs sort #sqrs;
set middle elem 1 #sqrs;

This does not work, however. If I do printr sqrs; before and after the sort, the order of the elements is altered. But the order of the keys (0, 1, 2) is altered too, so that each element is still associated with the same key. And elem apparently retrieves the elements by key, so elem 1 #sqrs is still the same as it was without the sort.

Array
(
    [1] => a1
    [0] => e1
    [2] => h1
)

How can I retreive the e1 from the above array, if I do not know its key, but only that it is the second element?


H. G. Muller wrote on Sat, Aug 8, 2020 02:26 PM UTC:


I have now implemented shuffling for the Applet-generated rule-enforcing GAME code. Because this involved some subroutines that could be of general use, I placed the code in a separate include file, which can also be included in hand-crafted presets, through:

include /membergraphics/MSply-test-applet-for-chess-variants/shuffle.txt;

To make the variant into one with a shuffled initial position, one then only has to specify (in the Pre-Game section) an array of what pieces have to be shuffled, and call the master shuffling routine. E.g.

set shuffleset (B N Q);
gosub ShuffleSetup;

would randomly shuffle all Bishops, Knights and Queens. Black would normally be shuffled the same way as white, unless you specify a shuffle for black separately:

set shuffleset (B N Q);
set blackshuffle (b n q);
gosub ShuffleSetup;

would independently shuffle the white and black pieces.

There are some ways to restrict the shuffle, for instance for the purpose of ensuring the Bishops stay on opposite shades. For that purpose there are some extra arrays you could specify. In particular, piece types mentioned in the array 'shaded' will be kept on the shade they were orignally on. In that case those pieces should not be mentioned in the shuffleset. E.g.

set shuffleset (N R Q K);
set shaded (B);
gosub ShuffleSetup;

If black is to be shuffled independently, it must have its own 'blackshaded' for this purpose.

An even more severe restriction one can impose is that certain piece types must remain positioned (left-right) symmetrically. This is useful if you don't want to shuffle the King-side and Queen-side wings independently, but preserve the overall symmetry. E.g. to optionally cause swapping of the Bishops with King and Queen you can do:

set shuffleset (K Q);
set symmetrized (B);
gosub ShuffleSetup;

In orthodox chess this would then result in one of the back ranks RNBKQBNR, RNBQKBNR, RNKBBQNR or RNQBBKNR. Currently this mode of shuffling cannot be combined with shade-preserving shuffles; you should not define 'shaded' and 'symmetrized' both. The blackshuffle would use an equivalent array 'blacksym'.

There finally is a possibility to restrict the shuffle in such a way that one piece will end up between two others. For this an array 'centralize' has to be defined, with two or three piece types, the first of which must occur only once, and there must be exactly two of the others in the setup. That first-mentioned piece will then always end up between the two others. This is useful in Chess960, where we could do

set shuffleset (N R Q K);
set shaded (B);
set centralize (K R);
gosub ShuffleSetup;

So far for the simple applications. It is also possible to specify a complex sequence of shuffles. This is mainly intended for interpreting Pre-Game code generated by the Play-Test Applet. But it is not so complex that it is impossible to specify such a shuffle by hand. The idea is to provide an array of arrays 'shufflespecs', where each shuffle is specified by three consecutive elements of the 'outermost' array. These three elements are then used as the shuffleset, symmetrized and shaded settings for that shuffle step. If some of those are not needed, they should be set to 0. E.g.

set shufflespecs
( (A C)   // shuffleset 1
  (N)     // symmetrized 1
   0      // shaded 1 (absent)
  (Q A C) // shuffleset 2
   0      // symmetrized 2 (absent)
   0      // shaded 2 (absent)
  (N)     // shuffleset 3
  (B)     // symmetrized 3
   0      // shuffleset 3 (absent)
   0      // make symmetric
);

The final 0 requests that black's position should be the mirror image of white's. If you want to shuffle black independently, you must omit that 0. But then you would have to specify all the shuffle steps in the array also with black pieces, or black would not be shuffled at all. In the example (starting from the setup of Capablanca Chess) you would force swapping of the B and N on both wings, or leave them unaffected, to decide whether super-pieces go onto the b- and i-file or the c- and h-file. The second shuffle would then permute all three super-pieces over the assigned locations. Finally, the Knight and Bishop might be swapped on both wings, or not at all.

 


🕸📝Fergus Duniho wrote on Sat, Aug 8, 2020 05:15 PM UTC in reply to H. G. Muller from 05:23 AM:

Since it looks like you're the first person to use sort, I modified it to use sort() instead of natsort(), and I also modified it to read all remaining arguments as an array if the first argument is not an array. I also added the following functions:

asort
Sorts an associative array, preserving the keys. Takes only one argument, which should be an array.
natsort
Sorts an associative array in a natural order, preserving the keys. Same as sort used to be. Takes only one argument, which should be an array.
isort
Sorts an array in a natural, case-insensitive manner. Will sort remaining arguments if first one is not an array.
values
Returns the values of an array. Mainly useful for placing the values of an associative array into a numeric array.

H. G. Muller wrote on Sat, Aug 8, 2020 05:39 PM UTC:

Thanks. To be sure: for sorting square coordinates it would be best to use isort, so that a2 is sorted before a10? With the old sort I was finally able to work around the problem by using pop to access the elements; this did pop the elements in the reverse order as printr printed them. I was a bit surprised anyway that the array I tried to sort was treated as an associative array. It was created as a merge of two arrays that were built by repeated push.


H. G. Muller wrote on Thu, Aug 20, 2020 10:19 AM UTC:

To prevent mishaps like this (people not ticking "Do not include moves in code". I stressed this should be done in the tutorial, but failed to mention it in the instructions on the Appler page itself), I could of course make the move parser detect the condition of an empty origin and the mentioned piece already on the destination, and point out the user should still do this in the error message. And adapt the text on the Applet page. But it would be nice if it was not possible to make this mistake at all.

Can we get a GAME-code command or variable that would enable the program to 'tick' this option under program control? Presumably Game Courier uses some PHP variable as a boolean to indicate whether it should execute the input moves, and all that would be needed is allow access to that as a system variable. Then I could set that option in the Pre-Game code.


🕸📝Fergus Duniho wrote on Thu, Aug 20, 2020 04:37 PM UTC in reply to H. G. Muller from 10:19 AM:

Can we get a GAME-code command or variable that would enable the program to 'tick' this option under program control?

I wasn't sure it would work, because it goes into effect during the construction of the program, which happens before its execution. But when I tested it in solitaire mode, it did work. The system variable is called omitmoves, and you should set it to true. I recommend testing whether it will continue to work in logged games.


H. G. Muller wrote on Thu, Aug 20, 2020 05:33 PM UTC in reply to Fergus Duniho from 04:37 PM:

I noticed some behavior that seems to be new, and it doesn't seem intentional. Before, when I clicked a non-highlighted square as destination, I got a popup to ask whether I was sure I wanted to play an illegal move, and when I confirmed that, it submitted the move. I do this often to test whether the error messages my generic code gives are working and understandable. Now, however, when I want to step into check with my King, it complains "is not a valid square", instead of the expected  "This exposes your royal to check". Turns out the move that is submitted was "K c4-", i.e. the click on c3 (where I would be in check) had been ignored completely. (Except that it cause submitting of the move.)


🕸📝Fergus Duniho wrote on Thu, Aug 20, 2020 07:26 PM UTC in reply to H. G. Muller from 05:33 PM:

Now, however, when I want to step into check with my King, it complains "is not a valid square", instead of the expected "This exposes your royal to check".

Since these messages are from your own code, this is a matter for you to figure out yourself.


H. G. Muller wrote on Thu, Aug 20, 2020 07:38 PM UTC in reply to Fergus Duniho from 07:26 PM:

Sure, but there is no way the code could know what the error is if the JavaScript doesn't relay what square the user clicked. As far as the code is concerned, it gets an empty string, so of course that is not a valid square. How could it know the user tried to expose his king?


🕸📝Fergus Duniho wrote on Thu, Aug 20, 2020 08:22 PM UTC in reply to H. G. Muller from 07:38 PM:

If the JavaScript is doing something wrong, tell me in precise detail how I can replicate what you are doing and see the same results.


H. G. Muller wrote on Thu, Aug 20, 2020 09:14 PM UTC in reply to Fergus Duniho from 08:22 PM:

Basically you should be able to do this on any preset that hilights moves, but you could use Mighty Lion Chess. Select Move or Play. Click e2 (highlights on e3 and e4 come on). Click e5. You get a popup that complains this is not highlighted as legal, and asks if you want to play it Anyway. Click OK. The problem now is that it doesn't submit the requested "P e2-e5; it submits "P e2-".

Now it is a perfectly valid stance that you don't ever want to send "P e2-e5", because the highlghts give a strong indication that it will be illegal (and in this case it certainly is). But why the popup, then? Sending "P e2-" is not what the wanted to play, and is most certainly illegal. Better just ignore clicks on non-highlighted squares completely, in that case.


🕸📝Fergus Duniho wrote on Thu, Aug 20, 2020 10:24 PM UTC in reply to H. G. Muller from 09:14 PM:

The new behavior came about from the different way that it now handles legal moves. Instead of constructing the move, it searches for a matching legal move and sets the move to the matching legal move. But when no legal move was found, it would not set it to anything. I have now changed it to construct the move before looking for a match among the legal moves. If it finds a single match, it will overwrite the constructed value with the the match it found. But if it doesn't find a match, it will keep the constructed value. Since enforcing and showing legal moves usually requires some separate code, there can sometimes be a discrepancy between the legal moves that are enforced and the legal moves that are shown. Players are allowed to purposely enter moves that are not shown as legal as a way of getting around this when it happens.


H. G. Muller wrote on Fri, Aug 21, 2020 06:00 AM UTC in reply to Fergus Duniho from Thu Aug 20 10:24 PM:

Since enforcing and showing legal moves usually requires some separate code, there can sometimes be a discrepancy between the legal moves that are enforced and the legal moves that are shown. Players are allowed to purposely enter moves that are not shown as legal as a way of getting around this when it happens.

Indeed, I already thought this would be the purpose of the popup. The code in the betza.txt file could also suffer from such a discrepancy, because I am using a shortcut for testing legality of the moves to be highlighted, different from a full king capture test used on the move that is played, and there could be cases I overlooked where the shortcut is not entirely accurate. At the moment this is certainly the case for the anti-trading rules, (but that would cause illegal moves to be highlighted, not the other way around), and moves of an imitator (where the shortcut doesn't take into account yet that the move will be altered because of the one we want to test for legality).

Another thing I ust noticed:

The 'menu' page for a preset used to highlight moves for a piece that you clicked. (But you could not click a destination; then they simly went off again.) This no longer works, because there is no 'messagearea' on that page. Not that it would be useful to have one. But perhaps you should make the JavaScript test whether getElementById returns null, and make execution of the code that accesses it conditionally dependent on that, for otherwise it crashes the script.


H. G. Muller wrote on Fri, Aug 21, 2020 11:13 AM UTC:

The Mighty Lion and Odin's presets now use a slightly adapted version of movePiece JavaScript routine, which does take care of the highlighting after the list with remaining moves opens: it first clears all the highlights for the first leg, and then applies highlights to the destinations of a second leg, or to the squares where there are side effects. A third click on the board can then be used to select any of those, and submit the move (if it then is unique and legal).

I am a bit confused about how things work now. Do all moves have to be written in $extralegal, to get them in the legalList? Or do you somehow convert the moves submitted by the GAME code through setlegal to text, and add these to $extralegal to make the legalList? It seems the highlighting now is done completely on the basis of legalList, and that legalMoves is no longer used for any other purpose than to switch on the highlighting, by testing it against null. The Applet GAME code used to push some partial (first-leg-only) moves with setlegal (because there was no way to include the side effect there), just to make sure that the destination would be highlighted and available for clicking. (After which it would use continuemove to inquire about the side effect.) But this backfires now, because the JavaScript thinks these moves would be legal by themselves, leaving ambiguity when there is in fact none after the second click, and needlessly asking for a third.

If I can rely on highlighting in the future being purely done from $extralegal, I can refrain from writing anything to $legalmoves.

BTW, since you seem to synthesize the move texts from the square pairs given to setlegal, which you will have to do for backward compatibility, it might be better to extend the capabilities of setlegal to also accept multi-leg moves, so that there is a unified way to submit moves for highlighting. E.g. you could add to the specs that when the (only) argument of setlegal is an array, it will treat it as a multi-leg move. (You can still distinguish that from the other formats, which always have to start with a square.) The array could then be interpreted as a sequence of (from, to) pairs for each of the legs, from which a move text would be generated by concatenating them, using hyphens and semiclons as separators where appropriate. E.g.

setlegal (c6 e5 e5 d4 Q dest);
setlegal (e2 e7 @ e8 N e6);

would translate to "c6-e5; e5-d4; Q-dest" and "e2-e7; @-e8; N-e6", respectively. That would relieve the GAME code from constructing the text by itself.


H. G. Muller wrote on Fri, Aug 21, 2020 03:37 PM UTC:

And for something completely different:

I had this idea about moving the piece with JavaScript. In HTML-table or ASCII-art mode that would not be a problem. But it seems you have already overlayed the images that are used in JPG/PGN/GIF mode with an individually addressable set of (entirely transparent) empty squares, for the purpose of using their border as highlights. It should be possible to replace these images on the origin and destination square of the first leg by opaque ones of an empty square and a piece. It doesn't really matter if these had a deviating background color compared to the square they cover; this could be seen as a form of highlighting of the first leg, while the normal highlights now indicate possible destinations for the second leg.


🕸📝Fergus Duniho wrote on Fri, Aug 21, 2020 04:11 PM UTC in reply to H. G. Muller from 11:13 AM:

The Mighty Lion and Odin's presets now use a slightly adapted version of movePiece JavaScript routine, which does take care of the highlighting after the list with remaining moves opens: it first clears all the highlights for the first leg, and then applies highlights to the destinations of a second leg, or to the squares where there are side effects. A third click on the board can then be used to select any of those, and submit the move (if it then is unique and legal).

I'm working toward something that will do that, but I need to be able to test it with Mighty Lion Chess.

Do all moves have to be written in $extralegal, to get them in the legalList?

No, moves set with setlegal are converted to text format for legalList.

It seems the highlighting now is done completely on the basis of legalList, and that legalMoves is no longer used for any other purpose than to switch on the highlighting, by testing it against null.

That was an oversight. I have now changed that to legalList, so that the legalMoves array is no longer used for anything.

The Applet GAME code used to push some partial (first-leg-only) moves with setlegal (because there was no way to include the side effect there), just to make sure that the destination would be highlighted and available for clicking. (After which it would use continuemove to inquire about the side effect.) But this backfires now, because the JavaScript thinks these moves would be legal by themselves, leaving ambiguity when there is in fact none after the second click, and needlessly asking for a third.

I have already brought up this problem and its solution with you, but you ignored what I said. If you would add a move option with pass as the second part of the move, the player could choose that immediately, which would bypass the need for the player to complete the move on the next page. If you like, you could even remove the option that includes the move by itself without pass. Then the player would have to make a choice before continuing to the next page.

If I can rely on highlighting in the future being purely done from $extralegal, I can refrain from writing anything to $legalmoves.

Using $legalmoves ensures that everything will be written in a standard format. If you use only $extralegal, you should keep your notation standardized. For a standard move, this means the piece notation, a space, the origin coordinate, a hyphen, and a destination coordinate with no extra spaces. For a drop, this means the piece notation, an asterisk, and the destination coordinate. For a free drop, just replace the asterisk with a hyphen. Note that if you use aliases, the piece notation is the alias, not the label used as a key in $pieces.

since you seem to synthesize the move texts from the square pairs given to setlegal, which you will have to do for backward compatibility, it might be better to extend the capabilities of setlegal to also accept multi-leg moves, so that there is a unified way to submit moves for highlighting.

I'll think about that, but first I have to work on what I mentioned at the top.


🕸📝Fergus Duniho wrote on Fri, Aug 21, 2020 04:17 PM UTC in reply to H. G. Muller from 03:37 PM:

I had this idea about moving the piece with JavaScript.

I have plans down the line to make Play mode AJAX-driven. If that works out, it could be applied to the other modes. But I have more immediate things to work on right now.


H. G. Muller wrote on Fri, Aug 21, 2020 05:28 PM UTC in reply to Fergus Duniho from 04:11 PM:

If you would add a move option with pass as the second part of the move, the player could choose that immediately, which would bypass the need for the player to complete the move on the next page.

But it was not possible to pass a pass option to setlegal, one could only pass the first leg. I didn't know the moves in $extralegal were also used for highlighting; I thought they were just for the auto-completion. One problem is that at the moment a move without side effects is generated, there is no way knowing whether the same move with side effect will be generated later. And it would look silly to write every simple move as a 2-leg move with pass as second leg, especially if it happened in a game where there even aren't any multi-leg movers.

So even now that I know that the $extralegal moves are used for highlighting, by studying the JavaScript, I still have the dilemma of whether to push a move a-b simply as a-b, or as a-b; pass. I now solve that by letting the JavaScript highlight the destination of the first leg also as possible destination of the second leg to select a move without side effect, and have it add the pass to the move just before submitting it, when that move gets selected by a third click. And I refrain now from using setlegal on moves with side effects.

That moves for $extralegal must be in standard format is indeed an extra obstacle for the programmer (although I think I got it right). This is why I proposed to use setlegal also for multi-leg moves, so that it can generate the standard format. What holds for simple moves holds to an even larger degree for multi-leg moves.

I'm working toward something that will do that, but I need to be able to test it with Mighty Lion Chess.

If you clone the Mighty Lion preset by saving it to another settings file, you won't copy the JavaScript with it. You can then use it to test your own JavaScript. Same with Odin's Rune Chess.


🕸📝Fergus Duniho wrote on Fri, Aug 21, 2020 09:26 PM UTC in reply to H. G. Muller from 05:28 PM:

So even now that I know that the $extralegal moves are used for highlighting, by studying the JavaScript, I still have the dilemma of whether to push a move a-b simply as a-b, or as a-b; pass. I now solve that by letting the JavaScript highlight the destination of the first leg also as possible destination of the second leg to select a move without side effect, and have it add the pass to the move just before submitting it, when that move gets selected by a third click.

This is a kludge that I wish to avoid. If the legalList includes a move by itself, and it includes that same move as the first part of multi-part moves, but none of these have pass as the second part, there are three possible interpretations of this, and it does not know how to rule between them. One interpretation is that an incomplete move is being allowed, and a continuation will be required on the next step. The second interpretation is that it is a complete legal move by itself. The third interpretation is a mishmash of the first two. It is that it is an incomplete move as written, but adding pass as the second part will make it a complete legal move. For the first two interpretations, it would not be appropriate to add pass. It is only for the third, which happens to be the case for games your applet has programmed, where it would be appropriate to add pass.


🕸📝Fergus Duniho wrote on Sat, Aug 22, 2020 01:49 AM UTC:

I have made a major update to movepiece.js. It can now highlight the proper spaces for the subsequent parts of multi-part moves. In general, players may click spaces in any order, and it will narrow down the legal moves to those that include all of the spaces clicked on. In the event that a shorter move is part of longer multi-part moves, or a multi-part move returns to its destination, clicking on a space a second time will indicate that this space must be the final destination of the move. Clicking on the same space twice will deselect a move only when it is the second click. To cancel a move beyond that point, you can click the Cancel button on the requester that lists multiple move options.

It now uses a single showLegal() function instead of the two functions showLegalTo() and showLegalFrom(). I will delay removing them until tommorow, since H.G. currently has code that is using them. One of the main differences from H.G.'s code is that it will not arbitrarily add "pass" to a move. It works with the legal moves provided to it in legalList, and it does not make any assumptions about there being other legal moves outside this list. Another difference is that it should handle multi-part moves with any number of different coordinates. H.G.'s code can handle multi-part moves with up to three different coordinates.

In the event that a third or later click results in no legal move, it will try to submit the move it has constructed. If this is an exact match for a legal move, it will automatically submit it. If it is not, it will ask the player if he wants to submit it. This allows a player in Fusion Chess who is prompted with both a standard move and a fission move, for example, to play the standard move by clicking the board again.


H. G. Muller wrote on Sat, Aug 22, 2020 06:02 AM UTC in reply to Fergus Duniho from Fri Aug 21 09:26 PM:

One interpretation is that an incomplete move is being allowed, and a continuation will be required on the next step. The second interpretation is that it is a complete legal move by itself. The third interpretation is a mishmash of the first two. It is that it is an incomplete move as written, but adding pass as the second part will make it a complete legal move.

The way I look at it is that it is a legal move by itself, but that pass sometimes has to be added to 'complete' it, as a kludge to tell that to the GAME code and prevent the infinite loop. And this problem is self-inflicted, by a mismatch between the GAME code and the JavaScript. With the enhanced JavaScript there never is a need to submit incomplete moves. But with the old JavaScript it could not be avoided (other than by typing) that a spurious (partial) move would be sent after entering the first leg, and the GAME code would have to be prepared to deal with that, using continuemove to ask for a second leg, with the risk for an infinite loop if there was none. Even in that setting adding of the pass could have been avoided by having the GAME code set a 'constant' that would enable it to distinguish between runs without or after a continuemove, like $answered allows it to distinguish between a run before and after deferring a promotion choice.

So perhaps I did indeed adopt a cumbersome solution; the logical one would be to simplify the Post-Move code to consider simple moves always complete, and never use continuemove on them. That would exclude interpretation 1, and thus also 3. As it is now I am using one kludge (in the JavaScript) to work around another (in the Post-Move GAME code). As long as the old JavaScript is still around, though, I don't want break my GAME code for working with it.

From the POV of the JavaScript there still will have to be some way the user can indicate whether he is done entering the move, when the legalList indicates that there is an optional continuation. Clicking the last-clicked square a second time (and hence making sure it is highlighted) is the natural way to indicate that. It is the only click that cannot possibly indicate the location of a new side effect.

 


H. G. Muller wrote on Sat, Aug 22, 2020 06:50 AM UTC in reply to Fergus Duniho from 01:49 AM:

I will delay removing them until tommorow, since H.G. currently has code that is using them.

OK, thanks, I have grabbed them now from movepiece.js so I can put them in an adapted script if needed.

I tried the new JavaScript in Mighty Lion. If the Lion captures an adjacent Pawn (l d6-e5) by clicking the latter twice, the move is submitted, but the Post-Move code does ask for a second leg because no pass was appended. Based on the reasoning in the previous comment, this should be considered as a flaw of the Post-Move code, though; it should just have accepted the move. Then this would have worked fine.

More serious is that when I try to play a distant Lion move beyond the Pawn (e.g. l d6-e4) it does not immediately accept the move, but still wants me to choose between the simple move and "l d6-e5; l e5-e4", highlighting both e4 and e5 to make that choice. This is a consequence of the "any order" policy, rather than using the order of entry of clicks 2 and 3 to distinguish between the shooter and the multi-mover case. Highlighting e4 and e5 here would have been desirable for the Forest Ox (a shooter, which would have indicated that by specifying the move as "l d6-e4; @-e5", requesting click order d6-e4-e5). The Lion is a multi-mover, though, and should have required d6-e5-e4 for taking the Pawn, while d6-e4 should already have been an unambiguous expression of the desire to not take the Pawn.

For me that issue is still important enough to prefer my own adaptation of the JavaScript. In connection with that I have some questions:

  • Currently the JavaScript array legalMoves[] is still on the Game Courier pages, and my adapted version, as well as some JavaScript embedded in the page that decides what the "How to move pieces" section should say still test for its presence. But since the new movepiece.js does not refer to it at all, I suppose it is scheduled for removal. Is it safe to assume that all future scripts will define legalList as null for presets that do not show legal moves, and that I should test that?
  • Would it be possible for an editor to rename the file /membergraphics/MSgame-code-generation/movepiece.txt to movepiece.js? Once the name exist I will be able to update it in the normal way. Then I could make presets that want to use it just contain the link to that file. As it is I would have to put the entire script in the page itself. And these are non-cached pages, typically loaded many times during a game.
  • A minor inconvenience is that the text editor for the 'Rules, written in HTML' field in the Edit screen for presets starts in WYSIWYG mode, which strips the HTML of any existing content of that section from everything it doesn't know, in particular script tags, before you even get a chance to see it. If it would start in 'Source Code' mode, as it does in the submission for for member-contributed articles, the original content would be respected, and people that do not want to use any special HTML there can still easily switch to to WYSIWYG. I do like that text editor very much; even in source-code mode it is very helpful in indenting HTML tags and JavaScript, pointing out imbalanced tags and such. But that switching to WYSIWYG mode can lose you so much source definitely is a risky feature of it.

Greg Strong wrote on Sat, Aug 22, 2020 12:56 PM UTC in reply to H. G. Muller from 06:50 AM:

Would it be possible for an editor to rename the file /membergraphics/MSgame-code-generation/movepiece.txt to movepiece.js?

This is done.

A minor inconvenience is that the text editor for the 'Rules, written in HTML' field in the Edit screen for presets starts in WYSIWYG mode

Thanks, I meant to report this.  This edit field should start in HTML mode if there is already content so existing content doesn't get trashed.


🕸📝Fergus Duniho wrote on Sat, Aug 22, 2020 05:00 PM UTC in reply to H. G. Muller from 06:50 AM:

More serious is that when I try to play a distant Lion move beyond the Pawn (e.g. l d6-e4) it does not immediately accept the move, but still wants me to choose between the simple move and "l d6-e5; l e5-e4", highlighting both e4 and e5 to make that choice.

That's not very serious. In most cases, the move that captures a piece will be more desirable than the move that doesn't, and the player may appreciate the reminder that he can capture the Pawn while moving across its space. Also, some players may find it more natural to first click on the final destination, and then to click on the space where a piece may be captured en route. Since the exact same move will be entered no matter which order the spaces are clicked on, there is no need to enforce a certain order of mouse clicks on the players.


🕸📝Fergus Duniho wrote on Sat, Aug 22, 2020 05:09 PM UTC in reply to H. G. Muller from 06:50 AM:

A minor inconvenience is that the text editor for the 'Rules, written in HTML' field in the Edit screen for presets starts in WYSIWYG mode, which strips the HTML of any existing content of that section from everything it doesn't know, in particular script tags, before you even get a chance to see it. If it would start in 'Source Code' mode, as it does in the submission for for member-contributed articles, the original content would be respected, and people that do not want to use any special HTML there can still easily switch to to WYSIWYG.

Okay, it now opens in Source mode.


🕸📝Fergus Duniho wrote on Sun, Aug 23, 2020 02:04 AM UTC:

I modified showLegal() slightly to leave out piece notation when parsing a move string. So, the only steps it considers are coordinates and piece notation concatenated with an * for drops. I also modified it to strip out forward slashes, which are used for inline comments. These two modifications are useful because of a trick I came up with for writing fission moves in Fusion Chess. I realized I could write the remaining part of the fission move as a comment, and even though it was a comment, this would allow a player to make a fission move by clicking on the origin space for the third click. After all, there is nothing in setLegal() that distinguishes between real moves and comments. In this case, the comment helps reveal something about the move that distinguishes it from the standard move. Since clicking on a space twice works only when all steps in a move have been used up, I had to eliminate piece notation as steps. This is fine, since they play no role in narrowing down legal moves.


H. G. Muller wrote on Sun, Aug 23, 2020 05:35 AM UTC in reply to Fergus Duniho from 02:04 AM:

I modified setLegal() slightly to leave out piece notation when parsing a move string.

You mean showLegal() in the JavaScript.


🕸📝Fergus Duniho wrote on Sun, Aug 23, 2020 01:15 PM UTC in reply to H. G. Muller from 05:35 AM:

You mean showLegal() in the JavaScript.

Yes, I have made the correction now.


🕸📝Fergus Duniho wrote on Mon, Aug 24, 2020 09:54 PM UTC in reply to H. G. Muller from Sat Aug 22 06:50 AM:

More serious is that when I try to play a distant Lion move beyond the Pawn (e.g. l d6-e4) it does not immediately accept the move, but still wants me to choose between the simple move and "l d6-e5; l e5-e4", highlighting both e4 and e5 to make that choice. This is a consequence of the "any order" policy, rather than using the order of entry of clicks 2 and 3 to distinguish between the shooter and the multi-mover case.

For me that issue is still important enough to prefer my own adaptation of the JavaScript.

I had a different issue with the any order mechanism for selecting moves. When I clicked on one of my own pieces in Fusion Chess, it would show both that piece's moves and any fusion moves to that space by another piece. This could be confusing, and I decided it would be better to just show the moves for the piece clicked on. To accomplish this, I rewrote showLegal() to require that the steps of a move be entered in order. When the same space is clicked twice, this signals that moves with more steps should not be accepted, and that the move's final destination must be the space that was clicked on again. This is useful for selecting a shorter move from longer continuations of the same move or for selecting a move that returns to its origin.

Since this would not work properly with moving pieces by clicking on the destination first, I removed that capability. It will now only show where the piece clicked on can move to. It will no longer show which pieces can move to a particular space.


🕸📝Fergus Duniho wrote on Tue, Aug 25, 2020 01:45 AM UTC in reply to Fergus Duniho from Mon Aug 24 09:54 PM:

Since this would not work properly with moving pieces by clicking on the destination first, I removed that capability. It will now only show where the piece clicked on can move to. It will no longer show which pieces can move to a particular space.

I have restored that ability, and I enhanced the ability to quickly make moves. I renamed the old showLegal() function to showAllLegal(), and I renamed the new one to showNextLegal(). As these names suggest, showNextLegal does not always show as many legal moves as showAllLegal() does. Since showNextLegal() applies clicks in order, it may exclude moves that showAllLegal(), which does not apply clicks in order, would not exclude. Because showAllLegal() returns all possible moves involving a space, it can be used to determine if there is only one legal move involving that space. This allows Game Courier to play a move right away when it determines that there is only one legal move involving the space clicked on. This now works for enemy pieces as well as empty space. But it will not work when you click on one of your own pieces to see its legal moves. In that case, it will display the legal moves even if there is only one, and it will not play the move automatically.


🕸📝Fergus Duniho wrote on Tue, Aug 25, 2020 03:34 AM UTC:

I was interrupted when I was writing before, and I just now remembered something I wanted to include. By using showNextLegal(), the code can tell that a piece has no legal moves of its own, and by using showAllLegal(), it can then tell how many legal moves there are to that space. It is through using both together that one-click moving to a space occupied by an enemy piece is made possible.


H. G. Muller wrote on Tue, Aug 25, 2020 08:27 AM UTC in reply to Fergus Duniho from 01:45 AM:

But it will not work when you click on one of your own pieces to see its legal moves. In that case, it will display the legal moves even if there is only one, and it will not play the move automatically.

That sounds indeed like the best way to handle it. Personally I always feel a bit unnerved when an own piece that I click suddenly jumps away, because I often just click different pieces to switch on the highlights for what they can do, while thinking. So it is good that this will never happen. OTOH, I can see little reason for clicking an opponent piece or empty square without the intention to move there with fewer clicks. In case of ambiguity this means the order of the first two clicks would be swapped. Additional clicks (which should be a pretty rare requirement anyway) can then be made in strict order, the highlights always showing what the options for the next click are.

BTW, I would still consider it an improvement when one could select a different piece to move from the currently selected one, by just clicking it, rather than having to deselect first. Unless the other piece is highlighted as a valid destination for the selected one. (Of which the most common case will probably be a click on your own Rook to indicate a castling that would be ambiguous when indicating the King destination; virtually no variant has true friendly capture.) Treating a click on a non-highlighted own piece in a game that highlights will thus virtually never be an attempt to illegally enter a friendly capture, which makes the popup asking to confirm that this is what you want a bit silly. Better just treat it as if the user selected 'cancel' on that popup, resetting the move-entry state, and recursively calling movepiece for the same square as if it was a first click.


🕸📝Fergus Duniho wrote on Tue, Aug 25, 2020 05:27 PM UTC in reply to H. G. Muller from 08:27 AM:

I can see little reason for clicking an opponent piece or empty square without the intention to move there with fewer clicks

That's what I was thinking.

In case of ambiguity this means the order of the first two clicks would be swapped.

This occurred to me while I was while trying to sleep last night, and I just programmed it to do that.

Now that it does that, I think I want to combine clicking the first time and clicking subsequent times for legal moves. Right now, they are currently handled separately, and a first click does not pop up the requester for multiple move options. Alternately, I may make put the requester in its own function and call it from different places.


wdtr2 wrote on Wed, Aug 26, 2020 02:12 AM UTC in reply to Fergus Duniho from Tue Aug 25 05:27 PM:

I often click the opponent piece to review what moves it can do. This is quite useful in chess with different armies, or the zebra, because the zebra moves are different from game to game.


🕸📝Fergus Duniho wrote on Wed, Aug 26, 2020 02:26 AM UTC:

Since it took less work, I moved the requester to its own function, selectMove(), and I used it in three places in movePiece().


H. G. Muller wrote on Wed, Aug 26, 2020 06:38 AM UTC in reply to wdtr2 from 02:12 AM:

I often click the opponent piece to review what moves it can do. This is quite useful in chess with different armies, or the zebra, because the zebra moves are different from game to game.

But you do that when the opponent is on move. Otherwise nothing would be shown anyway. When we say 'opponent' in these discussion, we mean the opponent of the side that is on move in the displayed position. Not necessarily that of the player who is looking at the page.


🕸📝Fergus Duniho wrote on Wed, Aug 26, 2020 02:43 PM UTC in reply to H. G. Muller from 06:38 AM:

But you do that when the opponent is on move. Otherwise nothing would be shown anyway. When we say 'opponent' in these discussion, we mean the opponent of the side that is on move in the displayed position. Not necessarily that of the player who is looking at the page.

In normal usage, a game typically has two players, and each player is the other player's opponent. According to the variable names used in Game Courier, $player is the player whose turn it is to move, and $opponent is the other player. In this specialized usage, only the player's moves are ever shown, and the opponent's moves are never shown. More precisely, only the current player's moves are ever available to be shown, and the attacks the opponent could make are not available to be shown.

When a player moves, $player and $opponent switch values, and that player can then see the moves available to his opponent up until his opponent moves. It would probably be even more useful to show attacks from the opponent when it is not that opponent's turn, but that would take additional programming, and it would be incompatible with another useful feature I just added, which is the ability to capture an opponent's piece in one click if there is only one legal move to its space.

In hindsight, I would like to undo the use of $player and $opponent as variables, because they have hindered my ability to program multi-player games. But at this stage, it would require a lot of reprogramming.


🕸📝Fergus Duniho wrote on Sat, Aug 29, 2020 02:18 AM UTC in reply to H. G. Muller from Fri Aug 21 11:13 AM:

BTW, since you seem to synthesize the move texts from the square pairs given to setlegal, which you will have to do for backward compatibility, it might be better to extend the capabilities of setlegal to also accept multi-leg moves, so that there is a unified way to submit moves for highlighting. E.g. you could add to the specs that when the (only) argument of setlegal is an array, it will treat it as a multi-leg move. (You can still distinguish that from the other formats, which always have to start with a square.) The array could then be interpreted as a sequence of (from, to) pairs for each of the legs, from which a move text would be generated by concatenating them, using hyphens and semiclons as separators where appropriate. E.g.

setlegal (c6 e5 e5 d4 Q dest);
setlegal (e2 e7 @ e8 N e6);

I have extended setlegal to treat an initial array and any subsequent array after a first array as a multi-part move. So far, this works only with coordinates, not with pieces. Also, it specifies a path. So, setlegal (c6 e5 d4) would result in "[piece notation] c6-e5; e5-d4". I might change it to something simpler, like what you're suggesting, since it would make it easier to include pieces.

I have also extended it to add strings to the $extralegal array. This lets you construct any legal move you like as a string. Now that variables can be included in strings when enclosed in braces, this should prove an easy way to add legal moves.

Finally, legal moves are now being validated. After all legal moves have been assigned, they are run through a filter to make sure they are well-formed.


🕸📝Fergus Duniho wrote on Sat, Aug 29, 2020 05:47 PM UTC:

I have updated movepiece.js again. In case you want to use one-click moving when there is more than one move available, what you can do next has become a bit more intuitive. When it turns out that all matching legal moves start with movement by the same piece, and this was not the first piece clicked on, the clicks array is modified to include a click on that piece as the first click. Also, the only spaces that get highlighted are those that can disambiguate the move further. One consequence of this is that you can sometimes click on a space twice in a row to move a piece there.

Thanks to misremembering what was stored in the clicks array, the showNextLegal() function was not handling drops, and the showAllLegal() function was picking up the slack, which was causing the move options requester to pop up for drop moves. I stopped this by fixing showNextLegal() to handle drops correctly.


Jose Carrillo wrote on Sat, Oct 10, 2020 12:43 AM UTC:

Fergus,

The empty command doesn't seem to be working as it should,

I'm trying to create a new preset, and when using the empty command in the pre-game, the pieces end up captured.

Then I checked one of my old presets (below), which used to work, and realized that the empty command has the same incorrect behavior:

https://www.chessvariants.com/play/pbm/play.php?game%3DAjax+Orthodox+Chess%26settings%3DAlfaeire


🕸📝Fergus Duniho wrote on Sat, Oct 10, 2020 01:43 AM UTC in reply to Jose Carrillo from 12:43 AM:

The empty command doesn't seem to be working as it should,

I'm trying to create a new preset, and when using the empty command in the pre-game, the pieces end up captured.

I just tested it in Chess, and it works as it should. When I ran the following code, it removed White's King and the Queen-side Rook from the board, and it printed K. If it were working the same as capture, it would have printed R.

capture e1;
empty a1;
echo $lastcaptured;

H. G. Muller wrote on Sat, Oct 10, 2020 11:48 AM UTC:

With 'captured' Jose might not refer to $lastcaptured, but to the places displayed next to the board. I understood that GAME Courier just calculates those as the difference between initial and current pieces, irrespective of how the missing pieces disappeared. That would confirm the reported behavior of empty. But it seems to be intended.


H. G. Muller wrote on Sat, Oct 10, 2020 01:08 PM UTC:

The highest numbered placeholder should not exceed the number of different placeholders that you use. So, for example, if you use #4 as a placeholder, you should also include #3, #2, and #1.

I have just been waging a battle with this rule. This really is an extremely troublesome property of GAME code; is it really necessary to treat functions so sloppily? I understand that you somehow have to know how many arguments a function call has to delete from the stack. But why does it care if the earlier arguments are actually used to compute the function result? It should be able to just ignore them.

I have an application where I want to make it possible for a user to supply a function that could veto a normally valid pseudo-legal move generated by the library code, e.g. because it lands outside a confinement zone as in Xiangqi, or captures a piece type it should not be able to capture (e.g. the Jianggi Cannon x Cannon ban). To this end the library code has to call that function from some appropriate place, and it passes all the available information about the move to it, because there is no telling what kind of conditions the variant imposes. So it passes origin, destination, optional locust-capture square all to the function. But in individual cases the decision might require one some of the items (e.g. just the destination). It is really inconvenient having to include dummy operations on all the unused arguments. It completely mystifies a function that a user of the library would have to supply (and is bad for efficiency). Currently I work around it by writing something like

def BadZone cond 1 fn Edge #1 join #0 join #2 join #3 #4;

where the entire join club is just there to produce a dummy result that is never used (but cannot even be parenthesized to suppress its evaluation, as then the trick doesn't work anymore).

 


Jose Carrillo wrote on Sat, Oct 10, 2020 03:19 PM UTC in reply to Fergus Duniho from 01:43 AM:

I just added those same lines to my code, and the result was the same, "empty" captured.

/play/pbm/play.php?game%3DPetteia+V2%26settings%3DSet8q

Doesn't seem to work. I end up with 4 captured pieces.

alias S CI s ci D ~C d ~c;
empty a4;
empty a5;
capture e1;
empty a1;
echo $lastcaptured;



Do I have to need to add an include file for "empty" to work the way it used to?


🕸📝Fergus Duniho wrote on Sat, Oct 10, 2020 05:08 PM UTC in reply to H. G. Muller from 11:48 AM:

With 'captured' Jose might not refer to $lastcaptured, but to the places displayed next to the board. I understood that GAME Courier just calculates those as the difference between initial and current pieces, irrespective of how the missing pieces disappeared.

Yes, that's the default behavior. The displayed captured pieces can be controlled by the code, though.

That would confirm the reported behavior of empty. But it seems to be intended.

Yes, the empty command empties the coordinates passed to it.


🕸📝Fergus Duniho wrote on Sat, Oct 10, 2020 11:15 PM UTC in reply to H. G. Muller from 01:08 PM:

I have just been waging a battle with this rule. This really is an extremely troublesome property of GAME code; is it really necessary to treat functions so sloppily? I understand that you somehow have to know how many arguments a function call has to delete from the stack. But why does it care if the earlier arguments are actually used to compute the function result? It should be able to just ignore them.

There is now a new way to pass arguments to a function. I thought I had documented this, but I don't see where. So, I added some documentation for it in the area you quoted from. I also removed one error message, changing it to do nothing when a variable assignment in a function has nothing to assign to it. This change allowed functions to use default values for parameters.


🕸📝Fergus Duniho wrote on Sat, Oct 10, 2020 11:32 PM UTC in reply to Jose Carrillo from 03:19 PM:

Do I have to need to add an include file for "empty" to work the way it used to?

The empty command works the way it always has. The only difference from before is that the captured pieces display is a relatively new feature. If you don't want the pieces to show up in the captured pieces display, you have two options. You can write code that will set the capturedpieces system variable to what you want it to display. Or you could modify the value of originalpieces after you modify the board at the beginning of the game, then allow the usual default behavior for creating the captured pieces display. To do that, just include this line of code after your code for modifying the position:

setsystem originalpieces currentpieces;

Jose Carrillo wrote on Sat, Oct 10, 2020 11:51 PM UTC in reply to Fergus Duniho from 11:32 PM:

Thanks Fergus.

This worked for me.

setsystem originalpieces currentpieces;


Jose Carrillo wrote on Sun, Oct 11, 2020 04:53 PM UTC:

Hi Fergus,

I have now a problem with the "won" command.

I just use the "won" command in this game:

https://www.chessvariants.com/play/pbm/play.php?game=Latrunculi+XXI&log=j_carrillo_vii-cvgameroom-2020-281-060

but the game continued.

I asked my opponent to resign, while I sort out what is happening to the "won" command.


🕸📝Fergus Duniho wrote on Sun, Oct 11, 2020 05:59 PM UTC:

While looking into this, I wrote some additional code. Game Courier stopped working properly, and since I could not see any problem in the new code, I just undid all changes, but the problem persisted. Since I have edited only one Game Courier file today, and I changed it back to what it originally was before any problems began, I'm not sure what the problem could be.


🕸📝Fergus Duniho wrote on Sun, Oct 11, 2020 06:11 PM UTC in reply to Fergus Duniho from 05:59 PM:

While not working in Firefox, it is working in Vivaldi. Strange.


H. G. Muller wrote on Sun, Oct 11, 2020 06:11 PM UTC:

How sure are you that you changed it back to what it was? Did you safe the old version, and moved it back?

This kind of thing usually happens to me when I accidentally made some unintended changes (e.g. drag-drop something because of a mouse glitch without noticing it, or leaning on the keyboard), and then reverting the intended changes then of course doesn't help. Under Linux I now use git for version control, so there I can always revert to any previous version. (And more importantly, just look at the diff with such a version, to see if anything untoward happened.)

I am afaraid that debugging it again is the only alternative.

[Edit] It could also be that FireFox was updated, and is not so forgiving as a previous version anymore. I know that I initially had uploaded the JavaScript for the Interactive Diagram with a PNG extension. This worked for a long time on FireFox, but at some point it stopped working, and it would only consider scripts in a .js file.


H. G. Muller wrote on Sun, Oct 11, 2020 07:21 PM UTC in reply to Fergus Duniho from Sat Oct 10 11:15 PM:

So, I added some documentation for it in the area you quoted from.

To make sure I understand this: the formal parameters of the function will have to be written at the end of the function, each prefixed with '=', in the order the corresponding actual parameters will appear in the function call? And the function call will then 'eat away' always that number of parameters from the stack, whether they are used or not? So I could write something like

def BadZone == 9 rank #destination =origin =destination =locustsqr =dropsqr =droppedpiece;

to get a function called with 5 parameters, and only testing if the second is on rank 9?


🕸📝Fergus Duniho wrote on Sun, Oct 11, 2020 09:41 PM UTC in reply to H. G. Muller from 06:11 PM:

How sure are you that you changed it back to what it was?

I used Ctrl-z all the way back in Notepad++.

It could also be that FireFox was updated, and is not so forgiving as a previous version anymore.

It hasn't been updated since I began running it earlier today. I just tried it in other tabs, and it is working. Maybe I went to the wrong tab. The one that wasn't working turned out to be for I-Chess, not Chess.


🕸📝Fergus Duniho wrote on Sun, Oct 11, 2020 09:47 PM UTC in reply to Jose Carrillo from 04:53 PM:

I have now a problem with the "won" command.

This problem went deeper than the won command. Thanks to a bit of restructuring I had done to speed up Game Courier, it was not properly handling any commands entered as moves except for a few that were handled earlier, such as resign, lost, and drawn, but not won. I corrected it to handle commands entered as moves. I set it up so that resign, lost, and drawn are not affected by the global ban on all commands, though they may be banned individually. I commented out the code for using them earlier, and I modified the code in the commands section.


Jose Carrillo wrote on Sun, Oct 11, 2020 10:03 PM UTC in reply to Fergus Duniho from 09:47 PM:

Fergus,

I'm not sure I understood your response.

Does the won command don't work anymore when entered as a move?

How are we supposed to claim a win when we checkmate in a preset that does not enforce the rules?

It would make more sense for the "won" command to work as a move than the "lost" command. For losing a game we have the alternative to "resign" command, but what is the alternative when we win by checkmate and we should claim a win immediately, rather than ask the opponent to resign a checkmated position?


🕸📝Fergus Duniho wrote on Mon, Oct 12, 2020 02:34 AM UTC in reply to Jose Carrillo from Sun Oct 11 10:03 PM:

To summarize, I fixed it.


Jose Carrillo wrote on Mon, Oct 12, 2020 12:44 PM UTC in reply to Fergus Duniho from 02:34 AM:

Thanks Fergus.

Now that the "won" command is working (and because by opponent had resigned to the game, while the won command didn't work) there was a strange behavior that affected the result for this game:

https://www.chessvariants.com/play/pbm/play.php?game=Latrunculi+XXI&log=j_carrillo_vii-cvgameroom-2020-281-060

Now it shows that my opponent (who resigned) won the game.

Can you please correct the result for this game? Thanks again.


Jose Carrillo wrote on Mon, Oct 12, 2020 01:07 PM UTC in reply to Fergus Duniho from 02:34 AM:

Fergus,

Also, something went wrong with this game, which also just ended with the "won" command:

https://www.chessvariants.com/play/pbm/play.php?game=Petteia+-+Dmytro+Variation&log=j_carrillo_vii-halfer-2020-285-568

I'm trying to view the moves to replay the game, and now I can't see any of the moves.

It just show the starting board without any of the moves played.

Thanks in advance.


🕸📝Fergus Duniho wrote on Mon, Oct 12, 2020 04:48 PM UTC in reply to Jose Carrillo from 12:44 PM:

Now it shows that my opponent (who resigned) won the game.

That's now been corrected.


🕸📝Fergus Duniho wrote on Mon, Oct 12, 2020 04:49 PM UTC in reply to Jose Carrillo from 01:07 PM:

Also, something went wrong with this game, which also just ended with the "won" command:

https://www.chessvariants.com/play/pbm/play.php?game=Petteia+-+Dmytro+Variation&log=j_carrillo_vii-halfer-2020-285-568

Are you sure you gave me the link to the correct game? This one doesn't include the won command in it.


🕸📝Fergus Duniho wrote on Mon, Oct 12, 2020 04:59 PM UTC in reply to H. G. Muller from Sun Oct 11 07:21 PM:

So I could write something like

def BadZone == 9 rank #destination =origin =destination =locustsqr =dropsqr =droppedpiece;

to get a function called with 5 parameters, and only testing if the second is on rank 9?

First, a matter of vocabulary. Function definitions have parameters, but function calls have arguments. An argument is a value passed to one of the parameters of a function. This will test whether the fourth argument from the right is a coordinate on rank 9, which would be the tenth rank. As long as you include five arguments in your function call, it will be the second argument from the left. If you had only four arguments, it would test the first one from the left. If you had three or less, that parameter would not be assigned a value. I know it's a bit counter-intuitive, but it's what comes from evaluating functions in reverse order, as Game Courier does.


Jose Carrillo wrote on Mon, Oct 12, 2020 05:15 PM UTC in reply to Fergus Duniho from 04:49 PM:

Apologies Fergus, gave you the wrong link.

The correct game was this one:

https://www.chessvariants.com/play/pbm/play.php?game=Petteia+-+Dmytro+Variation&log=j_carrillo_vii-halfer-2020-283-953

But I just checked again and now the log is there. It was weird. last time I checked there were only two lines in the log, White to play and Jose Carrillo won the game.

And I saw it as well in the page source.

Seems to be fine now. Thanks.

And thanks for correcting the winner in the other comment I submited.

Cheers!


Jose Carrillo wrote on Mon, Oct 12, 2020 06:11 PM UTC in reply to Fergus Duniho from 04:48 PM:

Fergus,

I must be going crazy... :-(

Now this game:

https://www.chessvariants.com/play/pbm/play.php?game=Petteia+-+Dmytro+Variation&log=j_carrillo_vii-halfer-2020-283-953

(the game whose moves I couldn't see before) is showing that my opponent won the game. This game is another one where I ended the game with the "won" command.

I issued the "won" command as white, but the log shows that my opponent (black) won.

There seems to be something weird with the "won" command.

Below the page source section with the problem:


🕸📝Fergus Duniho wrote on Mon, Oct 12, 2020 06:24 PM UTC in reply to Jose Carrillo from 05:15 PM:

The correct game was this one:

https://www.chessvariants.com/play/pbm/play.php?game=Petteia+-+Dmytro+Variation&log=j_carrillo_vii-halfer-2020-283-953

Seems to be fine now. Thanks.

It was showing that your opponent had won, yet you had entered the won command. So, I fixed that. It now makes use of the $players variable if available. This gets set when an invitation is accepted, and it keeps a permanent record of who moved first, which makes it easier to tell which player entered the command.


🕸📝Fergus Duniho wrote on Mon, Oct 12, 2020 06:26 PM UTC in reply to Jose Carrillo from 06:11 PM:

There seems to be something weird with the "won" command.

I have now fixed this. See the comment below.


Jose Carrillo wrote on Mon, Oct 12, 2020 07:54 PM UTC in reply to Fergus Duniho from 06:26 PM:

Thanks Fergus!


100 comments displayed

EarliestEarlier Reverse Order LaterLatest

Permalink to the exact comments currently displayed.