Check out Glinski's Hexagonal Chess, our featured variant for May, 2024.


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

Comments by FergusDuniho

Later Reverse Order EarlierEarliest
Game Courier. PHP script for playing Chess variants online.[All Comments] [Add Comment or Rating]
🕸💡📝Fergus Duniho wrote at 01:47 AM UTC in reply to Fergus Duniho from 01:25 AM:

In this test settings file for Musketeer Chess, I removed the bits of code I thought might be extraneous, and I found no difference in how it behaved. First, I removed the code for handling the second part of Black's first placement move from the code for White's first placement move, changing it to this:

elseif == movenum 2: // White's 2nd move
  setlegal d4 a0 b0 c0 d0 e0 f0 g0 h0;
  setlegal e4 a0 b0 c0 d0 e0 f0 g0 h0;
  end;

Second, I removed this code from Post-Game 1:

elseif == movenum 4: // White
  if not empty e5 or not empty d5:
    continuemove;
  endif;

As far as I can tell, the code I removed was not needed, and maybe it wasn't even executed. For both settings files, I was able to move pieces after placing the extra pieces. Since I tested only in Solitaire mode, I wonder if there might be some difference between them in a correspondence game.


🕸💡📝Fergus Duniho wrote at 01:25 AM UTC in reply to Aurelian Florea from Sat May 25 06:47 PM:

I am still confused. How do I execute the postgame handler (whiteFirstTurn) for a second time?

See the Post-Move code for Musketeer Chess to get some idea of how it can be done.

Each begins with a series of if and elseif conditions to check the value of thismove or movenum. Post-Game 2 first checks whether thismove is null, because at the very beginning of the game, it is effectively at the end of the second player's turn. This is because each subsequent time it is the first player's turn to move, it will be after the second player has moved, which is the normal time to run Post-Game 2. This means that the first Post-Game section to run will be the second, not the first.

However, Musketeer Chess does things in a more complicated way than your game. Before it lets you place both extra pieces on the same move, it has each player select one of the pieces. First White selects one, and Black gets the same piece, and then Black selects one and White gets the same piece. After this stage, it moves the selected pieces to the center of the board, and each player gets to place them. First White moves each piece, and then Black does.

So we need to jump ahead to this stage to see what is being done. For White, this is done with this code in Post-Game 2:

elseif == movenum 2: // White's 2nd move
  if not empty d4 and not empty e4:
    setlegal d4 a0 b0 c0 d0 e0 f0 g0 h0;
    setlegal e4 a0 b0 c0 d0 e0 f0 g0 h0;
    end;
  else:
    if not empty e!9:
      set legalto (b9 c9 d9 f9 g9);
      remind "Since you placed your first piece behind your King, the second may not go behind a Rook.";
    elseif not empty a!9:
      set legalto (b9 c9 d9 f9 g9 h9);
      remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
    elseif not empty h!9:
      set legalto (a9 b9 c9 d9 f9 g9);
      remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
    else:
      set legalto (a9 b9 c9 d9 e9 f9 g9 h9);
    endif;
    set f cond empty d5 e5 d5;
    foreach c var legalto:
      if empty realname #c:
        setlegal #f #c;
      endif;
    next;
    end;
  endif;

If White has not moved either piece, it sets legal moves for White. Otherwise, it sets legal moves for Black. But why does it work this way? Post-Move 2 normally runs after a move by the second player. If no moves have been made, this is normally the start of the first player's turn, and it will calculate legal moves for the first player. But when a move has already been made, this is a continuation of a move by the second player. In that case, it needs to calculate the moves for the second player.

When handling gating on the first move instead of the second, code like this may be more appropriate:

elseif == thismove null: // White's ist move
  setlegal d4 a0 b0 c0 d0 e0 f0 g0 h0;
  setlegal e4 a0 b0 c0 d0 e0 f0 g0 h0;
  end;
elseif == movenum 1: // Second part of Black's move
    if not empty e!9:
      set legalto (b9 c9 d9 f9 g9);
      remind "Since you placed your first piece behind your King, the second may not go behind a Rook.";
    elseif not empty a!9:
      set legalto (b9 c9 d9 f9 g9 h9);
      remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
    elseif not empty h!9:
      set legalto (a9 b9 c9 d9 f9 g9);
      remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
    else:
      set legalto (a9 b9 c9 d9 e9 f9 g9 h9);
    endif;
    set f cond empty d5 e5 d5;
    foreach c var legalto:
      if empty realname #c:
        setlegal #f #c;
      endif;
    next;
    end;
  endif;

Note that this is just a modification of the Musketeer Chess code, which has not been finetuned for your game, and which has not been tested.

Accordingly, the second part of White's turn is handled in Post-Game 1 with this code:

elseif == movenum 2: // Second part of White's Second Move
  set f cond empty d4 e4 d4;
  if not empty e!0: 
    setlegal #f b0 c0 d0 f0 g0;
    remind "Since you placed your first piece behind your King, the second may not go behind a Rook.";
  elseif not empty a!0:
    setlegal #f b0 c0 d0 f0 g0 h0;
    remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
  elseif not empty h!0:
    setlegal #f a0 b0 c0 d0 f0 g0;
    remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
  else:
    remind "Place your piece on" #f "behind your back rank.";
    foreach x range a h:
      set t join #x !0;
      if empty #t:
        set t join #x 0;
        setlegal #f #t;
      endif;
    next;
  endif;
  end;

Unlike the section that dealt with the second part of Black's move, this just calculates legal moves for White. Note that the movenum value it checks for is the same in each case. For White, it is the same move whether at its start or continuing it.

Since we already saw how Black's move is continued, let's look at how it begins. It begins with this code in Post-Game 1:

elseif == movenum 3: // Black's Second Move
  setlegal d5 a9 b9 c9 d9 e9 f9 g9 h9;
  setlegal e5 a9 b9 c9 d9 e9 f9 g9 h9;
  end;

I'm not sure why it would begin on a later move number than it would continue on. Maybe I included some extraneous code that doesn't do anything. Looking at Post-Game 2, I see this code for continuing Black's move:

elseif == movenum 3: // Second Part of Black's Second Turn
  set f cond empty d5 e5 d5;
  if not empty e!9: 
    setlegal #f b9 c9 d9 f9 g9;
    remind "Since you placed your first piece behind your King, the second may not go behind a Rook.";
  elseif not empty a!9:
    setlegal #f b9 c9 d9 f9 g9 h9;
    remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
  elseif not empty h!9:
    setlegal #f a9 b9 c9 d9 f9 g9;
    remind "Since you placed your first piece behind a Rook, the second may not go behind your King.";
  else:
    remind "Place your piece on" #f "behind your back rank.";
    foreach x range a h:
      set t join #x !9;
      if empty #t:
        set t join #x 9;
        setlegal #f #t;
      endif;
    next;
  endif;
  end;

This is mostly the same as the code for Black found with "White's 2nd Move". I'll do some tests later to see if I can remove the other code.

For some reason, I have code for continuing a partial move only in Post-Game 1:

elseif == movenum 4: // White
  if not empty e5 or not empty d5:
    continuemove;
  endif;

Investigation reveals that I am also using continuemove in the Post-Game sections. So things are just getting more complicated. White's placing move is handled with this code in Post-Game 1:

elseif == turn 2: 
  restore premove;
  set mvs explode chr 59 thismove;
  eval join "MOVE: " trim elem 0 mvs;
  if and != origin d4 != origin e4 or != rankname dest !0:
    die All you may do right now is place an extra piece behind your back rank.;
  endif;
  if > count var mvs 1:
    eval join "MOVE: " trim elem 1 mvs;
    if and != origin d4 != origin e4 or != rankname dest !0:
      die All you may do right now is place an extra piece behind your back rank.;
    elseif not empty a!0 or not empty h!0 and not empty e!0:
      die You may not place your pieces behind a King and a Rook.;
    endif;
    foreach f range a h:
      set c join #f "!0";
      if empty #c:
        delete #c;
      endif;
    next;
  remind "Now that you have placed your extra pieces behind your back rank, the remaining spaces behind it have been deleted.";
  else:
    continuemove;
  endif;
  return;
endif;

Note that it is restoring the position, parsing thismove into separate moves, executing each one individually, and testing it for legality. It does not evaluate either move until both have been made. If only one has been made, it uses continuemove.

In a similar manner, Black uses this code to evaluate the placing move in Post-Game 2:

elseif == turn 2:
  restore premove;
  set mvs explode chr 59 thismove;
  eval join "MOVE: " trim elem 0 mvs;
  if and != origin d5 != origin e5 or != rankname dest !9:
    die All you may do right now is place an extra piece behind your back rank.;
  endif;
  if > count var mvs 1:
    eval join "MOVE: " trim elem 1 mvs;
    if and != origin d5 != origin e5 or != rankname dest !9:
      die All you may do right now is place an extra piece behind your back rank.;
    endif;
    foreach f range a h:
      set c join #f "!9";
      if empty #c:
        delete #c;
      endif;
    next;
    setsystem originalpieces piececount;
    remind "Now that you have placed your extra pieces behind your back rank, the remaining spaces behind it have been deleted.";
  else:
    continuemove;
  endif;
  return;
endif;

🕸💡📝Fergus Duniho wrote on Sat, May 25 11:42 AM UTC in reply to H. G. Muller from 08:53 AM:

I suppose you meant to write Post-Game code here?

Yes, I did. I have now corrected this. In your last sentence, you said Pre-Game code. Did you mean Post-Game code?


🕸💡📝Fergus Duniho wrote on Fri, May 24 04:22 PM UTC in reply to H. G. Muller from 08:42 AM:

The code for continuemove is just a series of variable assignments, which by itself doesn't give much hint about how it should be used.

case "continuemove": // Allow multi-part move to be made with mouse/touch
case "redomove": // Allow player to redo illegal move
  if ($submit == "Preview")
    $submit = "";
  $pastmovesfield = ($args[0] == "redomove") ? "" : $moves;
  $movelist = $oldmovelist;
  $movenum = max($movenum - 1, 0);
  if (!$switchsides) {
    $side = $turnorder[$movenum % $sidecnt];
  }
  else
    $side = $turnorder[($sidecnt - 1) - ($movenum % $sidecnt)];
  break;

So, the main thing to consider is which variables are changing and how they are used. Changing the value of $submit changes which form_* script it includes when it loads the page after submitting a move. With a value of "Preview", it would include form_verify.php for showing a preview of the move and asking the player to confirm it. With an empty value, it will include form_move.php again. If you were playing by yourself in solitaire mode, it would not have to change the script it includes.

$pastmovesfield is for populating a form field that gets used for multi-part moves. So that the moves field works the same as it would for single moves, it starts out empty, and the previously entered moves go in a different form field.

$movelist is a string listing every move in the game on a separate line, sometimes with comments interspersed. $oldmovelist was set to $movelist just before appending the latest move to it. So this sets $movelist to what it was before the partial move that was already made was made. Once the full multi-part move has been made, it will be appended to $movelist as a single string.

$movenum is the number of the latest move. Since it would normally be incremented at the end of a complete move, it is decremented to keep it the same, though it is not allowed to go below zero.

$side indicates the side of the player who can move. This would normally switch to the other player at the end of a turn. But when continuing a move, it should not change to the other player. It gets the value of $side from a list of players whose identifiers in the game are values in the $turnorder array. It does this instead of switching a flag back and forth, because I wanted to add support for multi-player games and games with alternate turn orders, but that project is not complete, because some code in Game Courier just assumes a two-player game with alternating turns.

$switchsides has to do with the orientation of the board. It defaults to 0, which means that the board should be shown from the perspective of the player whose turn it is to move. Setting it to a non-zero value would cause the board to stay in the same position no matter whose turn it is. Since this is only a cosmetic difference, I'm not sure why it should have any bearing on whose side it is. So I'll experiment with whether giving $switchsides a non-zero value will mess up how a multi-move game operates.

The assigned variables mainly affect the form the player gets after completing the first part of a multi-part move, and they have nothing to do with the evaluation of a move, which is what the Post-Move code is supposed to handle. Given the purpose of this command, it should not be executed more than once during a whole series of moves, and it should not be executed for any past moves. In fact, calling it more than once could result in the wrong value for $movenum. So, it makes sense to reserve its use for the Post-Game code. In my code for Extra Move Chess, it is used after calculating the legal moves for the second part of the turn.


🕸💡📝Fergus Duniho wrote on Thu, May 23 03:03 PM UTC in reply to Aurelian Florea from 01:18 PM:

Per HG's suggestion!

No, he suggested you use it in your handling routines, but these are in your Post-Move code. So what I'm telling you is contrary to his suggestion.


🕸💡📝Fergus Duniho wrote on Thu, May 23 12:57 PM UTC in reply to Aurelian Florea from Wed May 22 05:42 PM:

In what I'm doing now continuemove does nothing. Any idea why?

The Developer’s Guide says to use it only in the Post-Game code, but you are using it in the Post-Move code.


🕸💡📝Fergus Duniho wrote on Wed, May 22 02:52 PM UTC in reply to Fergus Duniho from 02:27 PM:

It's the "set many" line that is causing the screen to go blank.

Technically, it was a bug in the line calling the error function that was causing it to go blank, as I had omitted the second argument for the line number. I have now fixed that so that if you use "set many" with an odd number of arguments, it will now give you a helpful error message instead of a blank screen.


🕸💡📝Fergus Duniho wrote on Wed, May 22 02:41 PM UTC in reply to Fergus Duniho from 02:27 PM:

The problem is that "set many" does not work with expressions. Each value assigned to a variable must be a scalar value or a variable value.

More precisely, "set many" does not natively work with expressions, and for a long time it just did not work with them. But if an expression is placed in braces, it will now be evaluated during preprocessing of the line. So this works:

set many ok 1 promo 0 ori #source1 desti #dest1 mover {space #dest1};

As a test of what I'm talking about, try echo with an expression and with the same expression between braces, like so:

echo + 8 9;
echo {+ 8 9};

The first line prints "+ 8 9", and the second prints 17.


🕸💡📝Fergus Duniho wrote on Wed, May 22 02:27 PM UTC in reply to Aurelian Florea from 09:43 AM:

It's the "set many" line that is causing the screen to go blank. I modified your code to this, and the screen went blank after I moved one Black piece.

sub blackInitialHandle:
 set tm thismove;
 set source1 join char thismove 2 char thismove 3;
 set dest1 join char thismove 5 join char thismove 6 char thismove 7;
 set source2 join char thismove 11 char thismove 12;
 set dest2 join char thismove 14 join char thismove 15 char thismove 16;
 move #source1 #dest1;
 move #source2 #dest2;
 set many ok 1 promo 0 ori #source1 desti #dest1 mover space #dest1;
die "ok: " #ok "promo: " #promo "ori: " #ori "desti: " #desti "mover: " #mover;
endsub;

The problem is that "set many" does not work with expressions. Each value assigned to a variable must be a scalar value or a variable value. When I changed your code to this, it did work:

sub blackInitialHandle:
 set source1 join char thismove 2 char thismove 3;
 set dest1 join char thismove 5 join char thismove 6 char thismove 7;
 set source2 join char thismove 11 char thismove 12;
 set dest2 join char thismove 14 join char thismove 15 char thismove 16;
 move #source1 #dest1;
 move #source2 #dest2;
 set many ok 1 promo 0 ori #source1 desti #dest1;
 set mover space #dest1;
endsub;

However, since it handled only one piece at a time, there are still pieces in the middle of the board, and they are now able to move normally, which is not what you want.


🕸💡📝Fergus Duniho wrote on Wed, May 22 02:07 PM UTC in reply to Aurelian Florea from 09:43 AM:

I get a blank screen after this instruction.

I modified blackInitialHandle like so to return some values before things go wrong.

sub blackInitialHandle:
 set tm thismove;
 set source1 join char thismove 2 char thismove 3;
 set dest1 join char thismove 5 join char thismove 6 char thismove 7;
 set source2 join char thismove 11 char thismove 12;
 set dest2 join char thismove 14 join char thismove 15 char thismove 16;
die "tm: " #tm "s1: " #source1 "s2: " #source2 "d1: " #dest1 "d2: " #dest2;
 move #source1 #dest1;
 move #source2 #dest2;
 set many ok 1 promo 0 ori #source1 desti #dest1 mover space #dest1;
endsub;

Here are the values I got:

tm: g e7-d11 
s1: e7 
s2: 
d1: d11 
d2:

I broke it into multiple lines so that you can clearly see that source2 and dest2 have no values.

So far, your code is not set up to handle two moves on the same turn. When I moved one White piece, it immediately changed sides for me to move a Black piece.

For a second test, I moved the die command down two lines to see if "move #source2 #dest2;" was the problem. Since the die command still worked, I assume something happened in HG's code.


