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 ]

Ratings & Comments

LatestLater Reverse Order EarlierEarliest
svg fairy pieces[Subject Thread] [Add Response]
Greg Strong wrote on Sun, Aug 2, 2020 12:55 AM UTC in reply to James Zuercher from Sat Aug 1 11:42 PM:

Hi James.

This is a work-in-progress. You can get the current group of completed pieces here:

https://www.chessvariants.com/graphics.dir/alfaeriePNG/GS-2020-07-28.zip

It does not contain the compound pieces, though, because they are being generated by combining the elements with H. G.'s renderer here: https://www.chessvariants.com/page/MSdiagram-editor-with-scalable-graphics

I am currently working on the "alternate" archbishop and chancellor, though, used here for example: https://www.chessvariants.com/play/pbm/drawdiagram.php?code=rw6wr%2Fclnbqkbnla%2Fpppppppppp%2F10%2F10%2F10%2F10%2FPPPPPPPPPP%2FCLNBQKBNLA%2FRW6WR&cols=10&scale=75&set=alfaerie-opulent&bcolor=804646&tcolor=FFFFCC&bsize=24&colors=6A8D8B+FFFFCC

I will post additional pieces as I complete them


James Zuercher wrote on Sat, Aug 1, 2020 11:42 PM UTC:

I have seen comments that indicate the alfaerie chess pieces are available in SVG format, but I cannot find a download for them. Can you please post a download url for these pieces. I am especially interested in the archbishop and chancellor compound pieces.


Shogi and legal moves[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Wed, Jul 29, 2020 12:49 PM UTC in reply to wdtr2 from 08:36 AM:

It was the modification I made to how push works. The stalemated subroutine in shogi.txt was using push to create an array of legal moves instead of using the setlegal command. I guess I wrote that subroutine before I created the setlegal command. Anyway, it was putting a null character at the beginning of the legalmoves array, and that threw off the JavaScript code, which didn't know what to do with that null character. So, I made a correction to push to make sure a variable is set before moving its scalar value to the first element of an array, since unset variables have the scalar value of null.


wdtr2 wrote on Wed, Jul 29, 2020 08:36 AM UTC:

I think there was a tweak somewhere. Shogi is not showing legal moves, nor does it allow you to move via mouse clicks.


GAME code table-driven move generator[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Tue, Jul 28, 2020 10:41 PM UTC in reply to H. G. Muller from 09:09 PM:

But what if I want to do it in a loop, to add the elements one by one?

I recently added better support for arrays. See this comment for details:

https://www.chessvariants.com/index/listcomments.php?id=39825

Is there a way to create an empty array?

Set it to an empty pair of parentheses, like so:

set ra ();

Can I push something to a so-far unused variable to create an array of one element?

Yes, there is a push command.

Can I push something to a scalar variable to make it an array of two elements?

I hadn't thought of that. You can now. The previous behavior was to hang the program without a helpful error message. So, changing that is not going to break anything.

Can I use setelem on a so-far unused variable?

Yes. You can now also use set. See the link above.


H. G. Muller wrote on Tue, Jul 28, 2020 09:09 PM UTC:

OK, that helps. My code now seems to work! When I move the King 3 steps to the left or right it automatically moves the Rook to the other side. Unless I move the King or the Rook back and forth first to destroy their virginity; then it just moves the King because it doesn't match any pseuo-legal castling. So that completes phase 2.

Next phase is to automate e.p. capture. This will again require a lot of new infra-structure, for handling the e.p. rights. In XBetza moves can be specified as rights-generating in several ways: a lame leap can generate e.p. rights on the square where it could be blocked, and slides can generate e.p. rights on every square they pass through. In the diagram it proved convenient to also use 'royal e.p. capture': e.p. rights created by moving a royal piece can be consumed by any capture, not just by pieces that have been defined as e.p.-capable. This then prevents the royal to pass through check. Castlings also create e.p. rights, even on the square the King starts from, to prevent castling out of check.

So moves can in principle create e.p. rights on a lot of squares, along a complex trajectory; XBetza would allow you to define a Griffon as e.p.-capturable piece. It seems thus best to create an array epsqrs, which contains all the squares with rights created in the previous move, and use match to test whether the current destiation is one of those.

This brings me to the following question:

How can I create an array in GAME code? I know I can write the elements in parentheses, but to use that there must be a fixed number of elements, all known in advance. But what if I want to do it in a loop, to add the elements one by one? Is there a way to create an empty array? Can I push something to a so-far unused variable to create an array of one element? Can I push something to a scalar variable to make it an array of two elements? Can I use setelem on a so-far unused variable?


🕸Fergus Duniho wrote on Tue, Jul 28, 2020 08:04 PM UTC in reply to H. G. Muller from 07:22 PM:

It seems the 0 at location 31 did not get into the array. That does not seem kosher to me...

That's now fixed. In some early preprocessing of the lines, it checked for an empty line, which would return true when the line equaled "0". I changed it to check the length of the string, and it now works.


H. G. Muller wrote on Tue, Jul 28, 2020 07:22 PM UTC:

I stumbled again on a mystery. I define this large array, and some code to print what is in it:

set legdefs
(0
1  1  0  1     1
1  1  1  1     2
1  1 -1  1     2
1  1  0  2   16577 // pawn(1)
1  1  1  1     4
1  1 -1  1     4
0
1  1  0 -1     1
1  1 -1 -1     2
1  1  1 -1     2
1  1  0 -2   16577 // pawn(32)
1  1 -1 -1     4
1  1  1 -1     4
0
//... snip ...
2 99 -1 -1    16
  99 -1 -1     2
2 99 -1  1    16
  99 -1  1     2
0);

set k 0;
do while < #k 100:
  print join #k join ". " elem #k #legdefs;
  inc k;
loop;
die "stop";

But what it prints is this:

...
20. 16577
21. 1
22. 1
23. 1
24. 1
25. 4
26. 1
27. 1
28. -1
29. 1
30. 4
31. 1
32. 1
33. 0
34. -1
...

It seems the 0 at location 31 did not get into the array. That does not seem kosher to me...


H. G. Muller wrote on Tue, Jul 28, 2020 09:00 AM UTC:

Now that the infrastructure for legality testing has been defined, we can pay attention to the heart of the move generator, the subroutine NextLeg. The first parameter of this indicate how many legs we will have yet to go. It is decremented every time the function recursively calls itself, and when it hits 0 we have completed the move, and can pass it to GotMove. Otherwise we have to retrieve the leg description from legdefs, and see if it is possible to move that way in the given position. The basic step of the leg is given, and the range specifies how many of those step we can maximally take. If this is 1, we are dealing with a leap. If it is larger, but the specified mode compells us to finish on a square with a particular occopant (friend or foe), there is still at most one way to do that. Only when the mode allows going to empty squares can we have more than one possibility to realize the leg, and even then the iso parameter can force the destination. But if we do have a 'free ride' we have to loop over all possible leg destinations, and if more legs follow, continue with the next leg from each of those. This happens for hook movers.

For phase 2 we only want to do castlings. These are encoded as two-leg moves, the first leg specifying a slide of the King that must end on the Rook. This is similar to a 'riendly capture' sliding leg, but still a special case in many ways: it must end in a specific location, the piece there must not have moved. So we have dedicated code for that, triggered by a special mode, only used for castling. Instead of following it by a new general leg through a recursive call, this dedicated code interprets the leg that follows by itself; the only info used from it is how many steps the King must move. Where the Rook will then reappear is implied by that.

sub NextLeg togo legindex startsqr cursqr locustsqr dropsqr iso:
  my range dx dy mode to tosqrs;
  // retrieve leg description (next 4 elements in 'legdefs')
  set range elem #legindex #legdefs;
  set dx elem + 1 #legindex #legdefs;
  set dy elem + 2 #legindex #legdefs;
  set mode elem + 3 #legindex #legdefs;
  verify not flag #startsqr or not & 64 #mode; // 64 = initial
  set tosqrs ray #startsqr #dx #dy;
  set r count #tosqrs;
  verify >= #range #r;
  set to elem dec #r #tosqrs;             // last square of ride
  set stopper space #to;                  // what is on it
  set side islower space #startsqr;       // whether we are black
  set fratricide cond #side islower #stopper isupper #stopper;
  if #fratricide:
    if & 8 #mode: // 8 = first leg of castling
      verify match #to #partners;         // ends at castling partner
      verify not flag #to;                // partner is virgin
      set locustsqr #to;                  // order its removal
      set to where #startsqr elem + 5 #legindex #legdefs 0;
      set dropsqr where #to - 0 #dx #dy;  // make it appear on other side of King
      gosub GotMove #startsqr #to #locustsqr #dropsqr #stopper 1;
    endif;
  endif;
endsub;

This code tests for virginity in two places. First, in the general code, it tests the moving piece when the mode indicates we are dealing with an initial move (which for conventional  castling will  be the case). Then in the dedicated it tests whether the castling partner is virgin. For these tests it uses flags with the name of the board squares. This assumes that in the HandleMove routine, ater each move, there will be a setflag #desti; to indicate the destination square no longer contains its original occupant. If this flag is not set, together with the fact that the square is occupied, it is a guarantee that the original piece is still on the square without having moved.


H. G. Muller wrote on Tue, Jul 28, 2020 06:52 AM UTC:

Move legality testing will be based on a move generator. This generates the pseuo-legal moves that are possible in the given position, always being fully aware of any side effects these moves might have. These moves are then compared to the input move, and if there is a match we know the input move was pseuo-legal. Normally we consider a move a match only if all the parameters ori, desti, promo, suicide, freedrop and dropped of the input move are equal to their counterparts orisqr, destsqr, locustsqr, dropsqr and unload of the generated move. But for moves with implied side effects we only match ori, desti and promo (the latter should be 0), and accept what the move generator specifies as side effects. E.g. for castling the locustsqr would be at the Rook to make it disappear, and the dropsqr would indicate where we must drop a Rook to make it reappear.

To make this process efficient, we generate only moves of the piece that according to the input is going to move. For moves that were already tested for legality before (now played for setting up the current position) we even take a short-cut on that: we only generate the moves with implied side effects, to calculate and perform those. The subroutine GenMoves will thus have three parameters: the piece type and start location from which its moves should be generated, and a Boolean that indicates whether we want all moves of the piece, or just those with implied side effects. In the latter case most pieces would of course have no moves at all; in orthodox Chess only the KIng (castling) and Pawns (e.p.) have moves with side efects.

sub GenMoves piece sqr all:            // generates moves for 'piece' on 'sqr' in current position
                                       // 'all' specifies whether we get only moves with side effects
  my index legcount;
  set side islower #piece;             // remember which side we are generating for
  set index fn #piece #all;            // function returns start of piece description in legdefs table
  set hit false;
  do:
    set legcount elem #index #legdefs; // the first element specifies the number of legs
    verify #legcount;                  // a 0 sentinel ends the list of moves
    inc index;                         // 'reads away' the leg count
    gosub NextLeg #legcount #index #sqr #sqr 0 0 0;
    set index + #index * 4 #legcount;  // skip to the next set of legs (= move)
  loop until #hit;
endsub;

The move descriptions come from the table legdefs, and where in this table the description of the given piece type starts is given by a function with the name of the piece type. This function has an additional argument, indicating whether we want all moves or just those with implied side effects. The latter will be found behind the former in the legdefs table, so that we can just start later in the table to get only those. Each move description will start with a number indicating how many legs the move has (where each leg is a leap or a ride). Each leg is then described by 4 numbers: range, sideway and vertical step, and mode. We call the subroutine NextLeg to interpret these. To get to the next move of a piece the table index then has to be incremented by 1 plus 4 times the number of legs. A dummy move with 0 legs indicates we are done with this piece, and ends the loop by terminating the subroutine though verify. A global variable hit can cause the loop to terminate early; there is usually no need to go on generating moves after we found the one we were looking for.

The routine NextLeg does the real work. It calls itself recursively in case there is more than one leg, to do the follow-up legs. Its first parameter controls the depth of this recursion, the next specifies where in legdefs to find the four numbers that describe the leg. Then follow a number of squares: the start square of the move, and the start square of the leg (which for the first leg are of course the same), then the squares for the side effects (starting at the default 0) locustsqr and dropsqr. Finally there is a parameter with which we can request an exact length of a ride when it is non-zero.

We will not go into the details of NextLeg now. When it succeeds in constructing the move according to the description in legdefs, it will eventually call a routine GotMove, passing it the parameters that describe the move and all its side effects. Because we will want to use the move generator for various purposes (e.g. testing whether a given move is pseuo-legal, regeneration of implied side effects, testing whether we can capture a royal piece, making a table of legal moves...), a global variable task will specify what this routine must do. For now we will only have 'task 1', regeneration of the implied side effects.

sub GotMove orisqr destsqr locustsqr dropsqr unload implied:
  switch #task:
    case 1:
      verify == #orisqr #ori and == #destsqr #desti;
      if not #implied: // explicitly specified side effects must also match
        verify == #locustsqr #suicide;
        verify == #dropsqr #freedrop;
        verify == #unload #dropped or not #dropsqr;
     else:            // no side effects must be specified when they are implied
        verify not #suicide and not #freedrop;
        if #locustsqr:
          capture #locustsqr;
        endif;
        set implieddrop #dropsqr;
      endif;
      set hit true;    // we found a matching pseudo-legal move
  endswitch;
endsub;

The move generator always specifies the side effects, and whether these are implied. If they are explicit, they will be automatically applied by Game Courier's execution of the input move. If they were implied, we perform any locust capture, and remember whether we should drop a piece somewhere, so we can do that later.

Why not immediately do all implied side efects? Well, we cannot always make the freedrop of a castling Rook before Game Courier has made the input move, as in some castlings the Rook then would clobber the King. So we must apply the freedrop after feeding the move to Game Courier.

sub HandleMove player:
  set mvs explode chr 59 thismove; // split at semicolons
  gosub ParseMove #player;         // syntax check and interpretation
  set task 1;
  set implieddrop 0;
  gosub GenMoves #mover #ori 0;    // only moves with implied side effects
  set k 0;
  do while < var k count var mvs:  // for all legs
    eval join "MOVE: " trim elem var k var mvs; // apply the move
    inc k;
  loop;
  if #implieddrop:                 // implied freedrop
    add #dropped #implieddrop;
  endif;
endsub;

Note that this code doesn't worry about promotions yet.


H. G. Muller wrote on Tue, Jul 28, 2020 05:17 AM UTC in reply to Fergus Duniho from Mon Jul 27 10:10 PM:

OK, great. That means all all issues encountered so far are solved now, and we are ready to continue. First a summary of where we are, because I was too optimistic in declaring phase 0 finished. The code shown befor turned out only to work for simple moves; Game Courier does not like it when you try to evaluate a composit move by putting "MOVE:" in front of it, and will complain the move is malformed in that case. So it is necessary to explode composit moves into an array mvs of simple moves, and have Game Courier perform these one by one in a loop. This exploding of moves had to be done anyway for parsing the move, but it is now done before we call ParseMove, and mvs is made a global variable, so that it will also be available inside ParseMove:

sub HandleMove player:
  set mvs explode chr 59 thismove; // split at semicolons
  gosub ParseMove #player;         // syntax check and interpretation
  set k 0;
  do while < var k count var mvs:  // for all legs
    eval join "MOVE: " trim elem var k var mvs; // apply the move
    inc k;
  loop;
endsub;

For phase 0 the call to Parsemove would not yet be there. The tested and debugged code for phase 1 is:

sub ParseMove player:
  my i j parts sqrs;
  set many suicide false freedrop false promo false;
  set parts explode ws trim elem 0 var mvs;            // split first move at space
  set i count var parts;
  if > var i 2:                                        // too many parts
    die "move must be piece ID plus board step";
  endif;
  set sqrs explode chr 45 trim elem dec var i var parts; // split last part at hyphen
  if != 2 count var sqrs:                                // must give 2 squares
    die "board step does not mention two squares";
  endif;
  set ori elem 0 var sqrs;                             // first is origin
  set desti elem 1 var sqrs;                           // second is dest
  if not onboard var ori or not onboard var desti:     // check if these are valid
    die "the board isn't that large";
  endif;
  set mover space var ori;                             // look what we move
  if != var mover elem 0 var parts and == 1 var i:     // input move mentioned another piece
    die "there is another piece there";
  endif;
  if not cond #player islower var mover isupper var mover: // it is not our piece
    die "no such piece there";
  endif;
  set j 1;                                             // prepare to do side effects
  do while < var j count var mvs:                      // for each of those
    set parts explode chr 45 trim elem var j var mvs;  // split them at hyphen
    if != 2 count var parts:                           // must give 2 parts
      die "malformed move " elem var j var mvs;
    elseif not onboard elem 1 var parts:               // second part must be valid square
      die "second leg goes off board";
    elseif onboard elem 0 var parts:                   // additional move for locust capture
      if != var desti elem 0 var parts:                // must start from destination of first move
        die "you can only continue with same piece";
      endif;
      if #suicide:                                     // for now only one side efect
        die "cannot have more than one locust victim";
      endif;
      set suicide var desti;                           // old dest was actually locust square
      set desti elem 1 var parts;
    elseif == var desti elem 1 var parts:              // drop on dest: promotion
      set promo elem 0 var parts;
    elseif == @ elem 0 var parts:                      // drop of empty: locust square
      if #suicide:
        die "cannot have more than one locust victim";
      endif;
      set suicide elem 1 var parts;
    else:                                              // drop of piece: unload
      if #freedrop:
        die "cannot kick more than one piece";
      endif;
      set dropped elem 0 var parts;
      set freedrop elem 1 var parts;
    endif;
    inc j;                                             // go on with next side effect
  loop;
endsub;

This extracts values for ori, desti, mover, promo, suicide, freedrop and dropped from the move. The first three from the (mandatory) first move. The others describe the optionally following moves of the turn, and are set to 0 by default. These values are not yet used in phase 1; the only observable effect is that the preset will now enforce turn order, as it no longer accepts moving of opponent pieces. It still accepts capture of own pieces, as XBetza can allow that. So this must be left for move generator to check out.

Next step is to take care of implied side effects: it should be possible (even mandatory) to enter castling and e.p. capture as a simple move. In phase 2 we will do this for castling. Phase 3 will then address e.p. capture, which is more complex, because it also has to address the creation of e.p. rights.

 


🕸Fergus Duniho wrote on Mon, Jul 27, 2020 10:10 PM UTC in reply to H. G. Muller from 08:46 PM:

Yes, flag #to should do what you want. ?#to should also now work, since I have placed variable evaluation into its own recursive function.


H. G. Muller wrote on Mon, Jul 27, 2020 08:46 PM UTC in reply to Fergus Duniho from 07:45 PM:

Wouldn't flag #to do what I want? Or is the flag operator just meant for things like flag a8 ?

An alternative would be not to use flags for this at all, but just an array. I woul have to set up my own mapping from square names to array entries by something like set index + * 100 rank #to file #to;


🕸Fergus Duniho wrote on Mon, Jul 27, 2020 07:45 PM UTC in reply to H. G. Muller from 06:34 PM:

To use the flags for testing whether a piece at a given location #to is virgin, I would have to test the flag with the name held in to. Would ?#to work for this?

Not presently. I need to separate variable evaluation into its own function and make it recursive, or at least mimic recursion with a loop. I'll look into that.


H. G. Muller wrote on Mon, Jul 27, 2020 06:34 PM UTC in reply to Fergus Duniho from 06:18 PM:

Ah, so this was just a very unlucky choice of variable naming. I was afraid there was something I completely misunderstood about the workings of var and #.

Another question: I had planned to use a flag for every board square, indicating whether a move had gone to that square. By doing setflag dest; on every move. Then we could be sure that the piece that is on it (if any) must have moved before. This because XBetza in principle could define initial moves on any piece.

I am starting to doubt now whether this can be used. To use the flags for testing whether a piece at a given location #to is virgin, I would have to test the flag with the name held in to. Would ?#to work for this?


🕸Fergus Duniho wrote on Mon, Jul 27, 2020 06:18 PM UTC in reply to H. G. Muller from 09:24 AM:

The problem was that player was an undocumented operator, and var player would not see player as the string "player". I'm not sure of what use it could be, since it returns the userid of the current player, which is useful only in email games. I don't think it would have any application for test games someone plays against himself. Because of that, and because it is undocumented anyway, I got rid of it.


H. G. Muller wrote on Mon, Jul 27, 2020 05:28 PM UTC in reply to Fergus Duniho from 05:14 PM:

player was (and still is) the formal parameter of the ParseMove subroutine. It received its value in the gosub call indirectly, through gosub ParseMove true; , which then does a gosub HandleMove #player; The debug prints I mentioned were inserted in ParseMove (because a cond var player ... expression appeared to give the wrong result).

The only thing I changed to get the current code is that it now does cond #player ..., and I deleted the debug print / printr.


🕸Fergus Duniho wrote on Mon, Jul 27, 2020 05:14 PM UTC in reply to H. G. Muller from 09:24 AM:

I don't have your old code to look at. In your current code, I do not see anyplace where you set a value for player. Since you were trying to use it with var or as #player, I assume it was a user variable. Also, $player is not an available system variable.


H. G. Muller wrote on Mon, Jul 27, 2020 09:24 AM UTC in reply to Fergus Duniho from Sun Jul 26 09:56 PM:

Yes, include "&submit=Edit" in the query string.

Great, that will be very helpful.

They cannot. Only some commands evaluate expressions, and gosub does not. Use #player instead.

I first had used #player , but then I noticed that the preset only allowed entry of moves for white, even when it said it was black's turn to move. Black moves were always rejected (by my ParseMove code) with the complaint that he wasn't moving his own piece. I figured that this was because #player was statically dereferenced in the Pre-Game section (where the ParseMove code is inserted), where white is on move.

[Edit] OK, I have got it working. But I don't understand why! The problem could be traced to the following:

printr player;
print join "var player=" var player;
print join "#player=" #player;

When the formal parameter player is passed as false in the subroutine call, the output is

false
var player=
#player=

as expected, as GAME code's default representation for true and false as the result o an expression appears to be 1 and the empty string, respectively. However, when the subroutine is called with arument true, it prints

true
var player=
#player=1

The value of var player is apparently not dependent on the actual value stored in player. Why is that? I understood that var is supposed to be more accurate than # in this respect.

Another issue: I get the error message solved

BANNED INPUT: P e3-e5; e5-e6 on turn 1:

You may not enter more than 4 move primitives in a move in this game.

Indeed I did setsystem maxmove 4. But how does it figure this input is more than 4 move 'primitives'? I count only 2 moves... Is each piece or coordinate a 'move primitive', and should I really set maxmove to 9 to allow one move, one promotion, one suicide and one freedrop?

This was due to continuing the loop over the partial moves after exploding thismove continued indefinitely, because there was no var in front of the loop index in the while condition. It is just that the error message is a bit confusing.


🕸Fergus Duniho wrote on Sun, Jul 26, 2020 09:56 PM UTC in reply to H. G. Muller from 08:44 PM:

Is there a way to edit a preset without Game Courier first attempting to execute the code?

Yes, include "&submit=Edit" in the query string.

Can the actual parameters of a subroutine call not be expressions like 'var player'?

They cannot. Only some commands evaluate expressions, and gosub does not. Use #player instead.


H. G. Muller wrote on Sun, Jul 26, 2020 08:44 PM UTC in reply to Fergus Duniho from 08:15 PM:

Ah, thanks! Is there a way to edit a preset without Game Courier first attempting to execute the code? It is really inconvenient if an accidental deletion could make the preset go in hiding this way...

I still don't understand how it could have happened in this case; the preset seemed to work fine until I stopped working on it. I wouldn't make any significant changes without immediately testing them. Perhaps something went wrong when I deleted a print statement I had used for debugging, and I accidentally deleted something else as well.

There is something else I don't understand either. I have two subroutines, HandleMove and ParseMove, each with formal parameter 'player'. I try to make one call the other:

sub HandleMove player:
  gosub ParseMove var player;
  eval join "MOVE: " thismove;
endsub;

But when I print 'player' in ParseMove (for debugging purposes) it prints 'var'!? Can the actual parameters of a subroutine call not be expressions like 'var player'?

 


🕸Fergus Duniho wrote on Sun, Jul 26, 2020 08:15 PM UTC in reply to H. G. Muller from 05:31 PM:

One line of your code in sanbox.php was missing a semicolon at the end. This caused it to not load. I added the semicolon by directly editing the file, and it loads now.


H. G. Muller wrote on Sun, Jul 26, 2020 05:31 PM UTC:

It seems I was too hasty: it is not fine at all. With 'sandbox' as name for the settings file it does not give me a blank page, but what it gives looks nothing like what I had made yesterday. It is another position with other graphics, all of the code has disappeared... It seems more that when the name of the settings file and the game are the same, and no file with that name exists, it just defaults to orthodox chess without any rule enforcement.

So the issue remains: the settings file 'sanbox', where I saved all yesterday's work on, doesn't exist anymore, or cannot be retrieved or some other reason.

The question is: how can this happen?


H. G. Muller wrote on Sun, Jul 26, 2020 09:43 AM UTC in reply to dax00 from 08:34 AM:

You are right! With d it works fine. Which is really weird, because the d was already missing when I typed the settings-file name when creating the preset. To access the preset yesterday I therefore had to use the link without a d, and this is the link that is in one of the earlier comments in this thread. Someone must have renamed the file.

Anyway, thanks. Now I can continue.


dax00 wrote on Sun, Jul 26, 2020 08:34 AM UTC in reply to H. G. Muller from 06:25 AM:

You left out a "d" in the last "sandbox". It works fine.


H. G. Muller wrote on Sun, Jul 26, 2020 06:25 AM UTC:

The link to the Sandbox preset stopped working ( https://www.chessvariants.com/play/pbm/play.php?game%3DSandbox%26settings%3Dsanbox ). When I click it, the "busy loading" indicator of the browser is on for a few seconds, and when it goes off the page is completely blank.

Any idea what could cause this? I have no idea how to progress now.


H. G. Muller wrote on Sat, Jul 25, 2020 10:26 PM UTC:

Well, that did not work quite as planned. For one, the # does not seem to work in subroutines; I had to replace it by var everywhere. What caused me the worst headache was the afct that origin and dest seem to be protected variables; everything worked fine upto the point where sqrs became an array (f3 f5), but after set origin elem 0 var sqrs; the value of origen was not the expected f3, but @ ! After I change the names to ori, desti and mover the preset worked again. At least to the point where it did not die, and executed the entered moves. I don't manage to print the variables to see if they obtained the expected values; the page where I printed them flashed away too fast to read. I suppose I would have to intentionally let it die to see it.

sub ParseMove player:
  my i j mvs parts sqrs;
  set many suicide false freedrop false promo false;
  set mvs explode chr 59 thismove;                    // split at semicolons
  set parts explode ws trim elem 0 var mvs;           // split first move at space
  set i count var parts;
  if > var i 2:                                       // too many parts
    die "move must be piece ID plus board step";
  endif;
  set sqrs explode chr 45 trim elem dec var i var parts; // split last part at hyphen
  if != 2 count var sqrs:                                // must give 2 squares
    die "board step does not mention two squares";
  endif;
  set ori elem 0 var sqrs;                            // first is origin
  set desti elem 1 var sqrs;                          // second is dest
  if not onboard var ori or not onboard var desti:    // check if these are valid
    die "the board isn't that large";
  endif;
  set mover space var ori;                            // look what we move
  if != var mover elem 0 var parts and == 1 var i:    // input move mentioned another piece
    die "there is no " elem 0 var parts " on " var ori;
  endif;
  if not cond var player islower var mover isupper var mover: // it is not our piece
    die "you have no piece on " var ori;
  endif;
  set j 1;                                            // prepare to do side effects
  do while < var j count var mvs:                     // for each of those
    set parts explode chr 45 trim elem var j var mvs; // split them at hyphen
    if != 2 count var parts:                          // must give 2 parts
      die "malformed move " elem var j var mvs;
    elseif not onboard elem 1 var parts:              // second part must be valid square
      die "second leg goes off board";
    elseif onboard elem 0 var parts:                  // additional move for locust capture
      if != desti elem 0 var parts:                   // must start from destination of first move
        die "you can only continue with same piece";
      endif;
      if var suicide:                                 // for now only one side efect
        die "cannot have more than one locust victim";
      endif;
      set suicide var desti;                          // old dest was actually locust square
      set dest elem 1 var
    elseif == desti elem 1 var parts:                 // drop on dest: promotion
      set promo elem 0 var parts;
    elseif == @ elem 0 var parts:                     // drop of empty: locust square
      if #suicide:
        die "cannot have more than one locust victim";
      endif;
      set suicide elem 1 var parts;
    else:                                             // drop of piece: unload
      if var freedrop:
        die "cannot kick more than one piece";
      endif;
      set dropped elem 0 var parts;
      set freedrop elem 1 var parts;
    endif;
    inc j;                                            // go on with next side effect
  loop;
endsub;

H. G. Muller wrote on Sat, Jul 25, 2020 05:38 PM UTC:

Phase 0 seems to work now. I create a preset Sandbox to try it out. (due to a faulty d key on my laptop the settings are saved in the file sanbox.) I notice this completely bypasses any checking on the entered moves; one can also move pieces of the opponent. When parsing the input move this thus also has to be checked.

Next is phase 1: testing whether the entered move could in principle be a valid move for a chess variant of the type that can be handled by the Play-Test Applet. These are simple moves (possibly performing replacement capture at their destination), moves that alter the piece type (promotions), moves that as a side effect remove one or two pieces from other squares, or make a piece appear on another square.

In Game Courier this can require entering a sequence of moves for one turn. We will enforce the convention that the first of these will always be a normal displacement of a piece of the player whose turn it is, like "P e7-e8". This can then be followed by putting a piece on the destination square on the first move ("Q-e8") to indicate a promotion. Such a ' drop move' should also be used to make a captured piece appear elsewhere. If a piece is captured as a side efect ('locust capture'), this can be indicated by dropping an empty square on top of it ("@-d4"). All the additional actions can thus be indicated through extra moves with the drop syntax; they just differ in where or what they drop.

We will allow one exception to this: a locust capture can also be entered by first making the capture in the normal chess way, moving to the location of the victim, and moving from there to the destination in a second 'normal' move. So additional board moves will be allowed, provided that they start where a previous board move ended. The intermediate square must then have been occupied, and the combination of board moves will have exactly the same effect as when that intermediate square had been mentioned in the drop of an empty square, to effect locust capture.

A tentative routine for parsing the input move is given below. Its purpose is to set the variables origin, dest, moved, promo, suicide, freedrop and dropped, in accordance with the entered move in thismove. The first three of those describe the mandatory first move, and will always be set when the move is accepted. The next three describe the optional side efects of promoting, removing a piece, adding a piece. When the move will not have the corresponding side effect, they will be set to false. The value of dropped will only be defined when a piece was added, and in that case holds the mentioned piece type.

sub ParseMove player:
  my i j mvs parts sqrs;
  set many suicide false freedrop false promo false;
  set mvs explode chr 59 thismove;                   // split at semicolons
  set parts explode ws trim elem 0 #mvs;             // split first move at space
  set i count #parts;
  if > #i 2:                                         // too many parts
    die "move must be piece ID plus board step";
  endif;
  set sqrs explode chr 45 trim elem dec #i #parts;   // split last part at hyphen
  if != 2 count #sqrs:                               // must give 2 squares
    die "board step does not mention two squares";
  endif;
  set origin elem 0 #sqrs;                           // first is origin
  set dest elem 1 #sqrs;                             // second is dest
  if not onboard origin or not onboard dest:         // check if these are valid
    die "the board isn't that large";
  endif;
  set moved space origin;                            // look what we move
  if != moved elem 0 #parts and == 1 #i:             // input move mentioned another piece
    die "there is no " elem 0 parts " on " origin;
  endif;
  if not cond #player islower moved isupper moved:   // it is not our piece
    die "you have no piece on " origin;
  endif;
  set j 1;                                           // prepare to do side effects
  while < #j count #mvs:                             // for each of those
    set parts explode chr 45 trim elem #j #mvs;      // split them at hyphen
    if != 2 count #parts:                            // must give 2 parts
      die "malformed move " elem #j #mvs;
    elseif not onboard elem 1 #parts:                // second part must be valid square
      die "second leg goes off board";
    elseif onboard elem 0 #parts:                    // additional move for locust capture
      if != dest elem 0 #parts:                      // must start from destination of first move
        die "you can only continue with same piece";
      endif;
      if #suicide:                                   // for now only one side efect
        die "cannot have more than one locust victim";
      endif;
      set suicide dest;                              // old dest was actually locust square
      set dest elem 1 #parts;                        // and this is true destination
    elseif == dest elem 1 #parts:                    // drop on dest: promotion
      set promo elem 0 #parts;
    elseif == @ elem 0 #parts:                       // drop of empty: locust square
      if #suicide:
        die "cannot have more than one locust victim";
      endif;
      set suicide elem 1 #parts;
    else:                                            // drop of piece: unload
      if #freedrop:
        die "cannot kick more than one piece";
      endif;
      set dropped elem 0 #parts;
      set freedrop elem 1 #parts;
    endif;
    inc #j;                                          // go on with next side effect
  loop;
endsub;

 

 


H. G. Muller wrote on Sat, Jul 25, 2020 12:42 PM UTC:

It seemed best to start an independent comment thread for this. The goal of this project is to develop GAME code that can be almost universally used for rule enforcement in Game Courier presets. The rules that will be enforced (piece moves, possible promotions, initial piece shuffling) will be encoded in some tables, which are then initialized in the Pre-Game section. These CV-specific tables can then be hand-coded, but also generated automatically through the Play-Test Applet, and copy-pasted in the Pre-Game section from there.

To not get ahead of ourselves, the project will be divided into several phases, where each phase would correspond to a functional preset, which will progressively allow less and less violation of the game rules. Phase 0 will test the basic method of handling the moves. To remain in full control over vetting and performing the moves, the preset will be created with the checkbox "do not include moves in GAME code" ticked. This means the preset would not do anything at all with entered moves, unless the Post-Game code tells it what to do.

The minimum requirement is thus to let the Post-Game code order execution of the entered move(s). This will already be done the way the finished project would do it: all code for handling a move will go into a subroutine HandleMove, and the only code in the Post-Move sections will be calling this subroutine:

gosub HandleMove false;

and

gosub HandleMove true;

where the Boolean parameter indicates whether the black player is making the move. The Pre-Game code for phase 0 will define the subroutine as:

setsystem maxmove 4;
ban commands;
sub HandleMove player:
  eval join "MOVE: " thismove;
endsub;

This will order Game Courier to do what it would have done automatically if we hadn't ticked the checkbox: perform the move exactly as entered, "no questions asked". For now the input can consist of any combination of up to 4 moves, promotions, drops, etc.

In phase 1 the input move will be tested for syntactical correctness, before we allow its execution.


Chess piece names with period in them[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Wed, Jul 22, 2020 01:44 AM UTC in reply to wdtr2 from Tue Jul 21 10:14 PM:

I am guessing that the Period in .rf prevents the function friend to determine if it islower.

Yes, it does. The islower function returns true only when all characters in the string are lowercase.

I would suggest making a distinction between your notation and the piece labels. .rf is a piece label, but it should not be used for notation. Use completely alphabetic notation, and test the case of the notation rather than the case of the label. See the fairychess include file tutorial for details.


wdtr2 wrote on Tue, Jul 21, 2020 10:14 PM UTC:

if fn friend $moved:
   set msg join join $moved #codename " is friend";
   echo #msg;
elseif fn enemy $moved:
   set msg join join $moved #codename " is enemy ";
   echo #msg;
else:
   set msg join join join $moved #codename " is not friend or foe " $moved;
   echo #msg;
endif;

I need advice on programming.  I have a piece that is .rf,  it appears to me the function friend / enemy is not working.  That function friend is using isupper or islower.  I am guessing that the Period in .rf prevents the function friend to determine if it islower.   

Any suggestions how I can add .rf to the function friend?


The new editcomment.php script[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Sun, Jul 19, 2020 10:32 PM UTC:

The editcomment.php script in /index/ now provides the same functionality to editors as the editcomment.php script in /indexmaint/ did. So, I have removed the [*] link and have replaced it with the [Edit] link when the editor is not the comment's author. When the editor is the author, it would be redundant to have two links, and only the regular Edit link is provided.

Instead of having a checkbox for Reviewed, it now has buttons called Approve and Disapprove. The former will update the Reviewed column with a true value, and the latter will update it with a false value.

Instead of having all the buttons show up all the time, only relevant buttons will show up, and only editors will get to see the extra buttons. The Approve and Disapprove buttons show up only if the person who posted a comment is not a registered user, and only the one that will change the value of Reviewed will show up. Likewise, Block will show up only for unblocked comments, and Unblock will show up only for blocked comments.

One change that affects authors too is that authors now have access to the Delete button to delete their own comments.


🕸Fergus Duniho wrote on Sun, Jul 19, 2020 03:52 PM UTC:

Since I was using a goto in an if-elseif series that checked the same variable, I changed it to switch and used break again. I also got rid of some breaks by using elseif instead of if in some places. But some early breaks were needed to skip over code for mailing notifications.


🕸Fergus Duniho wrote on Sun, Jul 19, 2020 01:44 AM UTC:

I have been working on getting this script to handle the extra abilities provided to editors in the /indexmaint/editcomment.php script. When it's complete, I'll remove the [*] link and just have the edit link show up differently for editors when the comment is not their own.

I also learned that PHP now supports goto, and I used it instead of the kludge of using break in a while or do-while loop.


🕸Fergus Duniho wrote on Tue, Jul 14, 2020 06:47 PM UTC in reply to H. G. Muller from 06:47 PM:

Okay, I modified it to do that.


H. G. Muller wrote on Tue, Jul 14, 2020 06:47 PM UTC:

Authors might still be interested in discussions between other people in the comment section. Wouldn't it be better to send a notification to both the page author and the poster of the comment that is replied to?


🕸Fergus Duniho wrote on Fri, Jul 10, 2020 11:24 AM UTC in reply to H. G. Muller from 11:24 AM:

The new script doesn't seem to have an exit: when you click 'post' after having seen the preview, it goes back to edit mode.

There is now a link back to the latest comments page.


🕸Fergus Duniho wrote on Tue, Jul 14, 2020 05:55 PM UTC:

I have now added the ability to send email notifications, which was in addcomment.php. I copied over the code from that file and made some modifications to it. Since I previously added the ability to reply to a specific comment, replies will send an email notification to the person whose comment is being replied to instead of to the page authors or game inventors. This will also work for subject comments. Otherwise, no one will be notified for new subject comments. Also, no one will be notified for Kibbitz comments.


H. G. Muller wrote on Mon, Jul 13, 2020 01:33 PM UTC:

The 'Edit' links seem to have disappeared from all my comments. Is there another way to modify a comment now?

[Edit] Forget about this; I see the link now. Not sure what was wrong before, it said I was logged on.


🕸Fergus Duniho wrote on Mon, Jul 13, 2020 01:53 AM UTC in reply to Fergus Duniho from 01:53 AM:

The footnotes were initially working in the preview. It appears that some tests following the footnote test are interfering with them working, but it's late, and I don't want to keep trying to figure out what that could be right now. Here is the footnote test by itself.

Testing footnotes

Here's a simple footnote,1 and here's a longer one.2


  1. This is the first footnote. 

  2. Here's one with multiple paragraphs and code.

    Indent paragraphs to include them in the footnote.

    { my code }

    Add as many paragraphs as you like. 


🕸Fergus Duniho wrote on Mon, Jul 13, 2020 01:50 AM UTC:

I have installed ParsedownExtra to handle Markdown Extra. I have also changed it to allow HTML to be used with Markdown. Here are some tests. Most are copied and pasted from the Markdown Guide's Extended Syntax page or from PHP Markdown Extra.

This is a test of how it handles code blocks. It does not do syntax highlighting.

// A useful debugging function for identifying the exact contents of a string
// Added by Fergus Duniho 4/6/2012
function show_ascii_code($text) {
    $len = strlen($text);
    for ($i = 0; $i < $len; $i++) {
        echo ord($text{$i}) . "/";
    }
}

Testing tables

Syntax Description
Header Title
Paragraph Text

Testing alignment of text in table cells

Syntax Description Test Text
Header Title Here's this
Paragraph Text And more

Testing footnotes

Here's a simple footnote,[^1] and here's a longer one.[^bignote]

Testing definition lists

First Term
This is the definition of the first term.
Second Term
This is one definition of the second term.
This is another definition of the second term.

Testing strikethrough

The world is flat. We now know that the world is round.

Testing task lists

  • [x] Write the press release
  • [ ] Update the website
  • [ ] Contact the media
Testing emoji shortcodes

grinning:

grinning_face:

Testing pasting an emoji

?

Testing automatic URL linking

https://www.chessvariants.com

Testing the disabling of automatic URL linking

https://www.chessvariants.com

Testing Markdown inside HTML DIV

This is *italics*, and this is **bold**.

Trying it again with markdown set to "1"

This is italics, and this is bold.

Testing abbreviations

The HTML specification is maintained by the W3C.

Testing underscores vs asterisks for emphasizing text within a word.

Please open the folder "secret_magic_box".

Please open the folder "secretmagicbox".


🕸Fergus Duniho wrote on Fri, Jul 10, 2020 11:24 AM UTC:

H. G. Muller wrote on 2020-07-10 EDT

I think the CKEditor was a lot more user-friendly then markdown. It made it very easy to enter simple text messages with common typographic refinements.

Have you used Markdown much yet? I have been using it for years with reddit, and I find it more convenient to use than a WYSIWYG editor. It makes it easy to do things by typing rather than by clicking a button in a toolbar.

You just had to be careful to never switch off 'source-code' mode once you had messed with the HTML.

Yes, that's the main complaint I got about CKEditor. It would be nice to have an editor without that problem.

The new script doesn't seem to have an exit: when you click 'post' after having seen the preview, it goes back to edit mode.

The new script will show the most recent comments in the footer, which wasn't fully working before, and it gives you the ability to make last-minute changes if you spot something you want to change after posting a comment. Links to the original page and to more comments should be found in the footer.


🕸Fergus Duniho wrote on Sat, Jul 11, 2020 07:32 PM UTC:

It seems that the script change affected the editor that is used in presets to write a brief description of the rules since these now appear in html view.

It didn't affect the editor. It affected how Game Courier displays the written rules for a game, because I made some changes to the display_comment() function. I changed the call to this function to use HTML, and now it displays the rules properly again.


Carlos Cetina wrote on Sat, Jul 11, 2020 05:56 PM UTC:

It seems that the script change affected the editor that is used in presets to write a brief description of the rules since these now appear in html view.

Example: Apothecary Chess-Classic


🕸Fergus Duniho wrote on Sat, Jul 11, 2020 04:14 PM UTC:

I removed the action from the form element, since the form calls the same page. It looks like it works.


🕸Fergus Duniho wrote on Sat, Jul 11, 2020 03:43 PM UTC:

When I press Preview, make some changes, and press Preview again, the preview is empty. (This was before logging in, if that matters.)

That should now be fixed. When someone enters a userid and password, one of the first things it now does is try to log in.


🕸Fergus Duniho wrote on Sat, Jul 11, 2020 02:54 AM UTC:

I updated the Format value in the Comment and Kibbitz tables to be HTML for any comment with HTML tags in it.

I modified the Markdown format to not allow HTML. It will display any HTML as text. However, it will still work with shortcodes.

I have modified the Text format to place text inside of <PRE STYLE="white-space: pre-wrap;"></PRE> tags, and I have stopped it from putting <P></P> tags around each paragraph. The style given to the tag allows it to wrap long lines. For the sake of backward compatibility, it will allow HTML and work with shortcodes. Unlike HTML mode, it does not require the use of <P> tags to separate paragraphs. A blank line will do.

The Subject entry box is wider than my screen.

I reduced it in size.

When I press Preview, make some changes, and press Preview again, the preview is empty. (This was before logging in, if that matters.)

I signed out to test this, and initially, there didn't seem to be a problem, but when I tried to post an earlier draft of this reply, I got the same problem. It is a bit too late right now to deal with it. It seems related to not signing me in even though I've entered my userid and password.

There's an Edit and View (and [*]) link on the preview that doesn't work (and probably shouldn't be there).

I removed those.

When I draft a message and then try to log in, I get an error along the lines of "You must be logged in as the original author to edit a comment" (this was after Preview, in case that matters).

I fixed that.

We should add

  1. a link to a markdown guide; since Parsedown uses github-flavored markdown, maybe https://guides.github.com/features/mastering-markdown/ ?
  2. possibly a short list of common markdown?

I added a link to a site called Markdown Guide, and I wrote a quick Markdown guide.


Ben Reiniger wrote on Fri, Jul 10, 2020 03:53 PM UTC:

The display width of my netbook is 1366px. After the left column ad, the article block is only 998px.


H. G. Muller wrote on Fri, Jul 10, 2020 03:04 PM UTC:

On my desktop monitor: 1680 pixels.


🕸Fergus Duniho wrote on Fri, Jul 10, 2020 02:34 PM UTC:

How wide is your screen?


H. G. Muller wrote on Fri, Jul 10, 2020 11:24 AM UTC:

I think the CKEditor was a lot more user-friendly then markdown. It made it very easy to enter simple text messages with common typographic refinements. You just had to be careful to never switch off 'source-code' mode once you had messed with the HTML.

The new script doesn't seem to have an exit: when you click 'post' after having seen the preview, it goes back to edit mode.


Ben Reiniger wrote on Fri, Jul 10, 2020 02:47 AM UTC:

The Subject entry box is wider than my screen. When I press Preview, make some changes, and press Preview again, the preview is empty. (This was before logging in, if that matters.) There's an Edit and View (and [*]) link on the preview that doesn't work (and probably shouldn't be there). When I draft a message and then try to log in, I get an error along the lines of "You must be logged in as the original author to edit a comment" (this was after Preview, in case that matters).

We should add

  1. a link to a markdown guide; since Parsedown uses github-flavored markdown, maybe https://guides.github.com/features/mastering-markdown/ ?
  2. possibly a short list of common markdown?

bold emph emph, emph

header

header2


🕸Fergus Duniho wrote on Fri, Jul 10, 2020 01:19 AM UTC:

There are still some things to fix up, but I figured it's time to switch over to the new editcomment.php script. This replaces a whole bunch of other scripts, and instead of giving you a WYSIWYG editor, which can modify the HTML entered by people, it allows you to enter HTML, Markdown, or plain text. By default, it will use Markdown, which is commonly used on reddit and on other sites.

Since this is the beta testing phase, give me your feedback on how well it works out for you.


🕸Fergus Duniho wrote on Fri, Jul 10, 2020 01:03 AM UTC:

I am replacing the useshtml value with a format value, which can take three different values:

  • HTML
  • Markdown
  • Text

This is to allow the use of Markdown. I installed Parsedown.php for the sake of using Markdown.

I am also removing CKEditor from this script, because it modifies the text in the text area.


🕸Fergus Duniho wrote on Thu, Jul 9, 2020 04:30 PM UTC:

I enabled this script to work with Kibbitz comments yesterday. I also noticed that the kibbitzinc.php script was not appearing in the footer, which led to no one posting Kibbitz comments for a long time. So, I fixed that. After posting this, I will try to update it immediately.

And now to update it with a new line.

Attempting again.

That was an insertion. Attempting again before fixing anything more.

I was assigning the primary key from the newly inserted row to $subjectid, which was a mistake. I have now corrected it to assign it to $commentid.


🕸Fergus Duniho wrote on Thu, Jul 9, 2020 04:29 PM UTC:

I enabled this script to work with Kibbitz comments yesterday. I also noticed that the kibbitzinc.php script was not appearing in the footer, which led to no one posting Kibbitz comments for a long time. So, I fixed that. After posting this, I will try to update it immediately.

And now to update it with a new line.

Attempting again.

That was an insertion. Attempting again before fixing anything more.


🕸Fergus Duniho wrote on Thu, Jul 9, 2020 04:27 PM UTC:

I enabled this script to work with Kibbitz comments yesterday. I also noticed that the kibbitzinc.php script was not appearing in the footer, which led to no one posting Kibbitz comments for a long time. So, I fixed that. After posting this, I will try to update it immediately.

And now to update it with a new line.

Attempting again.


🕸Fergus Duniho wrote on Thu, Jul 9, 2020 04:21 PM UTC:

I enabled this script to work with Kibbitz comments yesterday. I also noticed that the kibbitzinc.php script was not appearing in the footer, which led to no one posting Kibbitz comments for a long time. So, I fixed that. After posting this, I will try to update it immediately.

And now to update it with a new line.


🕸Fergus Duniho wrote on Thu, Jul 9, 2020 04:20 PM UTC:

I enabled this script to work with Kibbitz comments yesterday. I also noticed that the kibbitzinc.php script was no appearing in the footer, which led to no one posting Kibbitz comments for a long time. So, I fixed that. After posting this, I will try to update it immediately.


🕸Fergus Duniho wrote on Tue, Jul 7, 2020 08:28 PM UTC:

I have switched the script back to using INSERT and UPDATE. I wanted to make sure that the replace_row() function would work properly, and it does. Semantically, INSERT and UPDATE make more sense, especially given that the script uses them under different conditions anyway. You don't have to be signed in to INSERT a new comment, but you do have to be signed in to UPDATE a previously posted comment. The replace_row() function is useful in code that may be used for either inserting or updating a row.


🕸Fergus Duniho wrote on Tue, Jul 7, 2020 08:27 PM UTC:

I have switched the script back to using INSERT and UPDATE. I wanted to make sure that the replace_row() function would work properly, and it does. Semantically, INSERT and UPDATE make more sense, especially given that the script uses them under different conditions anyway. You don't have to be signed in to INSERT a new comment, but you do have to be signed in to UPDATE a previously posted comment. The replace_row() function is useful in code that may be used for either inserting or updating a row.

Modified with new paragraph.


🕸Fergus Duniho wrote on Tue, Jul 7, 2020 07:44 PM UTC:

I have switched the script back to using INSERT and UPDATE. I wanted to make sure that the replace_row() function would work properly, and it does. Semantically, INSERT and UPDATE make more sense, especially given that the script uses them under different conditions anyway. You don't have to be signed in to INSERT a new comment, but you do have to be signed in to UPDATE a previously posted comment. The replace_row() function is useful in code that may be used for either inserting or updating a row.


🕸Fergus Duniho wrote on Tue, Jul 7, 2020 06:22 PM UTC:

Insertion of new subject comment using REPLACE instead of INSERT. Updating.


🕸Fergus Duniho wrote on Mon, Jul 6, 2020 02:26 AM UTC:

Update of test comment, using REPLACE instead of UPDATE. This time for real.


Cetran Chess 3[Subject Thread] [Add Response]
Thor Slavensky wrote on Sun, Jun 28, 2020 11:13 AM UTC:

Great analysis and a fantastic answer to my question. Cetran Chess 3 is a fun game with a lot of strong pieces, and the 12x8 format really makes a challenge, balancing between developing the pieces and protecting the King. It's 'game on' right from the start!

I was asking Carlos, if he had enough compensation from his Queen sacrifice, if Black played 25. ... K l8xl7 26. P k4-k5 (check), K l7-l6 (Alternative 5 in the analysis). However in my inexperience with the Sissa, in my own simple analysis I had moved 27. S j4-k4 (check). The right move here was of course 27. S j4-i3 ! That activates the long-ranging abilities of this interesting piece, which now has control (if unblocked) of the square l7. This forces Black into the last variations in Carlos' analysis, and Black's position is terrible.

Maybe if you could be so smart as to find Carlos' variation  where Black is giving the Griffin up for the white Queen (last illustration) there possibly would be something to continue with, but with the 'heavy artillery' (Amazon and Griffin) being involved in the next couple of moves and Black's extremely weak king-position, I now totally understand and sympathize with Black resigning the game here!


Carlos Cetina wrote on Fri, Jun 26, 2020 11:25 PM UTC:

Analysis of the final position of the Cetran Chess 3 game played by Carlos Cetina (White) vs Daniel Zacharias (Black) made to answer a question raised by Thor Slavensky.

Cetina vs Zacharias

Black to move. 25th turn. Black's King is double-checked. White's Sissa checks via j4-j6-l8. Then 25. ... Kxl7 is forced. After 26.k6+ arises the following position.

CC vs DZ (1)

Black has 5 alternatives:

1) 26. ... Kk7 27.l6#

CC vs DZ (2)

2) 26. ... jxk6 27.lxk6+ Kk7 27.DKl7#

CC vs DZ (3)

3) 26. ... Sxk6 27.lxk6+ Kk7 28.DKl7+ Kj8 29.DKxj7#

CC vs DZ (4)

4) 26. ... GRYxk6 27.lxk6+ Kk7 28.DKl7#

CC vs DZ (5)

5) 26. ... Kl6 27.Sl3+ giving check via l3-i3-l6 

CC vs DZ (6)

Now Black has 2 alternatives: (A) 27. ... Kk7 and (B) 27. ... GRYj4 [obstructing the checking path].

If (A) 27. ... Kk7, then 28.l6+   

CC vs DZ (7)

Now Black has 2 possible moves: (A1) 28. ... Kxk6 and (A2) 28. ... Kl8.

Let's see A1 in detail move by move. 28. ... Kxk6 29.DKk1+

CC vs DZ (8)

The White's Sissa from l3 controls l7 (via l3-h3-l7), l6 (via l3-i3-l6) and l5 (via l3-j3-l5). Then 29. ... Kj5 [forced] 30.Sk5+

CC vs DZ (9) 

Now the Sissa from k5 controls i6 (k5-j6-i6), i5 (k5-i3-i5 or k5-k3-i5 or k5-k7-i5) and k6 (k5-l5-k6 or k5-j6-k6). Then 30. ... Kj4 [forced] 31.DKk4#

CC vs DZ (10)

Sissa and Dragon King defend each other.

Now let's see the A2 alternative 28. ... Kl8 29.k7+

CC vs DZ (11)

29. ... AANxk7 [forced because the White's Sissa controls l7 via l3-h3-l7] 30.lxk7+ Kxk7

CC vs DZ (12)

At this point it is not clear whether or not White has any decisive advantage. To continue attacking it needs to move its Gryphon to g2 so that the Amazon can join the fight and the Aanca from c1 can also do it later. Maybe Black could rearrange his defense starting with Gryphon k6.

Returning to the position after 26. ... Kl6 27.Sl3+

CC vs DZ (6)

The B alternative, 27. ... GRYj4, could be replied with 28.Sxj4 and if 28. ... AANxi5 then 29.DKk1.

CC vs DZ (13)

Again, it is not clear that White has any decisive advantage. However I think White has enough compensation for the Queen. The fight continues and "the coin is in the air".

 


[Subject Thread] [Add Response]
Davor Vujacic wrote on Tue, Jun 2, 2020 03:23 AM UTC:

Who can publish my remaining two articles?

 


waffle chess preset[Subject Thread] [Add Response]
Aurelian Florea wrote on Mon, May 4, 2020 02:13 PM UTC:

Fergus,

I has passed that stage, and now I have some tests to do. Thanks for your help!...


Aurelian Florea wrote on Mon, May 4, 2020 04:52 AM UTC:

If that manadatory or "else : if" if fine too?


🕸Fergus Duniho wrote on Sun, May 3, 2020 03:22 PM UTC:

On line 30, you have "else if" instead of "elseif".


Aurelian Florea wrote on Sun, May 3, 2020 02:15 PM UTC:

Silly me.

I had solved that problem, and some loose endifs problem but now I get the error:

The include command may not be used except at the main level.

I am not sure why because to me it seems all right to put the include command there.

https://www.chessvariants.com/play/pbm/play.php?game=Waffle+Chess&settings=FastCastling&submit=Edit


🕸Fergus Duniho wrote on Sun, May 3, 2020 11:43 AM UTC:

Each line should end with a colon or semicolon, but some lines are unterminated.


Aurelian Florea wrote on Sun, May 3, 2020 08:02 AM UTC:

Hei Fergus,

I see you are quite busy these days but if you can find some time to look over my code for waffle chess: https://www.chessvariants.com/play/pbm/play.php?game=Waffle+Chess&settings=FastCastling&submit=Edit

I'd appreciate. It has to use free castling. I managed to delete the 2 moves of the king besides him for the first move because they are ambiguous (they can be regular king moves or castling moves) so I treat them separately. I get the error you can see when you click the link, and I think that it comes from doing something wrong with current moves vs future moves.

Thanks for your time.


Question on Legal moves[Subject Thread] [Add Response]
wdtr2 wrote on Sun, Apr 26, 2020 05:14 PM UTC:

Hello, I am trying to make a game that has 2 royals.  setlegal seems to be the CV php command to add legal moves.  If you are looking through your standard programs that you have made i.e. "legal moves section", setlegal works great.   Let's say you completed your loop.   After you complete the loop you discover your 2nd royal is in check.  I want to clear out all legal moves and re-calculate.   Can you clear or unset the legal moves you set in setlegal a few milliseconds ago?  i.e. unset $legalmoves?


FrogsandPrincess[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Sun, Apr 19, 2020 12:23 AM UTC:

You can't paste images and expect them to show up on the site. You have to upload them to the site and use the correct URL in an IMG tag.


wdtr2 wrote on Sat, Apr 18, 2020 10:36 PM UTC:

I just attempted to put in rules for my new game.

In the past with other rules, I did a cut and paste from mspaint.  With this submission, the png appears, but when I hit the submit button, and then check it, the image is not there.   Is that OK?

The paste is in the setup section of the rules.

Possible issue on Shogi Drop[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Mon, Mar 30, 2020 05:24 PM UTC:

I had added the ability to enter moves backwards, but I hadn't taken into consideration that it also had to work with drops. I have now fixed that.


wdtr2 wrote on Mon, Mar 30, 2020 10:33 AM UTC:

If you pull up the shogi game, and play against yourself (2 people on same computer).  Eventually you will capture a piece and it will go into your pending drop box.  If you try to drop a piece via a mouse click,

p* <mouse_click_location_on_board>

It does not work for me.  Fergus, can you try a drop piece move and see if it works for you?

Note: if you put the command in the moves: textbox, (manual) it will work.

 

 


2019 Variant tournament[Subject Thread] [Add Response]
wdtr2 wrote on Sat, Mar 28, 2020 08:25 PM UTC:

This is more of a question for Greg.  How did the 2019 Tournament go?  Who was the winner?

Never mind, I see the comment below. :)

Question on PHP Engine or change on legal moves[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Fri, Mar 27, 2020 03:34 PM UTC:

Okay, that's now fixed. Thanks for reminding me how it was supposed to work.


wdtr2 wrote on Fri, Mar 27, 2020 10:47 AM UTC:

Hi, your bug fix helped, but I am being really fussy now!  A pop-up comes up in CONFIRM MODE saying "Showing Legal moves for <piece> you cannot actually move in view or preview mode Click OK to hide legal moves.  In certain situations a checkbox comes up saying "Prevent this page from creating additional dialogs."   If you click that  checkbox - Legal moves (on your enemy pieces) appears to me to get completely disabled."  

No, I do not want that. 

In the past, I was able in confirm mode to click several enemy pieces and see the enemy piece moves without the pop-up.    


🕸Fergus Duniho wrote on Thu, Mar 26, 2020 08:06 PM UTC:

Thanks for mentioning that. I had forgotten about this ability, and I inadvertently introduced a bug that got rid of it. I have now restored it.


wdtr2 wrote on Thu, Mar 26, 2020 04:17 PM UTC:

Something changed maybe about 2 to 4 weeks ago.  Let's say we have a game that shows legal moves.  I am on the white side, and it is my turn.  When I click a piece I get a gray square and blue squares that show legal moves.   Great.  I now move my piece.  I am now ready to confirm.  In the past, I could click on a black piece and see it's legal moves before I hit the confirm button.  This ability has disappered.  (maybe on purpose?).   


Match between Fairy Max and ChessV[Subject Thread] [Add Response]
Aurelian Florea wrote on Fri, Mar 6, 2020 06:20 AM UTC:

@Greg

Hey,

It works up to a certain point, this beeing the moment when you click fairy max in the engines list. There it shows that it can play frog, hannibal and waffle. But in the menu before starting the respective games it fails to offer the fairymax choice. I have also tried batch mode with a control file, and it did not work. Thanks for the help so far!...


Greg Strong wrote on Thu, Mar 5, 2020 01:33 PM UTC:

Thinking about it now, ChessV only determines the capabilities of an engine when it first sees it.  If ChessV had already discovered Fariy-Max and then you add support for Frog Chess, it won't know.

Click the Engines button on the main screen.  Select Fairy-Max and click Remove.  This does not delete any files.  If you have MaxQi and ShaMax in the list, you will need to select and remove those as well (because they are in the same folder.)

Then close ChessV and run it again.  It will re-discover the engines in that folder.  It should then show up.  You can click Engines, select Fairy-Max, and click Properties.  In the bottom-right you will see a list of the variants that it supports.  Make sure the name in that screen exactly matches what you put in the XBoardEngine variable.


Aurelian Florea wrote on Wed, Mar 4, 2020 04:13 PM UTC:

@Greg,

I have understood what you meant. But it still does not work.

@HG

Maybe that is because I misrepresented frog chess in the fairymax file. Currently it looks like this:

Game: frog # PNBRQ.FKpnbrq.fk # fairy
10x8
6 4 5 8 7 3 8 5 4 6
6 4 5 8 7 3 8 5 4 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
f:275 15,7 17,7 -15,7 -17,7 3,7 -3,7 48,7 -48,7
#
# F & FH


Greg Strong wrote on Wed, Mar 4, 2020 01:26 PM UTC:

Yes, I've seen the bug report but haven't finished looking at that yet.  My post was how you can use Fairy-Max under ChessV in the meantime.


Aurelian Florea wrote on Wed, Mar 4, 2020 09:18 AM UTC:

@Greg & HG

It seems to not work in this way either. This is probably because of what HG has explained down bellow!


H. G. Muller wrote on Wed, Mar 4, 2020 08:57 AM UTC:

I think the real problem is that the ChessV.Engine.exe is defective; see my posting in the ChessV comments.

Note that Fairy-Max calls this game 'frog' only because the user configured it this way; Frog Chess is neither pre-cofigured in Fairy-Max, nor an XBoard standard variant. It would be just as easy to make Fairy-Max use the name that ChessV uses.

I am not sure it is 'unfortunate' that XBoard protocol only defines a very limited list of standard variants. The problem is that such a list, no matter how long you make it, will never be (or stay) complete anyway. To be future-proof, any name should be allowed. This means the names are not really part of the protocol anymore than the names of chess engines are; they are just data, and the protocol prescribes only what commands should be used to communicate them.

IMO the list of standard variants is already way too long; many variants in the list have no special properties, and only differ from each other (or from orthodox Chess) through board size, array, and piece moves. And the latter properties have basically become freely specifiable parameters for 'engine-defined variants'. So variants like Capablanca Chess, CRC, Great Shatranj really have become redundant, and are maintained only to deal with 'legacy engines'. Because the latter would not reply to the 'variant' command that selected them with a 'setup' command for specifying the array and board size.

The concept of engine-defined variants does raise the problem of name standardization, though. Which becomes more than a cosmetic problem when we want to play engines against each other. Perhaps GUIs should already provide a work-around for cases where engines disagree on the name of a variant they both play, like a per-engine 'alias list' of variant names. Which the GUI then should apply (in either direction) on both variant names received from the engine and sent to the engine.


Greg Strong wrote on Wed, Mar 4, 2020 12:50 AM UTC:

@Aurelian:

ChessV decides what games an engine supports based on the variants it announces support for.  Unfortunately, the XBoard protocol only specifies how a small number of variants are to be named and they are often not the official name of the game.  For example, Joe Joyce's Great Shatranj is identified only as "great".  So for many games, ChessV doesn't know if an engine supports a game because there is no official string used to identify the game.

That said, you can tell ChessV how a variant should be identified by specifying the XBoardName string variable.  So, if you have configured FairyMax to play Frog Chess and called it "frog", you would also edit the ChessV include file that defines Frog Chess adding the following line:

XBoardName = "frog";

This line goes right inside the Game definition, where Invented and InventedBy are specified.  If you do this, it should offer Fairy-Max as an opponent for Frog Chess.


Aurelian Florea wrote on Tue, Mar 3, 2020 10:37 AM UTC:

So basically there is no chance for now to set up a game between the 2 engines.


Aurelian Florea wrote on Sun, Mar 1, 2020 10:35 AM UTC:

I did not combrehend it is about the Betza notation. Now I understand!


H. G. Muller wrote on Sun, Mar 1, 2020 09:51 AM UTC:

Well, for one the spaces are missing behind the # and & in the piece-descriptions for WinBoard, which probably leads to WinBoard ignoring them altogether. Which is just as well, as HH and WH are not the Betza notations for the moves of the Hannibal and Waffle: you defined the Hannibal for WinBoard as a Trebuchet-rider. But for Fairy-Max you defined it as a Modern Elephant, which has no moves in common. But even when ignoring the piece definitions, WinBoard will revert to the default move of the piece, which for the Elephant that you use in all cases will be the Alfil move.

The F moves of the Hannibal and the W moves of the Waffle will then be rejected by WinBoard as illegal, when Fairy-Max plays them. And Fairy-Max can recognize checkmates where WinBoard still sees a possibility for the King to escape, to a square that the Hannibal or Waffle attack without WinBoard being aware of it. And then WinBoard would judge the mate claim by Fairy-Max illegal.

 


Aurelian Florea wrote on Sat, Feb 29, 2020 03:51 PM UTC:

Greg,

I had noticed that chessV2 has the ability to play with different engines. But such an option is not shown for frog chess, hannibal chess, waffle chess. Is that from bad scipting or is it the fact that external engines variants options is hard coded?


Aurelian Florea wrote on Sat, Feb 29, 2020 03:48 PM UTC:

HG,

the following script in Fmax ini file yiels invalid move and invalid claim errors. I posted what I had changed. Please tell me where am I wrong.

//Frog chess invented by Kevin Pacey
Game: frog # PNBRQ.FKpnbrq.fk # fairy
10x8
6 4 5 8 7 3 8 5 4 6
6 4 5 8 7 3 8 5 4 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
f:275 15,7 17,7 -15,7 -17,7 3,7 -3,7 48,7 -48,7
#
#F&FH

//Hannibal chess invented by Kevin Pacey
Game: hannibal # PNBRQ.HKpnbrq.hk # fairy
10x8
6 4 8 5 7 3 5 8 4 6
6 4 8 5 7 3 5 8 4 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
h:275 15,7 17,7 -15,7 -17,7 30,7 34,7 -30,7 -34,7
#
#H&HH


//Waffle chess invented by Kevin Pacey
Game: waffle # PNBRQ.WKpnbrq.wk # fairy
10x8
6 8 4 5 7 3 5 4 8 6
6 8 4 5 7 3 5 4 8 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
w:275 1,7 16,7 -1,7 -16,7 30,7 34,7 -30,7 -34,7
#
#W&WH


H. G. Muller wrote on Sat, Feb 29, 2020 08:59 AM UTC:

For 'engine-defined variants', the definition in the fmax.ini file should also specify a 'pieceToCharTable' (to indicate which images should be used for what piece) and a 'parent variant' (normally 'fairy', unless there are some special rules that you want to borrow from another variant, such as a wider promotion zone, or the possibility to gate pieces). They go on the 'Game:' line, after the name of the variant, separated by #, like

Game: frog # PNBRQ.FKpnbrq.fk # fairy

if you want to depict the Frog as an elephant (because the F is in the 7th place of the pieceToCharTable, and WinBoard's 7th piece image is an elephant). The last piece mentioned for each color will always use the King symbol.

It will also be helpful to make Fairy-Max inform WinBoard on how the Frog moves, so that you will be able to play the games with legality testing on. To this end you should append the following two lines to the game definition:

#
# F& FH

This will make Fairy-Max emit a 'piece' command at the start of the game for F (the '&' indicating it applies to F of both colors), to indicate it moves as a (Betza) FH. (The other pieces move as WinBoard would expect a piece with that image to move, so there is no need to (re)define their moves.) Unfortunately Fairy-Max is not smart enough to construct the Betza notation that XBoard needs from the move definition as it was given on the 'f:' line. I still hope that I can make some future version of Fairy-Max work entirely from Betza move definitions in the fmax.ini file, rather than from the list of step vectors and primary/secondary move rights it uses now.


Aurelian Florea wrote on Sat, Feb 29, 2020 05:25 AM UTC:

@HG and Greg

I want to see three competitions between Fairy Max and ChessV using Winboard. The games should be Frog Chess, Hannibal chess and Waffle Chess.

1. What is the instruction that connects ChessV with winboard?

2. When I try to load FairyMax to play I get the message: "Engine did not send setup for nonstandard variant".

These are the fairymax representations of the 3 games, as I have written them:

//Frog chess invented by Kevin Pacey
Game: frog
10x8
6 4 5 8 7 3 8 5 4 6
6 4 5 8 7 3 8 5 4 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
f:275 15,7 17,7 -15,7 -17,7 3,7 -3,7 48,7 -48,7

//Hannibal chess invented by Kevin Pacey
Game: hannibal
10x8
6 4 8 5 7 3 5 8 4 6
6 4 8 5 7 3 5 8 4 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
h:275 15,7 17,7 -15,7 -17,7 30,7 34,7 -30,7 -34,7

//Waffle chess invented by Kevin Pacey
Game: waffle
10x8
6 8 4 5 7 3 5 4 8 6
6 8 4 5 7 3 5 4 8 6
p:100 -16,24 -16,6 -15,5 -17,5
p:100 16,24 16,6 15,5 17,5
k:-1 1,3034 -1,1034 1,7 16,7 15,7 17,7 -1,7 -16,7 -15,7 -17,7
n:310 14,7 31,7 33,7 18,7 -14,7 -31,7 -33,7 -18,7
b:350 15,3 17,3 -15,3 -17,3
R:475 1,3 16,3 -1,3 -16,3
Q:950 1,3 16,3 15,3 17,3 -1,3 -16,3 -15,3 -17,3
w:275 1,7 16,7 -1,7 -16,7 30,7 34,7 -30,7 -34,7


UserID on CV site[Subject Thread] [Add Response]
🕸Fergus Duniho wrote on Tue, Feb 25, 2020 09:35 PM UTC:

Since the userid is limited to 16 characters, and ChessVariantDemos has 17, I could not make the change. Note that you have two different IDs on this site, though both are presently the same for you. These are the personid, which is limited to 32 characters, and the userid. The userid is the handle that you use to sign in, and it is also used when you play games on Game Courier. The personid is used to identify you when you post comments or contribute content. This site was using personids before userids were ever a thing here, and the original personids were based on a person's name, such as DavidHowe or FergusDuniho. Userids were meant as shorter handles for signing in. I could change your personid to ChessVariantDemos, though one based on your name would be preferable.


JT K wrote on Tue, Feb 25, 2020 08:56 PM UTC:

Hi Fergus, can I get it changed to ChessVariantDemos?  (assuming all the info and variant pages I've written remain)


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

What do you want to change your userid to?


100 comments displayed

LatestLater Reverse Order EarlierEarliest

Permalink to the exact comments currently displayed.