Interactive diagrams. Diagrams that interactively show piece moves.[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Wed, May 22 01:53 AM UTC in reply to Daniel Zacharias from Tue May 21 10:49 PM:

How can I make an interactive diagram that can switch between greenwade and alfaerie graphics? Is there a way to change the image names associated with pieces dynamically?

You can use /play/pbm/showpiece.php with matching Game Courier sets, or you can alter piece names by hand. Look at the source for Chess to see how the former works or at the source for Ultima to see how the latter is done.


Hibernian Chess. Members-Only Missing description (14x14, Cells: 196) [All Comments] [Add Comment or Rating]

Since this comment is for a page that has not been published yet, you must be signed in to read it.

Since this comment is for a page that has not been published yet, you must be signed in to read it.

Since this comment is for a page that has not been published yet, you must be signed in to read it.

Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Mon, May 20 03:24 PM UTC in reply to HaruN Y from Sun May 19 11:30 PM:

Game Reviews are the same as Comments.

The query string had the right parameters, but it needed to set gamesonly and ratingsonly to true instead of just including them. I corrected that, and it now works properly.


Game Courier Developer's Guide. Learn how to design and program Chess variants for Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Sun, May 19 04:46 PM UTC in reply to Aurelian Florea from 08:27 AM:

A well-formed legal move should include the piece, but since e5 is empty, the compose_move function is not finding any piece to include in the move. Make sure each of your legal moves is from an occupied space.


Question on viewing past games[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Sat, May 18 09:25 PM UTC in reply to wdtr2 from 04:35 PM:

one of the viewing button becomes a "@". There is an info message: "Lacking data to view this position. To view whole game, load in last move.".

This means you loaded the game from an earlier position instead of from the latest position. You might have done this accidentally by clicking the View button, which used to be the only way to navigate through the moves of a game. You should follow the instructions and load it from the latest position. Click on the >| button, then click on the View button. This will load the game at the last move, making all past moves accessible without the need to reload any of them.


Obento Chess. 12x12 Chess variant with Shogi-style promotions and bent sliding pieces. (12x12, Cells: 144) [All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Thu, May 16 12:01 AM UTC in reply to HaruN Y from Wed May 15 11:19 PM:

I presume the name is inspired by the name Chess 960, which is an alternate name for Fisher Random Chess that some people prefer. But the number 960 in this alternate name for Fisher Random Chess is due to the number of different positions possible using the shuffle rules of that game. If you apply the same shuffle rules to a 12x12 game with two rows of non-Pawn pieces for each player, the number will probably be higher than 960. So I don't think Obento Chess 960 is really an appropriate name. It would be better to call it Fisher Random Obento Chess.

Also, it does not appear to be working. It does not shuffle pieces, and it does not show me how any piece moves.


Game Courier Logs. View the logs of games played on Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Tue, May 14 06:51 PM UTC in reply to H. G. Muller from 07:19 AM:

Marking of attacked squares to weed out illegal King moves is just one of the two things the accelerated check test does. The other thing is that it tabulates for each board square which (attempted) sliding moves visit it.

It's not the same thing that you're doing, but I have now made a quicker version of stalemated called stalemated-quick, which does some preprocessing to reduce the work involved in checking for check. It starts by creating an array of the King's location and each space it may move to, and for each location in this array, it makes an array of every location with an enemy piece that has it in its range. The code looks like this:

// Build threat lists
set krange merge fn join const alias space #kingpos "-Range" #kingpos #kingpos;
set threats ();
for to #krange:
  set threats.{#to} ();
next;
for (from piece) fn #enemies:
  set in intersection var krange fn join const alias var piece "-Range" var from;
  for to #in:
    push threats.{#to} #from;
  next;
next;

So it creates multiple elements of an array called threats, each of which is an array of the enemy pieces that include that space in its full range of movement. At the start of Chess, threats.d2 and threats.d1 both have one element set to d8, and the others (elements e1, e2, f1, and f2 of threats) are empty.

To check for check, it first assumes a value of false, and it tries out the move only if there are pieces potentially threatening the space the King is on. That move looks like this:

set checkpos cond == #from #kingpos #to #kingpos;
set checked false;
if count elem var checkpos threats:
  move #from #to;
  set checked fn threatened #checkpos;
  restore;
endif;

Instead of using the checked function, it used the threatened function, which looks like this:

def threatened anytrue lambda (fn const alias space #0 #0 var king) 
elem var king threats 
=movetype CHECK 
=king;

This function expects threats to be populated with appropriate values. So it can't be used everywhere checked can.

In tests with Chess, everything seems to be working. After making sure it worked, I did some speed tests comparing 100 calls to stalemated with 100 calls to stalemated-quick. In each pair, stalemated is first, and stalemated-quick is second. The results show that stalemated-quick is normally quicker.

Elapsed time: 4.7686970233917 seconds

Elapsed time: 2.8460500240326 seconds

Elapsed time: 4.8747198581696 seconds

Elapsed time: 3.0506091117859 seconds

Elapsed time: 4.4713160991669 seconds

Elapsed time: 2.9584100246429 seconds

🕸📝Fergus Duniho wrote on Tue, May 14 02:09 AM UTC in reply to H. G. Muller from Mon May 13 08:30 PM:

That would indeed be an alternative: do a full king-capture test after every King move. But it would be more expensive, as a King usually has several moves.

It's more than that. I do a full king-capture test for every pseudo-legal move by every piece that can move. My code works like this.

  1. It goes through every piece from the side that can move.
  2. For each piece on the side that can move, it calculates the spaces within its range of movement. This is an optimization to keep it from checking for legal moves to every position on the board.
  3. For each space within a piece's range of movement, it checks whether the piece has a pseudo-legal move there.
  4. For each pseudo-legal move, it tries the position and checks whether it places the King in check.
  5. It checks whether the King is in check by checking whether any enemy piece can move to the King's space. As an optimization, it returns true as soon as it finds one check.
  6. It checks whether a piece may move to the King's space by calling its function for the move from its location to the King's space.
  7. Divergent pieces are handled by writing them to behave differently when the movetype variable is set to CHECK. In the following example, the function for the White_Pawn first checks some conditions any Pawn move must meet, then handles capturing, then continues to handle non-capturing and en passant moves only if movetype is not CHECK.
def White_Pawn
remove var ep
and < rankname #1 var bpr
and < rankname var ep rankname #1
and == filename var ep filename #1
and checkleap #0 #1 1 1
and var ep
or and checkride #0 #1 0 1 == rankname #0 var wpr
or checkleap #0 #1 0 1
and empty #1
and != var movetype CHECK
or and islower space #1 checkleap #0 #1 1 1
and any onboard where #1 0 1 == var movetype CHECK count var wprom
and <= distance #0 #1 var fps
and > rank #1 rank #0;
  1. Pieces with non-displacement captures are handled by writing two different functions for them and using the value of movetype to call the correct function.

So you would have to do enemy move generation several times.

Since my code uses piece functions, this is not a big problem. In tests I ran yesterday, my checked function ran 1000 times in under half a second, and the checked subroutine got called 1000 times in close to a second, and this was on a position in which the King was not in check, which meant it never broke out early. Since your code does not use piece functions, it may handle the evaluation of moves more slowly, which will also cause it to evaluate check more slowly.

Testing whether a destination contains the King is not any more expensive than marking the destination. And to do it, you only need to geenrate all enemy moves once.

This optimization might be helpful when not using piece functions, but one thing about it concerns me. While it might be helpful in determining whether a move by the King would be into check, I'm not sure it will work for revealed checks. It is because of the possibility of revealed checks that my code checks for check for the position resulting from every single pseudo-legal move it finds.

I suppose one optimization that could be made if it were needed would be to identify the pieces that might possibly check the King at its current location, then limit the test for whether a move by another piece places the King in check to those pieces. This could be done by making a short list of every enemy piece whose range of movement contains the King's location and having the checked function use it instead of onlyupper or onlylower. If this list were empty, it could even skip the step of trying out a pseudo-legal move and testing whether it places the King in check.

However, this might not work for non-displacement captures in which the capture occurs outside the piece's range of movement, such as the Coordinator capture in Ultima. So, I have to balance efficiency with the work a programmer has to make to use a piece in a game. The brute force method I use helps reduce the work the programmer has to do to make different kinds of pieces work with it.


🕸📝Fergus Duniho wrote on Mon, May 13 07:35 PM UTC in reply to H. G. Muller from 05:54 PM:

The issue was that the test for being already in check was done with the King taken off the board

Why would you take the King off the board for this? Couldn't this cause false positives and false negatives from divergent pieces like Pawns or Cannons?

This was a bug that did not yet express itself. A Checker diagonally adjacent to the enemy King would not deliver check if a friendly piece was immediately behind that King, blocking the landing square. But that blocking piece would then essentially be pinned, and its moves should not be highlighted.

The code I use avoids this by trying each pseudo-legal move and checking whether any piece in the new position is checking the King.


The Fairychess Include File Tutorial. How to use the fairychess include file to program games for Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Mon, May 13 02:20 AM UTC in reply to Fergus Duniho from Sun May 12 10:29 PM:

I was thinking of splitting the checked function into separate checked-real and checked-potential functions, but as I was looking into which would be which, it looked like there was never any time when it was passed an empty space after the King just moved. In the Pre-Move sections, kpos or Kpos would be updated before calling the function, and in stalemated, it would check whether the King was the moving piece and pass the King's new position if it was. This meant I could reduce the function to this:

def checked anytrue lambda (fn const alias #0 var key var king) 
cond isupper space var king (onlylower) (onlyupper) 
=movetype CHECK 
=king;

Just in case, I ran this code in Ultima as a test:

sub checked king:
  my from piece;
  local movetype;

  set movetype CHECK;
  if empty var king:
    die "The King space at {#king} is empty.";
  endif;
  if isupper cond empty var king $moved space var king:
    def enemies onlylower;
  else:
    def enemies onlyupper;
  endif;
  for (from piece) fn enemies:
    if fn const alias #piece #from var king:
      return #from;
    endif;
  next;
  return false;
endsub;
def checked sub checked #0;

This code would exit right away with an error message if the subroutine, which was called by the function here, got passed an empty space. I then looked at completed games using the same include file, and they did not exit with the error message. So, I got rid of this code and modified the function, tested Ultima again, and it still worked for both actual checks and for moves that would move the King into check.

With that change made, I ran the speed tests again and got these results:

Elapsed time: 1.0438919067383 seconds

Elapsed time: 0.46452307701111 seconds

Elapsed time: 1.013090133667 seconds

Elapsed time: 0.48957395553589 seconds

Elapsed time: 1.1313791275024 seconds

Elapsed time: 0.49660110473633 seconds

In each pair the subroutine is first, and the function is second, and in each case the function takes less than half the time. In both this case and the previous one, these tests were done on the opening position in Chess, in which the King is not in check, meaning that it checks for check from every enemy piece without exiting early.


Rococo. A clear, aggressive Ultima variant on a 10x10 ring board. (10x10, Cells: 100) (Recognized!)[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Sun, May 12 10:39 PM UTC in reply to NeodymiumPhyte from 08:35 PM:

I asked David Howe about the situation where a Chameleon can capture a Cannon Pawn by hopping over an enemy Long Leaper, and he says "The Long Leaper is not captured. The Long Leaper capturing move requires moving to a vacant square."


The Fairychess Include File Tutorial. How to use the fairychess include file to program games for Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Sun, May 12 10:29 PM UTC:

The changes to Game Courier I described here were for the purpose of writing a checked function that would do the same job as the checked subroutine but even faster. This is for the sake of illustrating the gains in speed of using functions rather than subroutines when a function will do the job. Here's the code for the subroutine and the function:

sub checked king:
    my from piece;
    local movetype;

    set movetype CHECK;
    if isupper cond empty var king $moved space var king:
        def enemies onlylower;
    else:
        def enemies onlyupper;
    endif;
    for (from piece) fn enemies:
        if fn const alias #piece #from var king:
            return #from;
        endif;
    next;
    return false;
endsub;

def checked anytrue lambda (fn const alias #0 var key var king) 
cond isupper cond empty var king $moved space var king (onlylower) (onlyupper) 
=movetype CHECK 
=king;

I have tested the function out in Ultima, because its stalemated subroutine is not widely used in other presets, and its piece functions make use of the movetype value to determine whether it is a regular move or a checking move. Things appear to be working in Ultima. In speed tests comparing 1000 repetitions of each, the function is around twice as fast. In these results, the first, third, and fifth are the subroutine, and the second, fourth, and sixth are the function.

Elapsed time: 0.92847084999084 seconds

Elapsed time: 0.45569705963135 seconds

Elapsed time: 0.87418103218079 seconds

Elapsed time: 0.46827101707458 seconds

Elapsed time: 1.1367251873016 seconds

Elapsed time: 0.65254402160645 seconds

Game Courier History. History of the Chess Variants Game Courier PBM system.[All Comments] [Add Comment or Rating]
🕸💡📝Fergus Duniho wrote on Sun, May 12 08:53 PM UTC:

I made a change to the following functions that can run lambda functions on array values: aggregate, allfalse, nonetrue, alltrue, anyfalse, anytrue, any. These will now have access to the variable key, which will contain the key of the array value currently passed to the lambda function. This should be accessed with the var keyword to make sure that a previously defined variable is not being used.

To prevent expressions using these from changing the value of a previous variable called key, I had to raise the scope of every expression. But to get this to work, I had to rewrite each built-in function that exited the PHP function for evaluating expressions with a return. Instead of using return, I had each one set $output to a single element array with the return value, and I set $input to an empty array so that the condition on the while loop would be false. Doing this makes sure that it decrements the scope before exiting the function.

Raising the scope of an expression also makes sure that the mechanism for adding named variables to a function cannot be used in an expression to set a variable that lasts beyond the expression. The following code prints 6468, then it prints 63. This is because it raises the scope for the assignments in the expression, and when it completes the expression, it closes that scope.

set o 9;
set y 7;
set pp * var o var y =o 98 =y 66;
echo #pp;
print * #o #y;

Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Sat, May 11 06:14 PM UTC:

I noticed today in the comments section that Smess was being given the description for Take the Brain. So, I made some corrections to make sure that the correct description was given for the name it was paired up with in IndexEntry. In the comments section, the primary name and description should now be used. In queries of the database on the names of games, each description will now show up for the name it goes with. On the What's New page, the name should be the primary name, and the description should be the Whatsnew text if it is available. Otherwise, it will fall back to using the primary description. All of this now works correctly for Smess, All the King's Men, and Take the Brain, though I have not tested other games with multiple names.


Smess. (Updated!) Produced and sold in the early 70's by Parker Brothers. Arrows on squares determine direction pieces can move. (7x8, Cells: 56) (Recognized!)[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Sat, May 11 05:03 PM UTC in reply to Fergus Duniho from 12:38 AM:

Because the Ivorytower pieces looked a little small on the board, I reduced the size of the board from 83x83 squares to 73x73 squares. The original board had 83x73 squares to give it a more square shape with a 7x8 layout, but the 73 pixel width works better for the Ivorytower pieces, because they can now fully cover up the oval on some spaces that names the piece starting from that position. I also tried 60x60 spaces, as that is the size used in Storm the Ivory Tower, but the Blue Brain was covering up too much of the forward arrow on its space. So I reverted to 73x73.

While the Ivorytower pieces do look better, they are still rough around the edges. and I think they would look better as SVG pieces.


🕸📝Fergus Duniho wrote on Sat, May 11 12:38 AM UTC in reply to HaruN Y from Fri May 10 01:43 AM:

I got your diagram to display correctly and added it to the page with some modifications. To make the board display correctly without tiling, I removed the firstRank assignment and set borders to 0. I replaced the graphics with ones I created for Smess. The board is a stretched version of one I made for Game Courier, and the pieces are the ones I made for Storm the Ivory Tower, which have smoother edges. I set useMarkers to 1 to stop it from changing the background color of a space when highlighting it, but this doesn't work for moves made by the opponent. Since it is important to not hide the arrows on the board, it would be helpful if useMarkers would also change how the opponent's moves are highlighted.


🕸📝Fergus Duniho wrote on Fri, May 10 09:30 PM UTC in reply to Fergus Duniho from 09:10 PM:

I created and used a new board with 83x83 spaces, and I set squareSize to 83, but now the board is starting halfway into the first rank and tiling on the right side. What can I do to fix that?


🕸📝Fergus Duniho wrote on Fri, May 10 09:22 PM UTC in reply to Fergus Duniho from 09:10 PM:

I changed the board image to the one that goes with the pieces, and it looks a lot better, but there are still some alignment issues. The spaces on the board are rectangular with a width of 83 and a height of 73, but the squareSize parameter seems to expect one value that gets used for both height and width. Is there any way to specify height and width separately? In the meantime, I'll make a resized copy of the board with square spaces.


🕸📝Fergus Duniho wrote on Fri, May 10 09:10 PM UTC in reply to Fergus Duniho from 09:06 PM:

Also, I added the same code to the Smess diagram, and it is now tiling with the pieces on it. Since I made those pieces for a larger board, I think the board image and the pieces are not at the same scale.


🕸📝Fergus Duniho wrote on Fri, May 10 09:06 PM UTC in reply to H. G. Muller from 08:02 PM:

For some reason this does not work anymore. The I.D. on the Eurasian Chess page also lost its background, and I am sure this worked before. Is there some global style definition now that gives elements a background color?

Looking at it with Web Developer Tools in Firefox, I see that TABLE TR has the background-color value of var(--nav-bgcolor), and when I turn it off, the background image shows up. With that in mind, I added this to the Eurasian Chess page, and that fixed it:

<STYLE>
TABLE#board0 TR {background-color: inherit;}
</STYLE>

Would it be a good idea to add this to global.css?


Game Courier Logs. View the logs of games played on Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Fri, May 10 04:09 PM UTC in reply to H. G. Muller from 02:54 PM:

The reliable method would try out all pseudo-legal moves, and then generate opponent moves in each of the resulting positions, to see if any of those captures the King. All opponent moves will have to be tried to conclude the move is legal (which usually is the case), and on a large variant this can take very long (to the point where GC aborts the GAME-code execution).

Thanks to GAME Code being an interpreted language written in another interpreted language, it is not as quick at things compiled languages would do more quickly, and it will sometimes exceed the time limit that PHP imposes on script execution. This makes optimizations and short cuts more important, and in hand-written code, I have done this. See my previous comment about how I handled the spotting of check in Ultima as an example.

In automatically-generated code, it might be harder to get in the optimizations needed for particular games. So I would suggest a compromise between your quick method and your reliable method. Flag pieces that can capture a piece without moving to its space, and use your reliable method on these while just checking if other pieces can move to the King's space.


Smess. (Updated!) Produced and sold in the early 70's by Parker Brothers. Arrows on squares determine direction pieces can move. (7x8, Cells: 56) (Recognized!)[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Fri, May 10 03:56 PM UTC in reply to HaruN Y from 01:43 AM:

This isn't showing up well on any browser or OS I've seen it on. On my iPad, I see the arrowed board both above and below the blank 7x8 board with the pieces, and the one above is tiled. On Android and Windows, the tiled board is not appearing at the top, but the pieces are still not appearing on the same board as the arrows.


Game Courier Logs. View the logs of games played on Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Fri, May 10 01:16 PM UTC in reply to H. G. Muller from 05:58 AM:

You did not get the point. Does the preset say 'check' when you check with any other piece than an Advancer? I think it doesn't. So then this has nothing to do with the piece being an Advancer.

I dug back into this thread to find the preset he was talking about. He linked to a particular game in which neither Advancer checked the opponent's King. Continuing this game by choosing Annotate and then Move, I played some moves to get a White Flying Dragon to check the Black King, and when I did, it said "check!". After moving the King out of check, I tried to move White's Advancer, but no legal moves are being highlighted on the board for it. However, its legal moves do show up in the Moves field, and when I tried one, it worked. At the top of the Moves field, I see the legal move "A e1-#to; A #to-b1". I think this is not a properly formatted move, and it may be interfering with the ability to recognize the Advancer's legal moves. Also, when I entered it, it did not recognize it as legal, and it gave the error message "#to is not a valid square".

Here are the moves to the position in question so that you can see what's going on.

1. P f2-f5 
1... p f9-f6 
2. P e2-e4 
2... p e9-e7 
3. F i1-h3 
3... f i10-h8 
4. P i2-i3 
4... p d9-d8 
5. B h1-i2 
5... c g10-f7 
6. C d1-f3 
6... f b10-c8 
7. C g1-e3 
7... c d10-f8 
8. K f1-i1 
8... p g9-g7 
9. P b2-b3 
9... c f8-e5 
10. P d2-d4 
10... c e5-f8 
11. B c1-b2 
11... a e10-h7 
12. F b1-e2 
12... p i9-i8 
13. P g2-g5 
13... c f7-e8 
14. P g5-g6 
14... a h7-f9 
15. P c2-c4 
15... p b9-b6 
16. F h3-g2 
16... c e8-d7 
17. P d4-d5 
17... f c8-d6 
18. F e2-h3 
18... p c9-c7 
19. C f3-e6 
19... c d7-e6 
20. P d5-e6 
20... p j9-j8 
21. B b2-a3 
21... b c10-a8 
22. B a3-d6 
22... p e7-d6 
23. R h1-f1 
23... p j8-j7 
24. F g2-d3 
24... b h10-j8 
25. C e3-g1 
25... f h8-i6 
26. P j2-j3 
26... p d8-d7 
27. P a2-a5 
27... p b6-a5 
28. R a1-a5 
28... b a8-b9 
29. P e6-d7 
29... f9-e8;@-d7 
30. C g1-a7 
30... f i6-h4 
31. C a7-d8 // - check! -
31... k f10-f9

Just click on Annotate for Butterfly Chess and paste these in to see the same position.


🕸📝Fergus Duniho wrote on Thu, May 9 10:18 PM UTC in reply to Kevin Pacey from 08:57 PM:

Yes, I originally would have thought when an Advancer made a move that threatened a King, an enforcing preset would automatically announce check.

However, maybe the Advancer, being an Ultima-like piece, does not actually make a check in an Ultima-like game (which Butterfly Chess is not)?

So I now ask, is that the usual assumption that Applet generated preset code makes for every CV put through the generating process?

I don't know how a generated preset works, but the checked subroutine I use in the fairychess include file normally checks for captures by displacement by checking if each enemy piece on the board can move to the King's position. This would not normally work with Ultima pieces, which do not normally capture by displacement, but I have managed to use this subroutine with Ultima without modifying it. First, let's look at the subroutine:

sub checked king:
    my from piece;
    local movetype;

    set movetype CHECK;
    if isupper cond empty var king $moved space var king:
        def enemies onlylower;
    else:
        def enemies onlyupper;
    endif;
    for (from piece) fn enemies:
        if fn const alias #piece #from var king:
            return #from;
        endif;
    next;
    return false;
endsub;

The key to working with Ultima is that it sets movetype to CHECK. With this in mind, I have written functions for Ultima pieces like this:

def Black_Withdrawer fn join "Black_Withdrawer_" var movetype #0 #1;

Depending upon the value of movetype, it will call either Black_Withdrawer_MOVE or Black_Withdrawer_CHECK, which I have defined separately and differently. Thanks to setting movetype to CHECK, the checked subroutine will use the *_CHECK functions for Ultima pieces. Instead of going through a normal move, one of these functions will check whether the piece at the first coordinate can capture the piece at the second. For example:

def Black_Withdrawer_CHECK 
empty where #frm - file #frm file #to - rank #frm rank #to
and == distance #frm #to 1
and not near #frm I 1
=frm =to;

This first makes sure that the piece is not next to a White Immobilizer (designated as I). It then verifies that the two spaces are adjacent. Calculating the direction away from the piece at #to, it checks whether there is an adjacent empty space in that direction. If there is, it returns true.


Crossroads. Crossing the diagonals generate figures. (9x9, Cells: 81) [All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Thu, May 9 09:56 PM UTC in reply to Gerd Degens from 07:12 PM:

Is this perhaps a matter of opinion?

I don't think effective communication is a matter of opinion. One thing you're not taking into consideration, perhaps because you don't know of it, is the previous usage of an inverted King image for the Anti-King in Anti-King Chess, which can be won by completely unchecking your opponent's Anti-King. When I see an inverted King, that's the piece I think of.


🕸Fergus Duniho wrote on Thu, May 9 07:07 PM UTC in reply to Gerd Degens from 06:44 PM:

That is precisely why!

But it fails to do it.


🕸Fergus Duniho wrote on Thu, May 9 06:23 PM UTC in reply to Gerd Degens from 05:36 PM:

Calling an inverse king symbol 'Man' goes against the grain.

Why use an inverse King symbol when one of your goals is to make it clear that this piece does not have the same status as a King?


🕸Fergus Duniho wrote on Thu, May 9 05:32 PM UTC in reply to Gerd Degens from 04:54 PM:

In the selection table of the PTA, 'Kinginv' appears under the heading 'name'.

In that table, the name of any piece without a Betza code provided for it appears to be based on the file name.


🕸Fergus Duniho wrote on Thu, May 9 05:29 PM UTC in reply to Bob Greenwade from 04:51 PM:

My impression is that it's an icon name, not a piece name.

Yes, it means inverted King, which is exactly what the image is of.


🕸Fergus Duniho wrote on Thu, May 9 04:29 PM UTC in reply to Gerd Degens from 04:14 PM:

I wanted to keep the term king, because it's a piece that can move like a king, but without the status.

But Kinginv is not a word, and the name suggests something that may still have the status of a King. I would mention the common names, but Bn Em already did that.


Game Courier. PHP script for playing Chess variants online.[All Comments] [Add Comment or Rating]
🕸💡📝Fergus Duniho wrote on Thu, May 9 04:12 PM UTC in reply to Aurelian Florea from 06:59 AM:

You need code in your Post-Move sections to control what is allowed on the first turn. Setting legal moves in the Post-Game section is not enough, because these will only be used for which legal moves are highlighted for the player. They will not control which legal moves are allowed.


Play-test applet for chess variants. Applet you can play your own variant against.[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Sun, May 5 04:59 PM UTC in reply to H. G. Muller from 08:18 AM:

The only thing I am still in doubt about is whether the current betza.txt include file on which the PTA-generated code relies tests for a move being the final one in a safe and reliable way. Because it uses mln for the test rather than turn.

I have just added thismovenum and maxmovenum. These will return $mline[$mln]->movenum and $mline[$maxmln]->movenum. It's likely that maxmovenum will be returning the same value as movenum, which returns $movenum, but using it will add clarity to your code.


About Game Courier. Web-based system for playing many different variants by email or in real-time.[All Comments] [Add Comment or Rating]
🕸💡📝Fergus Duniho wrote on Sun, May 5 04:34 PM UTC in reply to Daniel Zacharias from 03:38 PM:

You're using k/K for the general, but the code you copied is using g/G. So kpos and Kpos are not being updated.


🕸💡📝Fergus Duniho wrote on Sun, May 5 01:16 PM UTC in reply to Daniel Zacharias from 12:38 PM:

Your link is missing a query string.


Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Fri, May 3 10:33 PM UTC:

The print color scheme now has its own small logo too. Since the big logo included 19th century black and white artwork of Chess pieces, I chose a more retro style that displays fairy pieces by changing the orientation of Chess piece images. According to a section of Anthony Dickins' A Guide to Fairy Chess, the inverted queen is the grasshopper, and the reclining bishop is the unicorn.


🕸📝Fergus Duniho wrote on Fri, May 3 10:28 PM UTC in reply to HaruN Y from 04:43 AM:

I have changed forpersonid to author in the link, and it now works.


Play-test applet for chess variants. Applet you can play your own variant against.[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Fri, May 3 06:05 PM UTC in reply to H. G. Muller from 05:45 PM:

if == 0 $mline[$mln]->movenum:

That is mixing GAME Code with PHP. GAME Code does not support classes with properties or write out array elements with brackets, and it doesn't provide read access to $mline. But you can use the value of turn with your knowledge of which side you're concerned with to determine where you are in a game.


Glinski's Hexagonal Chess. Chess on a board made out of hexagons. (Cells: 91) (Recognized!)[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Fri, May 3 05:43 PM UTC in reply to H. G. Muller from 05:25 PM:

I am not familiar with this technique, but a problem could be that it is not just about positioning the images, but also about translating mouse clicks to cell coordinates. (Which must also work for empty cells, for entering non-captures.) In the table version I have attached event handlers to the cells for this.

With grid, you would use a <div> tag instead of a <td> tag for each space, and you could attach event handlers to it just as easily. What I have done in Game Courier, though, is place a transparent image over each empty space, as I have attached event handlers to the piece images.


Play-test applet for chess variants. Applet you can play your own variant against.[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Fri, May 3 05:35 PM UTC in reply to H. G. Muller from 05:20 PM:
set all == mln $maxmln;          // indicates last move

Note there is no $ there, so we might be talking about different things, and this one might be a legacy variable.

This operator just outputs the value of $mln.

I cannot image how this would work if mln was not the current move number.

It works because you are comparing mln with its maximum value. When there are comments, $maxmln will be greater than any move number, but it will be no higher than mln will eventually reach.


Glinski's Hexagonal Chess. Chess on a board made out of hexagons. (Cells: 91) (Recognized!)[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Fri, May 3 05:20 PM UTC in reply to H. G. Muller from 08:19 AM:

The I.D. represents the board through a HTML table,

Game Courier used to use HTML tables for hexagonal boards, but I gave up on this in favor of using either CSS with a board image or drawing the board image. This reminds me that I was working on getting CSS to work with a generated board image so that you could view each position of the game without reloading the page, but I haven't completed that. I think I had two different approaches and wasn't sure which one to go with. I either wanted to change how I generated the board so that the image would be perfectly symmetrical, or I wanted to modify the code to work with the asymmetrical boards I was already generating. I lost sight of what I was doing when I got caught up with other projects.

in theory it should be possible to create a table with a masonry-like tiling, shifting each subsequent rank by half a cell.

I imagine this would be easier to do with CSS grid, because, as far as I know, table columns remain vertical.

I have tried this, though, and it works to some extent. But for reasons that I do not grasp yet it also changes the height of the ranks in a way that I could not control.

Using grid would probably help you avoid this problem too. With grid, you should be able to make one column or row diagonal, though I have not yet tried using grid with hexagonal boards. My CSS code for hexagonal boards uses absolute positioning, as grid was not yet part of CSS when I wrote the code. Anyway, absolute positioning is another alternative to using tables.


Play-test applet for chess variants. Applet you can play your own variant against.[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Fri, May 3 04:59 PM UTC in reply to H. G. Muller from 08:55 AM:

I think the variable 'mln' gives you the current move number in the Post-Move sections.

It does not. I have made that mistake too and had to correct it. To use $mln to get the move number, you need to get $mline[$mln]->movenum. $mline is an array with a separate entry for each line of the movelist, but besides containing actual moves, it contains comments. $mln is the index that a line has in this array, but when some lines are comments, it will go out of sync with the move number.

GAME Code has turn, which will return $mline[$mln]->turn, but it doesn't currently have anything returning $mline[$mln]->movenum.


Glinski's Hexagonal Chess. Chess on a board made out of hexagons. (Recognized!)[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Fri, May 3 04:43 PM UTC in reply to Daniel Zacharias from 03:08 AM:

The Official Glinski Coordinates preset has CSS rendering which isn't working right for hexagonal games

The board image it was using had two separate elseif clauses dealing with it in a long series of elseif clauses in image_dimensions.php, and changes I was making to the second one had no effect. But when I noticed that it had two and combined them into one, I was able to set a value for $offy that worked for the board.


Glinski's Hexagonal Chess. Chess on a board made out of hexagons. (Cells: 91) (Recognized!)[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Fri, May 3 02:30 AM UTC in reply to HaruN Y from Thu May 2 02:56 PM:

Is it possible to make an Interactive Diagram use a hexagonal board?


Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Thu, May 2 07:42 PM UTC in reply to Fergus Duniho from Wed May 1 09:17 PM:

I may make a logo for it with some of Tenniel's black and white illustrations from Through the Looking-Glass, though I'm open to other ideas.

I have now done that except that I cropped and divided one illustration instead of using two separate illustrations. Also, most of the small piece images I used are based on characters Alice encounters in Lewis Carroll's books.


Featured Chess Variants. Chess Variants Featured in our Page Headers.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Thu, May 2 01:55 AM UTC:

Glinski's Hexagonal Chess is the featured variant for May, 2024.


🕸📝Fergus Duniho wrote on Wed, May 1 09:23 PM UTC in reply to Lev Grigoriev from 06:12 PM:

Hey! New month started!

Oh, right. I was focused on updating the color schemes. I should exercise now, but I'll remember to do this soon.


Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Wed, May 1 09:17 PM UTC:

The color scheme code I was working on yesterday and into today is now on the site. As I mentioned before, it will now change the theme with JavaScript as long as JavaScript is enabled. This is done mainly as a backup for older browsers that do not support :has() in CSS. It uses both JavaScript and CSS to change the color scheme so that if one method fails, the other one might still work. Generally, the CSS method will fail on older browsers, and the JavaScript method will fail if someone has JavaScript disabled.

One new feature is the Print color scheme. This is a more minimalist version of the Light color scheme. I may make a logo for it with some of Tenniel's black and white illustrations from Through the Looking-Glass, though I'm open to other ideas. For now, it uses the same logos as the Light color scheme.

Internally, I have moved the color scheme CSS to colors.css, where it is better organized and more maintainable than before. First, it creates individual custom properties for each color in each color scheme. The light ones begin with --light-, the dark ones with --dark-, etc. Since it has to define each color scheme multiple times for different selectors, it defines them in terms of the individual custom properties already created. So if I decide to change a color, there is now only one place it has to be changed.

Also, this provides page authors with the ability to customize color schemes for a particular page. By adding a style section in which you add custom properties to :root, you can rewrite individual values for particular color schemes.


🕸📝Fergus Duniho wrote on Wed, May 1 12:44 AM UTC:

On the page /index-test.html, I have augmented the CSS implementation of the color schemes with a JavaScript implementation. The CSS implementation works without JavaScript, but it requires the use of :has(), which earlier browsers do not support. The JavaScript implementation is working on both my Kindle browser and on both Chrome and Edge on my iPad 2, though the latter two require you to save your change before it takes effect. I don't think there are browsers more primitive than these that still need to be supported. By providing both a CSS and a JavaScript way to change the color scheme, this expands the number of browsers it will work well on. I plan to add the code for this to the site tomorrow. In the meantime, try it out and let me know how it works for you, particularly if you have some older device I am not using.


Hannibal Chess with Manticore and Falcon. Expansion for hannibal chess. (10x9, Cells: 90) [All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Tue, Apr 30 03:43 PM UTC in reply to Aurelian Florea from 06:11 AM:

I could not figure out what closing tag you were mentioning.

I already fixed that bug, and it was in my code, not yours.

This ID still does not work properly!

I tested it in Safari, Edge, and Firefox this morning, and it was working in all of them, though I did have to reload the page in Firefox before the board would display.


Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Tue, Apr 30 01:58 AM UTC in reply to Daniel Zacharias from Mon Apr 29 09:52 PM:

When I go to any person information page and try to view unpublished submissions, it just shows my own submissions.

Okay, I corrected that.


Waffle Chess with Gryphon and Falcon. Expansion for waffle chess. (10x9, Cells: 90) [All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Mon, Apr 29 06:45 PM UTC in reply to Aurelian Florea from 03:59 PM:

There was a typo in implementing a new property I had added. I added the displayPieces property, which when set above zero will display the piece table when the page loads. This much worked as it should, but when it was not set, it omitted the closing > in the tag, which caused what followed it to not be displayed.


Game Courier. PHP script for playing Chess variants online.[All Comments] [Add Comment or Rating]
🕸💡📝Fergus Duniho wrote on Sat, Apr 27 07:50 PM UTC in reply to Jean-Louis Cazaux from 05:52 PM:

It's important to maintain backwards compatibility, and anyone who doesn't like the name of Aanca is free to use a different name with an alias.


Hectochess. 10x10 variant that can be played with 2 mismatched Chess sets.[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Tue, Apr 23 06:54 PM UTC in reply to A. M. DeWitt from 06:34 PM:

For some reason, it cannot find the description even though the path to that file is correct, but I'm not really concerned about that.

It wasn't prepending ROOT to the filename. So it was actually incorrect. I have now fixed that.


🕸Fergus Duniho wrote on Tue, Apr 23 04:57 PM UTC:

I fixed the PHP script behind this page to display the description, rules, and credits for this page, but it could not find some of the expected files.


Play Chess Variants with Jocly. Missing description[All Comments] [Add Comment or Rating]
🕸Fergus Duniho wrote on Tue, Apr 23 04:25 PM UTC in reply to H. G. Muller from 12:17 PM:

Therefore Fergus created separate HTML pages for individual variants, which embed the Jocly applet preconfigured to run the corresponding variant, with a rule description. The overview page you refer to contains links to those individual game pages.

While I used to make separate HTML pages for individual variants, I replaced this practice with a PHP script that gets called through a semantic URL whose relative part starts with "/play/jocly/". If you want to review its code to see how it works, you can find the script at "/play/jocly/control.php". It relies on certain files being in place to display the description, rules and credits. It should work with games that have not been indexed yet, and if you do use it with unindexed games, you can, as an editor, add them to the index.


Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Tue, Apr 23 04:10 PM UTC in reply to Lev Grigoriev from 09:04 AM:

Please remove these unneeded lines from Edit Metadata also. I’ve written new page, thank you, but when I tried to revert it to Members-only, error repeated. It shows that I’m veteran contributor with nine or more submissions, so I cannot publish more if I have nine submissions to review (even if it’s not).

While it was giving you the same error message, it wasn't due to extra code again. This time, another variable was undefined, which caused its counts of the database to return the wrong values, and the solution was to add a new line assigning its value.


🕸📝Fergus Duniho wrote on Tue, Apr 23 01:17 AM UTC in reply to Lev Grigoriev from Mon Apr 22 05:35 PM:

There were a few lines of code that were held over from an earlier version of the code, and these lines used an undefined variable. The result was $itemid being set to just "MS". Removing these lines of code fixed the problem.


Game Courier Developer's Guide. Learn how to design and program Chess variants for Game Courier.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Mon, Apr 22 06:16 PM UTC in reply to Daniel Zacharias from 05:39 PM:

I'm sure there's a reason for this, but why is it that having legality defined for move highlighting isn't enough to have legal moves enforced?

  1. Rule enforcement was a feature before showing legal moves was. Instead of replacing the standard method for rule enforcement, calculating all possible legal moves ahead of time was done as an extra step.

  2. Additionally, moves sometimes had side effects that were not explicitly mentioned in the notation for a move, such as en passant capture in Chess or changing the side of a piece and placing it in hand for Shogi. This imposed the requirement of running code for the actual move when it was made.

  3. Because calculating all possible legal moves is more expensive than just calculating whether one move is legal, it is done only in the Post-Game section. So, if rule enforcement depended upon the calculation of all possible moves for each turn, it would work only in on-going games made one move at a time, or it would have to be repeatedly done in the Post-Move sections, which would prolong the calculation of whether a series of moves were all legal. The way it currently works, it evaluates the legality of a series of moves much more efficiently than it would if it had to calculate all possible moves after each move. For the sake of efficiency, which kind of matters in an interpreted language written in another interpreted language, it makes sense to calculate all possible legal moves only when there is a choice of which move to make. For past moves, calculating all this is just overkill.

[Edit: combined 3 and 4]


Home page of The Chess Variant Pages. Homepage of The Chess Variant Pages.[All Comments] [Add Comment or Rating]
🕸📝Fergus Duniho wrote on Mon, Apr 22 11:41 AM UTC in reply to Lev Grigoriev from 03:57 AM:

That’s not what I meant. I was looking for Reche's Super Faceoff Masquerade and could not find it. Please be clear about what you were doing and walk me through it step by step.


🕸📝Fergus Duniho wrote on Sun, Apr 21 10:10 PM UTC in reply to Lev Grigoriev from 08:02 PM:

I have not located the page mentioned in your screenshot. What is its URL? If you were attempting to create a new page, please make that clear. I need every relevant detail when you make a bug report.


🕸📝Fergus Duniho wrote on Sun, Apr 21 09:56 PM UTC in reply to Lev Grigoriev from 07:58 PM:

Hey, it seems like both logos in dark & darker mode have the same silver moon image in them.

They do not. One is from the Motif Shogi set, and one is from the Symbolic Shogi set.

Can I suggest one replacement in darker logo? – change moon to khon:

No, the moon, as a symbol of the night, is representative of the color scheme. But I might replace it with another moon-themed piece, such as the Alfaerie Mage. Then I might replace another piece with a Kanji Shogi piece.


🕸📝Fergus Duniho wrote on Sun, Apr 21 04:21 PM UTC in reply to Lev Grigoriev from 07:40 AM:

This should be fixed now.


🕸📝Fergus Duniho wrote on Sun, Apr 21 04:00 PM UTC in reply to Bob Greenwade from 02:40 PM:

As it happens, two of the options I would've given over Champion are Cardinal and Camel.

I have avoided using Cardinal or Chancellor for C, because the Cardinal is also known as an Archbishop, Princess, Paladin, and other names, and the Chancellor is also known as Marshall, Empress, and other names. I was initially using the Alfaerie Camel, but in looking over your pieces, I decided I liked your Champion better than the Alfaerie Champion.

And since I'm mentioning it, where you put the Fortress I would've suggested something more whimsical or offbeat:

I was going for something more suggestive of a Chess variant piece when seen out of context. A doubled-up Rook is one of those obvious designs that you, Jean-Louis Cazaux, and Musketeer Chess have all used.


🕸📝Fergus Duniho wrote on Sun, Apr 21 12:41 PM UTC in reply to Bob Greenwade from 03:51 AM:

The champion and phoenix were chosen to help spell cvp.


🕸📝Fergus Duniho wrote on Sun, Apr 21 02:09 AM UTC:

I have added new logos for the Darker color scheme. They feature a black cannon and a natural colored nightrider in the style of a winged horse. In the big logo on this page, the cannon was designed by Jean-Louis Cazaux and the nightrider by Bob Greenwade.


🕸📝Fergus Duniho wrote on Sat, Apr 20 06:51 PM UTC in reply to Bob Greenwade from 05:15 PM:

I followed the link to your thingiverse profile, but I didn't see all the pieces you have posted images of here in your comments. The closest I found to a Nightrider was the Zebrarider.

I figured out that you're packaging multiple pieces together, and I have to browse through each package to see them all.


🕸📝Fergus Duniho wrote on Sat, Apr 20 04:48 PM UTC in reply to Jean-Louis Cazaux from 01:40 PM:

I think I can work with the 3dviewer.net website, but I don't have a link to Bob's thingiverse account. Considering how many 3D pieces he designs, it would be a good idea for him to include a link to it in his profile.


🕸📝Fergus Duniho wrote on Sat, Apr 20 04:01 PM UTC in reply to Bob Greenwade from 03:37 PM:

Hopefully, brown works at least a little better.

It doesn't. The coloring is very splotchy, though more so on curved surfaces than on flat surfaces, as can be seen in this color image of a color scan of my Likebook Mars:


80 comments displayed

Later Reverse Order EarlierEarliest

Permalink to the exact comments currently displayed.