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/Ratings for a Single Item

LatestLater Reverse Order EarlierEarliest
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 Wed, Jun 22, 2016 02:18 PM UTC:

While it is a bad programming practice to use variables in a subroutine that were created as local variables in another subroutine, I have discovered that I did this with the castle subroutine. Although I could change this in the include file it appears in, this could have effects on games that include the include file but also use custom versions of the subroutines calling it. So, to update the language without breaking anything, I would have to update the code written with the language first, and that could be a bigger project.


🕸📝Fergus Duniho wrote on Wed, Jun 22, 2016 01:41 AM UTC:

I've decided to work on a modified clone script so that I can try things without disrupting Game Courier. So far, the changes I made caused the first move in a game of Gross Chess to be recognized as illegal, though I haven't figured out what is going on. What I want to do is drop block scoping, which has hardly been used, and maybe add include files to lexical scoping. I figured that the main place it would be helpful to be able to use local variables outside of subroutines is in the main body of an include file. This could be helpful given that an include file and a preset may be by different authors. But this might have problems of its own, and it might not be that necessary. Including include files early and inserting changes after the file is included, as I already do, may be sufficient.


🕸📝Fergus Duniho wrote on Tue, Jun 21, 2016 09:15 PM UTC:

There is a catch to changing how variable scoping works in GAME Code. It currently supports block scoping. This means that blocks of code that appear between if and endif, do and loop, for(each) and next, or switch and endswitch increases the scope. Since PHP and JavaScript, the two main languages I program Game Courier in, do not use block scoping, I am not used to it, and I do not use it much in GAME Code, though I have used it a little bit. The main advantage to block scoping is that it will let you use variable names in blocks that might have a different use outside the blocks. The advantage to eliminating block scoping is that it allows the interpreter to handle variables more quickly, because there is no searching down levels of scope for the matching variable. Another possible advantage is that it may simplify how variables work, making it easier to add better support for multidimensional arrays. But to make this change, I'll have to check whether scope plays any functional role in how the control structures work.


🕸📝Fergus Duniho wrote on Tue, Jun 21, 2016 05:08 PM UTC:

I'm planning to make some changes to how variables work in GAME Code. In practice, the distinction between my and local variables has been a moot one. Both are given the narrowest scope when created, and they differ in whether they are lexically scoped to the current subroutine (my) or to the main scope (local). This difference makes local variables visible to any functions they call. In general, it is a bad idea to use local variables in this way. The basic idea behind a local variable in other languages is that it will be local to the function it is created in, and it will not be visible to other functions. So, my variables are what actually work like local variables in other languages. Also, my variables are quicker to access. So, I plan to remove what I have called local variables and use the name local for my variables. For the sake of not breaking old code, I'll treat my and local as synonyms. So, the available variable scopes will just include global, local, and static, where global has wide/main scope, local has narrow/subroutine scope, and static has wide/subroutine scope. Narrow/main scope, which is currently called local, will be removed.

I also want to provide better support for multidimensional arrays. I don't like the setelem command. I would rather do something like set var[key] "something or other". While I can currently use something like var[key] as a variable name, doing so won't currently create an array element. I want it to add an element to an actual array that will be recognized by functions that work with arrays. I also want to be able to replace key with a variable, such as var[#key]. This will require some changes to line parsing.


🕸📝Fergus Duniho wrote on Tue, May 17, 2016 09:21 PM UTC:
I have reorganized and revised the beginning sections of this guide. I have also touched up the section on GAME Code. It now includes links to more tutorials and links to some of the PHP source code behind GAME Code.

🕸📝Fergus Duniho wrote on Mon, Feb 8, 2016 04:04 PM UTC:
I traced a mysterious bug in my code for Musketeer Chess to a use of the move command in the castle subroutine. The bug is that the flag on the King's space was being unset prematurely. It turns out I had written the move command to move both the piece and the flag from one space to another. But in all my subsequent uses of the move command, I never needed it to move the flag with the piece. Although I had written the command before I had a full-fledged programming language, I ended up using it mainly in subroutines that temporarily changed the positions of pieces to test for various conditions. Also, I can't think of any game that really requires flags to move with pieces, and if you have written such a game, it's probably best to make the flag movement explicit in your code. So, I have removed the ability of the move command to move flags. It will now just move pieces.

🕸📝Fergus Duniho wrote on Tue, Mar 24, 2015 02:42 PM UTC:

I have just changed how some of the output commands work. Some output commands output text immediately. These are die, echo, print, and printr. Previously, output from these commands has remained visible when the program finished successfully. I have changed this, so that when a Game CODE program completes successfully, output from these commands will be hidden. This is done through CSS by giving a containing block the property of display:none, and the output from these commands will still be visible in the page source. With this change, these commands are intended only for debugging or for writing errors messages that can be seen when a player makes an illegal move.

I have made this change so that output from these commands will not mess up the display on mobile devices. It also removes clutter that was easy enough to ignore on a computer monitor but gets in the way more on a small mobile screen. I have also removed the restriction against using echo in Play mode, since its output will no longer show up unless something goes wrong.

I have also changed die to display text as an H1 heading, so that the error or warning message it gives will be more prominent.

For text that the player should see upon successful completion of the GAME Code program, you should use say, whose behavior has not been changed.


🕸📝Fergus Duniho wrote on Thu, Jul 3, 2014 12:26 AM UTC:
No, there isn't. The two languages serve different purposes, and they do not easily map onto each other. It's best to just forget about conversion and  program a game with reference only to the game's rules, not to the ZRF code used to program its rules in Zillions-of-Games.

Stephane Burkhart wrote on Thu, Jun 26, 2014 09:24 PM UTC:
Hello Fergus
Is there somewhere a "Zillion2Game" (whatever the name) transcription script ? It would be so much easier to transcript existing games...
Sincerely,
Stephane Burkhart (from France)

🕸📝Fergus Duniho wrote on Sat, May 10, 2014 01:03 PM UTC:

I have added a section on including a description of the rules with your preset. This is a natural language description for players to read. It may include HTML or Javascript, and I have written a Javascript function for displaying pieces using the selected piece set. Details are in the documentation at


🕸📝Fergus Duniho wrote on Mon, Feb 7, 2011 02:12 AM UTC:
Added subsection on adding comments, which I forget to document earlier. Also fixed a bug that wouldn't let comments be used in code entered into the forms in edit mode. Comments can now be entered anywhere in your code.

🕸📝Fergus Duniho wrote on Sun, Feb 6, 2011 04:41 AM UTC:
Just added unlink command for use with logical directions. Useful for unlinking separate planes of a 3D game from each other before adding in directions that go from one plane to another.

🕸📝Fergus Duniho wrote on Fri, Dec 31, 2010 03:41 AM UTC:

As an update to my last comment here, the new input and revision commands are called appendmove, ask, askpromote, continuemove, redomove, and rewritemove. They are all described in Input and Revision Commands. The continuemove command is what I earlier called extendmove. I have just made use of it with Extra Move Chess to handle double moves.

While working on that game, I discovered a good use for a do-while loop that ends with a never condition. I previously mentioned that this will function like a simple if statement. Although it doesn't have the benefit of adding elseif conditions, it can sometimes be more useful than a simple if statement, because it allows the use of break or continue to exit it early or the use of redo to return to the beginning. In Extra Move Chess, I had code that I wanted to execute if the player made a second move, but if the player passed the second move with the pass command, I wanted to skip over most of this code. So I put it in a do-while/loop-never loop and used break to exit early if the move equaled the pass command.


🕸📝Fergus Duniho wrote on Sun, Dec 12, 2010 03:43 AM UTC:
In a move toward making Game Courier more user-friendly, I have added some commands that allow a player to create moves longer than a single move primitive by using the mouse. I have already used them with Shogi and Chess to handle promotions with the mouse. If you want to use them with the presets for your games, details are now on this page. Briefly, the new commands are appendmove, ask, askpromote, and extendmove.

🕸📝Fergus Duniho wrote on Sat, Nov 27, 2010 07:14 PM UTC:

Attention Game Courier Developers:

If you have programmed any presets to enforce the rules, and you use variables to keep track of the location of the King or other royal piece, you will need to make a slight modification to your code for your preset to work properly with fairy chess problems. In most of the presets I've programmed, I have code that looks like this:

set K e1; set k e8;

To work with fairy chess problems, in which the Kings might be found anywhere on the board at the beginning of the problem, this code needed to be changed to this:

set K findpiece K spaces; set k findpiece k spaces;

This change will allow Game Courier to know the position of the Kings when a fairy chess problem begins, allowing it to properly use code for recognizing check and checkmate.

I am currently going through my own presets, making the appropriate modifications. For some games with different royal pieces, this code has to be modified.


Thomas Marquardt wrote on Fri, Jan 1, 2010 04:06 PM UTC:
Bug in the preset for Wildebeest Chess:

/play/pbm/play.php?game%3DWildebeest+Chess%26settings%3DWildebeest+Chess+with+rules

Hi, I have written a preset for Wildebeest Chess some months ago. When I tested it (arount spring/summer of 2009) it seemed to work, but now it is no longer working. Before the first move it complained that the function definition of some function is wrong: the message was 'Function def requires more arguments than it has placeholders for.'. I fixed this by removing the function definitions, doing the calculation directly where the functions were previously called.

The function definition was:
def isKINGc == #2 K and == #0 f1  and match #1 a1 b1 c1 d1 h1 i1 j1 k1;

and it was called in post-move 1:
if fn isKINGc origin dest moved:
  ...


Now there is still another bug: when the rook castles onto the origin square of the king (entered as a rook's move, e.g. a1-f1) then the king dissapears.

I am sure that I had checked this after writing the preset and it worked, before Jeremy Good made the preset the official one (see the comments at http://www.chessvariants.com/large.dir/wildebeest.html).


-----------------------------------------------

Edit: I have found the bug and fixed it. I just forgot a ':' after the condition of an if-statement...

Jack Nitch wrote on Tue, Dec 29, 2009 03:37 PM UTC:
while playing smess, found sg8 piece is not allowed to move.

🕸📝Fergus Duniho wrote on Mon, Dec 21, 2009 02:08 AM UTC:
Today I went through the operators and built-in functions available for use in expressions, and I documented those I hadn't documented yet.

🕸📝Fergus Duniho wrote on Mon, Dec 14, 2009 01:00 PM UTC:
Yes. I developed it out of the need to handle the unusual topography of Circular Chess, which is to be played in the upcoming tournament. It will be useful for other unusual topographies, such as toroidal boards and 3D boards, and it will make it much easier for me to program Interdependent Chess. It also makes some types of piece movement easier to program, particularly winding riders and turning riders.

John Smith wrote on Mon, Dec 14, 2009 05:25 AM UTC:Excellent ★★★★★
Great developments, Fergus. So if I am right, it can support more complex movement now, correct?

🕸📝Fergus Duniho wrote on Sun, Dec 13, 2009 10:52 PM UTC:

I have now added commands and built-in functions for using logical directions. A logical direction is one associated with a name rather than with an actual physical direction. If you program ZRF files, you are already familiar with using logical directions, because that is all that Zillions of Games uses. Until now, Game Courier has only used physical directions. Contrast how GAME Code could define a Knight's move with how Zillions of Games would:

def N checkleap 1 2;

vs.

(moves
	     (leap2 n ne)
	     (leap2 n nw)
	     (leap2 s se)
	     (leap2 s sw)
	     (leap2 e ne)
	     (leap2 e se)
	     (leap2 w nw)
	     (leap2 w sw)
      )

GAME Code could simply define a Knight as a 1-2 leaper and do mathematical calculations to check whether its move was legal, whereas ZoG needed to have every direction of movement spelled out explicitly.

Now you can do the same thing in GAME Code. The map and link commands will define directions similarly to how Zillions of Games does. The logleap and logride built-in functions will determine whether a leap or ride is legal using logical directions. The logleap function can be used for both simple leapers and lame leapers. Here are some examples:


// Chess Knight. Knight moves must be defined as single leaps.
def N logleap #0 #1 nne nnw sse ssw nww nee see sww;
// Xiangqi Knight. Lame leaps defined by separate paths, each in a pair
// of parentheses
def H logleap #0 #1 (n ne) (n nw) (s sw) (s se) (w sw) (w nw) (e se) (e ne);

The logride function can work for simple riders, winding riders, short-range riders, winding short-range riders, and turning riders. Some examples:


Simple rider. Rook
def R logride n w s e;

Winding rider.
Goes orthogonally, then outward diagonally, then alternates between
the same two directions.
def WR logride #0 #1 (n ne) (n nw) (s sw) (s se) (w sw) (w nw) (e se) (e ne);

Short-range rider. Short Rook. Non-direction z is used to stop movement.
def SR logride (n n n n z) (w w w w z) (s s s s z) (e e e e z);

Winding short-range rider. 
Like previous winding rider but limited to four spaces.
def SWR logride (n ne n ne z) (n nw n nw z) (s sw s sw z) (s se s se z) (w sw w sw z) (w nw w nw z) (e se e se z) (e ne e ne z);

Turning rider.
Moves one space orthogonally, then outward like a Bishop
def OD logride (n (ne) (nw)) (s (se) (sw)) (e (se) (ne)) (w (nw) (sw));

🕸📝Fergus Duniho wrote on Wed, Nov 25, 2009 03:25 AM UTC:
I have just added support for function literals. I'll be brief, because now I'm tired.

The literal operator returns a function literal or an array literal, depending on whether it receives a function name or an array.

The setfn command sets the named function to the value of an expression. To copy a function, you can set a new function to the literal of an already defined function. For example:

def ff - #0 #1;
setfn qq literal ff;

This also works:

def ff - #0 #1;
set dd literal ff;
eval def qq #dd;

You can copy functions even faster without the intermediary of function literals:

copyfn ff qq;

With function literals, you can write code that creates its own functions. This may be useful for writing more generalized code, which can be used with more games, or for games whose rules change according to new conditions.

🕸📝Fergus Duniho wrote on Thu, Nov 19, 2009 02:04 AM UTC:
I have updated the sections on optimization and learning by example. If you're a GAME Code programmer or want to program in GAME Code, it is worth checking out the changes to these sections.

Jose Carrillo wrote on Thu, Nov 5, 2009 02:38 AM UTC:
Great Fergus!

Not sure I understand how to use them to store initial random positions.

Can you please give us an example?

🕸📝Fergus Duniho wrote on Thu, Nov 5, 2009 12:47 AM UTC:
I have just added documentation for constants. Briefly, constants get stored in the log, so that their values are immediately available whenever a program associated with a log starts. They are useful for storing randomly generated values that must never change on subsequent runs of the program for the same game.

🕸📝Fergus Duniho wrote on Thu, Feb 5, 2009 02:44 AM UTC:
I have copied the changes I made to the push command to the rest of my code for handling scoped variables. There should now be no problem recognizing variables with null values as set.

🕸📝Fergus Duniho wrote on Thu, Feb 5, 2009 02:33 AM UTC:
Okay, I fixed the push command. The problem was that an empty array was being interpreted as a null value, and isset returns false when a variable has a null value. This problem has not shown up with zero values, because PHP does not treat zero as a null value, and isset will normally recognize a variable set to zero as set. The fix combines isset with array_key_exists, using isset to check whether any variables for the scope exist and array_key_exists to check for the named variable. I need to use isset before array_key_exists to avoid error messages from array_key_exists when the array it is supposed to search for a variable doesn't exist.

🕸📝Fergus Duniho wrote on Wed, Jan 28, 2009 04:53 AM UTC:
I've gotten closer to isolating the problem. The PHP language construct isset returns false when a variable exists but has a null value, and I had been expecting it to return true whenever a variable exists no matter what it's value is. So, in the code you gave, the local a2 had a null value, and isset failed to recognize that it existed. I need to replace my uses of isset with something else, maybe array_key_exists, but I will continue work on it later.

🕸📝Fergus Duniho wrote on Tue, Jan 27, 2009 02:57 PM UTC:
Curious. Using the dump command after each gosub, I learned that a2 still existed as a global variable after the subroutine was called. By putting the dump command in the subroutine, I learned that a2 was being treated as global instead of local. I will look at this further when I have some free time.

Thomas Marquardt wrote on Tue, Jan 27, 2009 01:37 PM UTC:
Hi, either I didn't get something, or I have found another bug.

I put the following code in the Pre-Game part:

set arr (x y);
sub test:
  local a2;
  set a2 ();
  for i var arr:  push a2 #i;  next;
  for i var a2:  echo #i;  next;
endsub;
gosub test;
gosub test;


I believe the output of this should be:

x
y
x
y

since test is called twice, and both times the content of arr is copied into a2 and then output. But the output is in fact:

x
y
x
y
x
y

In the second call of test, the old content of a2 is seemingly not deleted, and the 'x y' is appended to it.
If I make the variable a2 global (i.e. delete the line 'local a2;') then it works as it should.

🕸📝Fergus Duniho wrote on Sat, Jan 17, 2009 02:17 PM UTC:
First, you cannot edit the Games for Game Courier Page. That is an editor-created page maintained by myself, and it showcases only a small number of the many Game Courier presets. What you need to do for your presets is (1) create individual pages for them, and (2) add those pages to our database. Once this is done, they will show up on the What's New page, and you will be able to follow the appropriate letter links at the top of the Games for Game Courier page to pages listing your presets. In the future, you should be able to make member-created pages, but it appears that the privilege of doing this is extended only to previously published members, probably to reduce spam pages created by just anyone. For now, make some HTML pages of your presets, and email them to me. You may include graphics on the pages, preferably reduced in scale, which are easily made with the use of Game Courier. I have ascertained that your userid is thomas. For attribution purposes, I recommend adding your name to your personal information. To enter messages with your userid, enter your userid in the 'Your User ID' field instead of entering your name in the 'Your name' field, then hit Preview and enter your password when asked for it.

Thomas wrote on Sat, Jan 17, 2009 10:53 AM UTC:
This is good to know. But can someone please tell me how it is done?

I can't log in. I just went to the 'Games for Game Courier' page,
clicked 'edit' at the bottom right of the page (is this the right way to
add more presets, BTW?), and after entering my username and PW, the login
window just appeared again with my PW deleted. I used the same data as
when saving a preset.

Maybe it's because I'm not a member nor a contributor yet. What should I
do next?

🕸📝Fergus Duniho wrote on Sat, Jan 17, 2009 03:18 AM UTC:
He must have already registered to be able to save Game Courier presets. He just needs to learn that the userid and password he is using with Game Courier is good throughout the site, including for entering messages and for posting member-created pages.

John Smith wrote on Sat, Jan 17, 2009 02:19 AM UTC:
Thomas, you should register. By doing so you can also create purely informational pages and have your comments appear more quickly.

Thomas wrote on Fri, Jan 16, 2009 11:24 AM UTC:
I'm done with four presets yet. They are automated and with
rule-enforcement and detect the end of a game (but not by threefold
repetition or 50 moves rule). I have tested them and they seem to be
bugfree. Maybe you want to include them into the 'Games for Game
Courier' list.

Breakthrough:
/play/pbm/play.php?game%3DBreakthrough%26settings%3DBreakthrough

Wildebeest Chess:
/play/pbm/play.php?game%3DWildebeest+Chess%26settings%3DWildebeest+Chess+with+rules

Gess:
/play/pbm/play.php?game%3DGess%26settings%3DGess+with+rules
Playing gess is a nuisance without an automated preset, so I wrote one. To
make the point-and-click movement usable, the preset expects that the
origin and destination coordinates of the direction stone are entered.
This is uncommon, normally a move is denoted by the coordinates of the
center of a piece (= 3x3 area containing a stone in the direction of
movement).

Squirrel Chess:
/play/pbm/play.php?game%3DSquirrel+Chess%26settings%3DSquirrelChess1
This variant I have made up myself. The difference to orthochess is only
the 9x9 board and every side has an extra pawn and a squirrel which leaps
two squares orthogonally or diagonally or like a knight (as described in
the piececlopedia). Pawns promote to squirrels also.


BTW: how can I uncheck 'exclude pieces not in setup' when editing a
preset? Somehow it doesn't work.

Is it possible to select some pieces out of a piece set and assign them 
names entirely of upper- or lowercase letters, so that 'isupper' and
'islower' can be used to identify pieces of a side?

🕸📝Fergus Duniho wrote on Sat, Jan 10, 2009 03:31 AM UTC:

Thanks for your bug report and your bug fix recommendations. I changed #ep in the p and P functions to var ep. You are right about the difference between the two in functions vs. subroutines. Functions and subroutines are very different things in GAME Code. A subroutine is made up of lines of code. When a subroutine is called, program execution jumps to the subroutine, and as the program goes through the subroutine, it executes each line of code afresh. In this context, it doesn't matter whether a variable's value is called by the var operator in an expression or with the # prefix. But in functions it does matter, because when a function is called, the program does not go back to the function definition and execute it afresh. Instead, it draws an already created function from a table of functions. If a variable in a function definition is accessed by the # prefix, then its value at the time of the function definition shapes the function. To use whatever value the variable has whenever the function is executed, the var operator needs to be used instead of the # prefix.


Thomas wrote on Fri, Jan 9, 2009 06:10 PM UTC:
Here I am again with one more bug ;)

In file chess2.txt the 'stalemated' subroutine doesn't recognise en
passant captures. I tested this with my Squirrel chess preset. In a
position where the only legal move is an ep capture, it says
'stalemate'.

By experimenting I found that it should work if in the functions P and p
'#ep' is replaced by 'var ep'.

It seems that '#' inside a function inserts the value of the variable at
the time the function is defined, while 'var' is reading the value when
the function is executed. But this seems not to be so for subroutines.
Here # and var have the same effect (at least I haven't observed a
difference yet).

🕸📝Fergus Duniho wrote on Sun, Jan 4, 2009 04:41 PM UTC:
Thank you for the fixes and explanations. But you have overlooked that in
sub 'enpassant' there is twice 'filename' used.
It should be 'filename #to rankname #from'.

Thanks for mentioning that. It's now fixed.

To check if any piece or any empty square is attacked, one could use the
following subroutine:

This subroutine may work for Chess, but it would not work for games with other divergent pieces, such as Cannons. The best way to handle attacks on empty spaces that a King must pass through to castle is to move the King to each square before checking whether it is attacked, which I have now done. This works equally well for any divergent piece.

A better method than your subroutine to check whether an empty space is attacked is to temporarily fill an empty space with a piece then check for attacks on it. With an enemy Cannon on a player's first rank, this would not work accurately for castling, though it would give the right result for the wrong reason. Let's say that the first rank just has an unmoved King and Rook with an enemy Cannon on the other side of the King. Although the Cannon attacks the spaces between the King and Rook, it is not accurate to say that the King would be passing through check from the Cannon if it castled. After all, the Cannon attacks the space just to the other side of the King, using the King as the screen, but the King may legally move there, because there is no screen between the King and the Cannon. Still, castling would put the King in check, because the Rook would become a screen. So, castling would still be illegal. In most instances, using an attacked subroutine that temporarily places a piece on an empty space would work for castling. But if you had a game in which Rooks can block Cannon attacks, then castling would be legal, and this method of checking for attacks would not work for castling. Alternately, if you had a piece that can check the King but not any other piece, or a piece with an attack that only affects the King, such as the Kings' long range attacks on each other in Eurasian Chess, then whether or not this subroutine worked well with castling would depend in part on which piece is temporarily placed on the empty space.

Note that the changes I made to the castle subroutine in the chess2 include file are not needed in the chess include file, because that include file uses separate functions to determine whether the King is attacked.


Thomas wrote on Sun, Jan 4, 2009 03:10 PM UTC:
Thank you for the fixes and explanations. But you have overlooked that in
sub 'enpassant' there is twice 'filename' used.
It should be 'filename #to rankname #from'.

To check if any piece or any empty square is attacked, one could use the
following subroutine:


// This subroutine checks whether 'square' is attacked by the given
side:

sub attacked square bywhite:
  local from piece pawn pdir;
  if #bywhite:
    def enemies onlyupper;
    set pawn P;
    set pdir 1;
  else:
    def enemies onlylower;
    set pawn p;
    set pdir -1;
  endif;
  for (from piece) fn enemies:
    if == #piece #pawn:
      if checkaleap #from #square 1 #pdir or
         checkaleap #from #square -1 #pdir:
        return #from;
      endif;
    elseif fn #piece #from #square:
      return #from;
    endif;
  next;
  return false;
endsub;

🕸📝Fergus Duniho wrote on Sat, Jan 3, 2009 03:52 AM UTC:

Thanks for your bug reports, Thomas. Here is a checklist of what I have dealt with.

The operator sign calculates the sign of the operand decremented by 1.

Fixed.

In the preset for orthodox chess (and maybe in some others too) it is not
tested if a rook to castle with has been captured. One should add
  unsetflag dest;
at an appropriate place in the code.

Yes, it allowed the King to castle with a Queen that captured a Bishop that captured the Rook. I fixed it in the Chess preset. To avoid editing numerous presets, I may modify the - operator to unset flags and create a system variable for turning this behavior off for games that use flags differently.

In the file 'chess2.txt':

In function p: checkatwostep must have the arguments 0 -1 0 -1;

Fixed.

Functions p and P allow captures to occupied squares only (except
enpassant). Thus they are not suited to test if an empty square is
attacked, and the subroutine 'castle' doesn't work correctly. It calls
'checked' to test for castling out of or through check, which in turn
uses p and P.

TO DO. I'm not sure if I can fix the functions, since the stalemated subroutine uses them to check whether any piece may move. What I should do is rewrite the castle subroutine to move the King one space at a time, checking whether the King is in check for each step of its move. Then these functions should work with the castle subroutine.

In sub stalemated: If a royal pawn captures en-passant, the captured pawn
isn't removed.

I never anticipated royal Pawns. Since I don't know of any games with royal Pawns, and I don't think royal Pawns would make for a very good game, I have simply modified the comments to say that it doesn't work for royal Pawns.

 (also, 'store' and 'restore' are called more often than necessary.)

The stalemated subroutine calls store once. It might call restore in one spot where it's not needed, but it doesn't hurt. Every time restore is used after a move, it is necessary.

In sub 'enpassant': The line
  set #pe join filename #to filename #from;
should be replaced by
  local pe;
  set pe join filename #to rankname #from;

Fixed

In sub castle: near the end there should be 'subargs' instead of
'subarg'.

Fixed.


🕸📝Fergus Duniho wrote on Fri, Jan 2, 2009 10:07 PM UTC:
Even if en passant and castling moves were fully written out, so that automation was not required for these moves, it would be a mistake to check only the last move, because the legality of these moves depends not only on the board position but also on the past history of the moves. Checking all prior moves each turn allows for the bookkeeping that must be done to determine if an en passant move or castling move will be legal. Besides, checking only the last move won't save much time. Checking a series of moves doesn't take very long, even for long games. Compared to checking for checkmate and stalemate, which require checking out alternate lines of play, checking the legality of a move doesn't take very long at all.

🕸📝Fergus Duniho wrote on Fri, Jan 2, 2009 08:29 PM UTC:
I'll need to get home before I can deal with the bugs, but I'll answer your other question now. The difference between numbers and strings should be the same as it is in PHP. Being programmed in PHP, GAME Code just inherits the types of its parent language. However, a test I ran using pregame code says that a number is identical to the string representation of the number. This may be because Game Courier handles each line of code as a string and does not attempt to distinguish between numbers and quoted numerals.

🕸📝Fergus Duniho wrote on Fri, Jan 2, 2009 03:55 PM UTC:
Thanks for your bug reports and questions. I will deal with them more thoroughly when I don't have my breakfast waiting for me. To answer your last question, it would be a mistake to test only the last move, because that would not allow for moves with automated behavior, such as castling and en passant. Also, bugs sometimes allow illegal moves, and if you tested the legality of only the last move, a bug fix would not catch any prior illegal moves.

Thomas wrote on Fri, Jan 2, 2009 11:27 AM UTC:
I have looked at 'chess2.txt' as you recommended, and rewrote my
Squirrel
Chess preset to use it (because this was easier than Wildebeest Chess).
Also I have experimented and looked at some other presets.
Thereby I have found some bugs:

The operator sign calculates the sign of the operand decremented by 1.

In the preset for orthodox chess (and maybe in some others too) it is not
tested if a rook to castle with has been captured. One should add
  unsetflag dest;
at an appropriate place in the code.

In the file 'chess2.txt':

In function p: checkatwostep must have the arguments 0 -1 0 -1;

Functions p and P allow captures to occupied squares only (except
enpassant). Thus they are not suited to test if an empty square is
attacked, and the subroutine 'castle' doesn't work correctly. It calls
'checked' to test for castling out of or through check, which in turn
uses p and P.

In sub stalemated: If a royal pawn captures en-passant, the captured pawn
isn't removed. (also, 'store' and 'restore' are called more often
than necessary.)

In sub 'enpassant': The line
  set #pe join filename #to filename #from;
should be replaced by
  local pe;
  set pe join filename #to rankname #from;

In sub castle: near the end there should be 'subargs' instead of
'subarg'.



Also I have some questions:

Is there a difference between numbers and strings, or are numbers just
strings consisting of digits only?
In the following code:
set wpr 2;
if == rankname #from #wpr: ... endif;
either rankname gives a number if the ranks are labelled with numbers, or
numbers are strings, or numbers are implicitly converted to strings (or
vice versa).

Wouldn't it be reasonable to check the legality of the last move only?
In
all presets I have seen the legality of every move is checked, but if a
preset rejects all illegal moves, all moves except maybe the last must be
legal, if I don't overlook something.


BTW: I plan to write a 'chess3.txt' include file which is more flexible
and general, first to practice writing GAME Code and second because it
might be of use for you and others. Before I begin, I should know if it
can be a mistake to thest the legality of the last move only. This
would improve efficiency in long games.

Thomas wrote on Sat, Dec 20, 2008 11:17 AM UTC:
Thank you!
I'll look at the chess2 file and see how I can use it.

I started to program Wildebeest Chess because it is a good practice in
GAME Code and because there is not yet a preset with rule enforcement (at
least I have found none).

🕸📝Fergus Duniho wrote on Sat, Dec 20, 2008 12:33 AM UTC:
There was a bug in the code for do-loops. I fixed the bug, and your code works now. BTW, if you're interested, there's an easier way to program the rules of Wildebeest Chess. It involves using the chess2 include file, writing a few extra functions, and modifying the K, k, P, and p subroutines.

Thomas wrote on Fri, Dec 19, 2008 05:43 PM UTC:
The link to the preset:
/play/pbm/play.php?game%3DWildebeest+Chess%26settings%3DWildebeest+Chess+with+rules

The error occurs in the procedure 'checkkcastl' in the pre-game part.
Near the end there is a do-until loop that checks if the king crosses
attacked squares. This loop seems to cause the error.

The error occurs when legally castling with the king over 2 or more
squares (entered as a king's move, e.g. f1-h1). Then the said loop is not
ended by the 'die' command but by the until-condition, and the error
message is produced.

If I castle over an attacked square, the 'die' ends the loop, and it
works correctly.

🕸📝Fergus Duniho wrote on Fri, Dec 19, 2008 04:58 PM UTC:
I might have to see the larger context to say. Give me an URL to your preset.

Thomas wrote on Fri, Dec 19, 2008 03:20 PM UTC:
Sorry I have to pester you again:

I'm writing a preset for Wildebeest Chess.
Now I have a strange bug in the code which I can't understand. I have
boiled it down to the following little procedure:

sub test;
  my i;
  set i origin;
  do:
    if != space #i @:
      die X.;
    endif;
    set i where #i 0 1;
  loop until == #i dest;
endsub;

This is defined in the pre-Game part. In the Post-Move-1 part I call the
procedure:

gosub test;

Then I enter a pawn move, e.g. f2-f5 and I get the error message
'misplaced endsub' at the line number where the procedure 'test' ends.
Why is this?

🕸📝Fergus Duniho wrote on Fri, Dec 12, 2008 06:06 PM UTC:

In the presets for Extra Move Chess and Marseillais Chess, I stored the board configuration before the move, parsed the moves entered by the player, restored the board to its premove configuration, then evaluated the moves individually. You could do something similar. I recommend restoring the board and evaluating the moves separately only when there are multiple moves, allowing the preset to just go ahead and evaluate the single move when only one move has been made.

Another alternative is to allow the castle subroutine and require players to use it for castling. It is supposed to be able to handle free castling. Details are provided in the comments before the subroutine in the include file. The examples you gave could be rewritten like this:

e1-d1; castle e1;
e1-b1; castle d1;

Thomas wrote on Fri, Dec 12, 2008 12:51 PM UTC:
I want to restrict user input so:

setsystem maxmove 2;
ban commands allmoves;
allow moves 1 moves 2 captures 1 promotions 2;

The purpose is to allow entering a generalized castling move, examples:

e1-d1;a1-e1
e1-b1;a1-d1

But then the user might enter something like c1-f7;d2-d4 , the first part
being illegal. The preset should reject this move, but it is difficult,
because the system variables only reflect the (legal) second part d2-d4 :

old = @
origin = d2
dest = d4
moved = P

Is it possible to get info about the first move-part, or at least the info
that the user has entered two parts?

Thomas wrote on Sat, Nov 29, 2008 11:04 AM UTC:
Thanks for your explanations!

I have suspected the problem with ep == false. I should correct my
Squirrel Chess preset due to this.

🕸📝Fergus Duniho wrote on Sat, Nov 29, 2008 12:27 AM UTC:

Thanks for your interest in GAME Code.

1. I've had the same problem, but I haven't taken the time to look into it. Maybe I will sometime.

2. Fixing a preset people are using should normally have no harmful effect on any ongoing games. It might break some logs if someone has made an illegal move and your bugfix corrects this. I can fix logs manually when this happens. Adding the ability to spot check, checkmate and stalemate is unlikely to break any logs unless someone continued a game past its natural end.

3. While there is no defined behavior, tests indicate that when the stack does not have all the operands required by an operator, the operator gets null values for the remaining operators. For example, '+ 1' returns 1, '* 1' returns 0, '- 1' returns 1, and '/ 1' complains of a division by zero error and returns nothing.

If there are more values on the stack after evaluating an expression, the expression will return a backwards array of all the values remaining in the stack. For example, set a + 5 6 - 8 3 sets a to the array (5 11). To get an array in the same order as the remaining operands, use the array operator, as in set a array + 5 6 - 8 3, which sets a to the array (11 5). Sub-expressions within a larger expression will use only as much of the stack as they need and return values to be used in the larger expression. For example: set a * + 5 6 - 8 3 would reduce to set a * + 5 6 5 then to set a * 11 5 and finally to set a 55.

Since GAME Code is loosely typed, it will convert a value given as one type to the type of value it is using. For example, a boolean value of false would be treated as zero by a math operator. In your example, 'where #ep 0 1' where ep is set to false, it apparently got interpreted as a1, whose index in the list of coordinates is zero. It is normally expected that you will write your code to give operators the types of operators they expect, and the results you may get from bad data are undefined.

4. The notation for coordinates and pieces are strings. In Game Courier, the board is represented by an array whose keys are coordinates and whose values are pieces, @ signs for empty space, and - signs for offboard locations. This array is called $space, and GAME Code lets you read the contents of its elements with the space operator.


Thomas wrote on Fri, Nov 28, 2008 05:18 PM UTC:
I have written two presets:

/play/pbm/play.php?game%3DBreakthrough%26settings%3DBreakthrough

/play/pbm/play.php?game%3DSquirrel+Chess%26settings%3DSquirrelChess1


May I ask some questions about Game Courier / GAME code:

1. I observe that I can't enter comments starting with '//' in the
Pre-Game part. I wrote:

// comment
setsystem maxmove 2;
...

And I receive an error message:

Syntax Error on line 0
// comment
setsystem maxmove 2 is not a valid expression, because // is not a
recognized piece, coordinate, command, or subroutine.

Why is this?


2. What happens if I edit and save a preset if there are already players
using it, e.g. when I remove a bug or add notification for mate /
stalemate. Can this cause problems?


3. What happens if an operator needs more operands than are on the stack,
or if there are two or more values left on the stack after evaluating an
expression, or if an operator is given an operand with a senseless type,
e.g.:
  set ep false;
  ...
  if equal where #ep 0 1 a3;
    ...
  endif;

Are there rules how such cases are handled, or does the program behave in
an undefined way?


4. am I right that a board position (like 'a4') is of type 'string',
and also a piece type like 'n' or 'K'? Or are these special types on
their own?

🕸📝Fergus Duniho wrote on Sun, Oct 12, 2008 07:51 PM UTC:

I have finished programming some commands for restricting user input. I have rewritten the ban command to handle types of movement, I have introduced the allow command, and I have added a system variable for restricting the length of a full move. These changes do not affect any games that do not enforce rules. They are merely provided as options to help developers program better rule enforcement. Here is how they would generally be used together for Chess:

setsystem maxmove 2;
ban commands allmoves;
allow moves 1 captures 1 promotions 2;

I have added this code to the Chess include files, and I have added appropriate code to some of the other include files. So extraneous user input should now be banned in several games that enforce the rules. If you have programmed rule enforcement for your own presets that do not include any of my include files, then you will need to add this or similar code yourself.

If you program in GAME Code, you may want to take note of this. One internal change I made while programming these features was to separate user input from GAME Code commands. The result is that user notation can no longer be used inside of a GAME Code program as programming code unless the line is prepended with the keyword 'MOVE: '. In general, it is best to reserve user notation for the players and use only commands in the code you program.


🕸📝Fergus Duniho wrote on Tue, Sep 30, 2008 03:52 AM UTC:
I have now modified the eval command to evaluate and execute as a command any Polish notation expression given to it. If given an array, it treats it as multiple lines of code and executes all of it. Here is an example of its use:

eval join 'shift ' list ray a1 1 0;

Since quotation marks will mess up code entered as a move, here is an alternate version someone could type as a move:

eval join join shift ws list ray a1 1 0;

ws (also whitespace) is a new unary operator that returns a space character.

This will also work:

eval join join shift chr 32 list ray a1 1 0;

🕸📝Fergus Duniho wrote on Tue, Sep 30, 2008 02:19 AM UTC:
Trying to change how preprocessing works turned out to be a dead end. While trying to work out the bugs it introduced, I discovered that some commands depend upon it working the old way. But I also discovered an undocumented command that will do what you want. The command is eval. It will evaluate the variable that comes after it as though it were a line of code. Here is some code that lets you use information from the ray operator to shift pieces:
set rowe join 'shift ' list ray a1 1 0;
echo #rowe;
eval #rowe;
The first line creates the line of code for shifting pieces and copies it to the variable rowe. The second line shows you what that line of code looks like. The third line executes the line of code.

🕸📝Fergus Duniho wrote on Sun, Sep 28, 2008 02:47 AM UTC:
Larry,

It's not a problem with the shift command. It is a systemic problem with preprocessing. As the word suggests, preprocessing should be done before any other processing of a line of code, but I had combined preprocessing with line parsing. The undesired result of this is that it treats your list of arguments as a single argument. I will work on separating preprocessing from parsing, so that things work as they should.

Joe Joyce wrote on Sun, Sep 28, 2008 01:35 AM UTC:
'Thanks again for Game Courier. I haven't seen anything quite like it anywhere else on the Web.' - from the previous post

I will second that. Thank you, Fergus. Also note that game Courier has some 600+ presets, found here and at the CVwiki. To the best of my knowledge, no one else matches that, and certainly no one else matches that in abstract [strategy] games. Is there any other site that comes close? Thanks also to those who have done presets. Jeremy Good, in particular, has some 100 presets to his credit. 

This does bring up the question of how we rate these things. The recognized games haven't been getting much recognition lately. Should we attempt to recognize more, and if so, just how? Game ratings can be somewhat subjective. I think we can see some need, with 600 games, to rate them in some manner. Even if it's something short, like:
 'Excellent concept game. Unplayable.'
The question is: should we try? Is it worth it, given likely results such as 'animated' discussions? George Duke expanded the criteria for 'the next chess', and we can look at possibilities, and compare them. We could rate games by first dividing them into categories, and rate games by types, rather than just seeing all games as in the 'variant' category. So you wouldn't have games like Pocket Mutation [my pick for best '00s CV] and Rococo going up against each other for the one initial spot of 'recognized'. Heh, what are the different categories of CVs?

Larry Gilbert wrote on Sat, Sep 27, 2008 11:19 PM UTC:
Fergus, thanks again for all of your help. The list operator looks like it's working, and so GAME Code looks like it's all working as documented now.

It still doesn't look like shift will take an array or a 'list'-ed string, but please don't worry about changing that urgently. I've had enough time to think about what I wanted to use shift for, and I think I can do it with a custom, recursive subroutine instead. If you think it needs 'fixing,' go ahead and fix it, but there is no need to do so on my account.

Thanks again for Game Courier. I haven't seen anything quite like it anywhere else on the Web.


🕸📝Fergus Duniho wrote on Tue, Sep 23, 2008 11:40 PM UTC:
There was a bug in the code for the list operator. It is now fixed.

🕸📝Fergus Duniho wrote on Tue, Sep 23, 2008 11:33 PM UTC:
Ray is a ternary operator. It takes three arguments. Your use of ray is missing the first argument, which should be a coordinate.

Larry Gilbert wrote on Tue, Sep 23, 2008 09:55 PM UTC:

I hope I am not being a pain yet... Unfortunately, I still can't get things to work the way we expect. I think the point of failure is with the list operator (or how I'm using it). This snippet should reproduce the problem. It ends with strcoords being empty--not an empty array, just nothing.

set arraycoords ray 0 1;
set strcoords list var arraycoords;
dump;
shift #strcoords;

Larry Gilbert wrote on Tue, Sep 23, 2008 02:50 PM UTC:
Great, I will try it out. Thank you again!

🕸📝Fergus Duniho wrote on Tue, Sep 23, 2008 01:38 AM UTC:
As originally written, the list operator would not do what you want. I just rewrote it so that it will, and I updated the documentation on it. It will work with either a single array or the contents of the stack if the first element after the list operator is not an array.

🕸📝Fergus Duniho wrote on Tue, Sep 23, 2008 01:18 AM UTC:
The list operator should do the job. Your code should probably look something like this:
set stringvar list var arrayvar;
shift #stringvar;

Larry Gilbert wrote on Mon, Sep 22, 2008 03:18 AM UTC:

I have another question, and I'm sorry if this is a trivial one.

I would like to use the shift command, but it doesn't seem to accept an array, and I need to be able to give it a list of coordinates from an array. Is there any operator that will empty an array and put all of its contents back onto the stack? In other words, is there something that does the inverse of array?


Larry Gilbert wrote on Mon, Sep 22, 2008 01:53 AM UTC:
Very good; thank you!

🕸📝Fergus Duniho wrote on Sun, Sep 21, 2008 11:21 PM UTC:
Okay, the problem with reverse is fixed. In my code for the operators, each operator is nested in two switch-case statements. The outer one groups operators around the number of operators it takes. Anyway, although the code for reverse appeared in its inner switch-case statement, it was missing the 'case 'reverse':' code in the outer switch-case statement. So it wasn't recognizing the operator. Adding it fixed the problem.

Larry Gilbert wrote on Sun, Sep 21, 2008 11:00 PM UTC:

Hello Fergus,

I appreciate your help with this! I'll admit that the initial learning curve has been steep for me. It's been so long since I did anything with Polish notation that I'm basically starting over (but I'm learning to appreciate it again, too).

I will study your new example of the cond operator more closely. For right now, here is some code that I think will illustrate the problem I'm having with the reverse operator. And it may either be a bug or just my misunderstanding of how things should work.

set arrayvar ray a1 1 1;
set reversedarray reverse #arrayvar;
dump;
exit;

What I was expecting to see in the dump was reversedarray having the same contents as arrayvar, but in reversed order. Instead, I get this:

    [reversedarray] => Array
        (
            [0] => Array
                (
                    [0] => b2
                    [1] => c3
                    [2] => d4
                    [3] => e5
                    [4] => f6
                    [5] => g7
                    [6] => h8
                )

            [1] => reverse
        )

🕸📝Fergus Duniho wrote on Sun, Sep 21, 2008 03:22 AM UTC:
In searching through my include files, I couldn't find any line of code that uses the reverse operator. So it might have gone untested. Show me the code you are trying to use it in.

🕸📝Fergus Duniho wrote on Sun, Sep 21, 2008 03:15 AM UTC:
Larry,

I believe I have code in which the cond operator is working properly. For example, it is used in 

/play/pbm/includes/ivorytower.txt

and the code for Storm the Ivory Tower works. It is used in the code for Clodhoppers (C/c), for example, and in test moves I've made, only legal moves have been accepted.

Cond is a useful operator for pieces with divergent moves, such as, for example, pieces that move one way and capture another way, or pieces that move differently depending on their position. Cond can be used to check which rules of movement apply to a piece's move and then to apply the correct rule of movement. To illustrate, I'll give an analysis of its use in this line of code:

def C cond cond empty #0 (not capture) (empty #1) (checkride #0 #1 1 1 or checkride #0 #1 0 1) (checkhop #0 #1 1 1 or checkhop #0 #1 0 1) and fn legaldir #0 #1;

Remember that evaluation begins at the end and proceeds backwards. First, it checks whether the move was made in a legal direction. This is a requirement for any move in this game, and it is not part of the cond statement. It just stops the move if it is in a direction no arrow points.

This code has two cond statements. The inner cond statement, which sets the condition for the outer cond statement, checks whether the move was not a capture. I think I expressed it as a cond statement to allow the function to be used for hypothetical moves that get evaluated during the stalemate function. In a normal move, the origin space (#0) will not be empty, and it will just need to evaluate (empty #1) to tell whether the move was to an empty space (and hence not a capture). In a hypothetical move, the origin space might be empty, though my memory is hazy on this, and I can't pinpoint why this would be right now. Anyway, this inner cond returns true if the move was not a capture and false if it was. So, if it was not a capture, it evaluates whether it was a legal riding move, and if it was a capture, it evaluates whether it was a legal hopping move, because Clodhoppers capture by hopping but otherwise move by riding.

🕸📝Fergus Duniho wrote on Sun, Sep 21, 2008 03:00 AM UTC:
Larry,

You are correct about the user-defined placeholders beginning at #0. I looked at some of my own include files written in GAME Code, and I was routinely using #0 as a placeholder with the def command. I have updated the guide to correct this.

Larry Gilbert wrote on Sat, Sep 20, 2008 12:52 AM UTC:
Okay, now I'm really going crazy.

The doc says that the 'reverse' operator takes an array and returns a new array with the elements reversed. But whenever I try to use it, it's as if it doesn't even exist in the language. In other words, what I end up with on the stack is not a reversed array but the word 'reverse' and a copy of the array I'm trying to reverse!

Help?


Larry Gilbert wrote on Fri, Sep 19, 2008 08:30 PM UTC:
I haven't been able to reproduce this 100% yet, but it seems that using cond within a function defined with def causes invalid results in all cases, not just in cases where the function is recursive.

Larry Gilbert wrote on Wed, Sep 17, 2008 10:15 PM UTC:
Under 'User Defined Functions,' I believe the argument placeholders really are numbered starting at #0 now, contrary to the present instructions.

Greg Strong wrote on Wed, Oct 11, 2006 01:14 PM UTC:
Oh, ok. Thanks, Fergus. I was wondering why I didn't see the card commands. I looked at presets for other games, but they didn't seem to do what I want. I'll look at the user's guide when I get a chance but it will probably be a few days before I get to it. No hurry anyway. Thanks for the help!

🕸📝Fergus Duniho wrote on Wed, Oct 11, 2006 01:59 AM UTC:
Maybe that won't work, because played cards also go to the discard pile. The place and displace commands might be helpful for what you want. But I might just have to modify the commands used for cards. By the way, all the card commands are described in the User's Guide, not here.

🕸📝Fergus Duniho wrote on Wed, Oct 11, 2006 01:11 AM UTC:
Try this. It is probably best to do this through programmed automation, not with user-entered commands. On each move, each player draws all the cards from the discard pile, and if the discard pile has any fewer than four, he draws the rest from the deck. This may require a loop that draws one card at a time, checking each time whether the discard pile is empty. When a player ends his turn, he discards the rest of his hand. This allows his opponent to pick up what is left of his hand.

Greg Strong wrote on Tue, Oct 10, 2006 01:16 PM UTC:
I am interested in creating a game, but I am not sure it is possible. From what I see in the developer's guide, I do not see what I need. This is a chess-type game, also with a deck of cards. The deck of 52 cards would be shuffled, and four would be drawn and placed out for either player to use. When a card is played, it would be replaced by the next card drawn from the deck. When the last card is drawn, that is it, no more cards. Can anyone think of a way to do this with Game Courier?

Joe Joyce wrote on Fri, Aug 4, 2006 05:18 PM UTC:
David, thank you very much. It's gratifying to know that it's not *always* me when it comes to computer-type problems. Now, if only my son would believe that... And thanks for looking into making the number of players more flexible. I also appreciate the efforts that have already been made to make indexing more useful for people like me. [Finally, I was thinking of making a mixed 2D-4D version of this game...]

David Howe wrote on Fri, Aug 4, 2006 01:42 PM UTC:
I've changed the name. I will look into the problem you had changing the name. As to the number of players, there is currently no way to specify a range other than to make two separate index entries. I will look into improving this aspect of the indexing.

Joe Joyce wrote on Fri, Aug 4, 2006 12:55 PM UTC:
I am attempting to change the name of my recent submission from 'Chieftain
Chess with Preset' to 'Chieftain Chess', now that a preset page is
available. I am also trying to indicate it is multi-player, with 1-4
players per side, for a total of 2-8 players. I seem to be having 2
problems. First, when I try to do the name change, I get this error
message:
 Error performing query: Duplicate entry 'MSchieftainchess' for key 1
Second, is there a way to indicate a range in the number of players per
side?  I will put in '1-4' and '2-8', but what comes up is '1' and
'2'. 
Any information or assistance will be greatly appreciated.

🕸📝Fergus Duniho wrote on Tue, Jun 20, 2006 02:23 AM UTC:
I have just added a recolor command and a color operator. These are for manipulating and reading the background colors of spaces. These work with color indexes, not with the actual colors seen by users. The actual colors are hardcoded into a preset and may be changed to suit a user's preferences. This gives users the freedom to choose the colors they want to use while still allowing games that change or use information on the colors of spaces. Naturally, recolor and color are of use only with boards based on a set of colors. They will not be useful with boards based on graphic images.

🕸📝Fergus Duniho wrote on Fri, Apr 7, 2006 03:39 AM UTC:
Not without a lot of work. The Java applets on this site were all written by other programmers, none of whom have worked on Game Courier, and I, the creator of Game Courier, have no experience programming in Java.

pallab basu wrote on Fri, Apr 7, 2006 01:22 AM UTC:
Can one develop a javaboard type application for game courier, from which one may play just by mouse clicking. You already have similar type of system for computer play.

🕸📝Fergus Duniho wrote on Sun, Feb 6, 2005 09:41 PM UTC:
Game Courier can now render boards as GIF files. I have also programmed the GIF and PNG rendering methods to be able to resize images with little or no distortion to the image. Previously, a resized PNG file would be very ugly, but no more. Resized GIF files get the palette reduced back to 256 colors and are dithered. Resized PNG files make use of the PNG format's ability to handle true color images. This results in no distortion but also a larger file size than a resized GIF or JPG. Although the PNG method can handle true color images, it will normally start out as a small-palette image. So JPG is better if you are using a JPG background for your board.

Greg Strong wrote on Mon, Jan 10, 2005 06:57 PM UTC:Excellent ★★★★★
Oh yes, this is a great addition for so many reasons...  Thanks!  I'm
especially pleased that pieces can now be represented by the correct
letters for the game, without requiring a proliferation of piece sets. 
The ability to use the plus-sign in the name for shogi pieces is a very
nice touch, too.

I would like to suggest something, though.  Right now, when moving a piece
you can either enter the piece type ('P e2-e4') or not ('e2-e4').  I
always do the former, because it makes it easier for me to keep track of
games.  Some opponenets do, some do not.  I would be nice if, when
entering a simple single-move, like 'e2-e4', it would automatically add
the 'P' or 'p'.  

Thanks for the consideration.  You have done a lot of good work on
improving the Game code recently!  I need to get to work on presets using
the new features for wildebeest chess, lions & unicorns chess, and others.

Tony Quintanilla wrote on Mon, Jan 10, 2005 06:12 PM UTC:Excellent ★★★★★
Excellent addition that will make play and presentation more intuitive and appealing. Thanks!

🕸📝Fergus Duniho wrote on Mon, Jan 10, 2005 05:57 PM UTC:
<P>I have added the <B>alias</B> command, which is quite a significant new command that will change how presets are developed. It significantly reduces the need to create new sets and to use the Custom Board rendering method. This command lets you create aliases for piece and coordinate labels, which players may use for entering moves in place of the internal representations used by Game Courier. Heretofore, internal and external representations have been identical. Now they may be separated. Here are some examples for how this can be used:</p> <P>I have added the following line to the Shogi presets:</P> <PRE> alias +p t +n y +l m +s v +r d +b h +P T +N Y +L M +S V +R D +B H; </PRE> <P>This provides more intuitive labels for promoted pieces. Each promoted piece is now represented to the players as a plus sign before the type of piece it is the promoted form of. For backwards compatibility with pre-existing games, the internal representations still work. But the new ones may now be used, and they are what show up in tooltip text when you place your pointer over a piece.</P> <P>I have added the following line to the Grotesque Chess preset:</P> <PRE> alias e a E A g m G M; </PRE> <P>This allows the use of e and E for the Equerry and the use of g and G for the Guard.</P> <P>If I were to do an Omega Chess preset, I could use the usual rank and file system to define the board and then use the alias command to create aliases for the four corner squares. Previously, I would have had to settle for not using the official names for those squares or for figuring out how to enforce rules with the Custom Board method, which would be difficult. But now by distinguishing between internal and external coordinate systems, I can use an internal representation that is perfectly logical while allowing players to use the official coordinate system for a game. Likewise, I could now make a preset that enforces the rules for Glinski's Hexagonal Chess and that also lets players use its official coordinate system, which is unsuitable for simple mathematical descriptions of piece movement.</P>

🕸📝Fergus Duniho wrote on Sun, Jan 2, 2005 09:53 PM UTC:
I have now modified the Alfaerie-JPG version of the Chess preset to use the
code I've been working on for identifying check, checkmate, and stalemate.
For each of these, it will put an appropriate message above the board, and
for checkmate and stalemate, it will automatically update the status.

I have also created the commands won, drawn, and lost for updating the
status. The <B>won</B> command declares the current player to be the
winner, <B>lost</B> declares the current player's opponent to be the
winner, and <B>drawn</B> declares the game drawn. Don't confuse this with
draw, which is a command for drawing cards. The lost command is an alias
for resign, to be used when a player has already lost without resigning.

🕸📝Fergus Duniho wrote on Sun, Jan 2, 2005 09:47 PM UTC:
This comment, which I accidently posted on the wrong page a couple days
ago, belongs on this page:

I added the following new functions to the Polish notation calculator
today:

checkmaxsteps
checknsteps
checkpath

These all handle movement that may go along a winding, unobstructed path,
such as the movement of some pieces in Jetan. The checkmaxsteps function
checks whether a piece may move from one space to another within a
specified number of steps from one adjacent space to another. The
checknsteps function checks whether a piece may move from one space to
another in exactly a specified number of steps. Both of these functions
allow movement through the origin space and repeated movement through the
same space. They are both handled by a recursive function that goes
through all possible paths until it finds one that works. The checkpath
function checks whether a piece can move from one space to another by
following a specific path, given as a set of paired directions. To
illustrate how these work, here are two alternate ways to handle the
Squire from Holywar:

Barring possible mistakes, here is the long way that uses 16 checkpath
functions for all possible paths:

checkpath origin dest (1 0 1 1) or checkpath origin dest (1 1 1 0) or
checkpath origin dest (1 0 1 -1) or checkpath origin dest (1 -1 1 0) or
checkpath origin dest (-1 0 -1 1) or checkpath origin dest (-1 1 -1 0) or
checkpath origin dest (-1 0 -1 -1) or checkpath origin dest (-1 -1 -1 0)
or
checkpath origin dest (0 1 1 1) or checkpath origin dest (1 1 0 -1) or
checkpath origin dest (0 1 -1 1) or checkpath origin dest (-1 1 0 -1) or
checkpath origin dest (0 -1 1 1) or checkpath origin dest (1 1 0 1) or
checkpath origin dest (0 -1 1 -1) or checkpath origin dest (1 -1 0 1);

Here is the short way that uses checknsteps in combination with
checkleap:

checkleap origin dest 1 2 and checknsteps origin dest 2;

The checkleap function makes sure that the piece is going to a space a
Squire could move to, then the checknsteps function makes sure it can get
there in exactly two steps.

🕸📝Fergus Duniho wrote on Fri, Dec 31, 2004 12:24 AM UTC:
I went through my code today, adding descriptions to this page of functions, commands, and operators I had previously missed or only recently created. Except for the commands for cards, which are already described in the User's Guide, this page should have a complete and up-to-date description of the commands, operators, and built-in functions you can use in GAME Code.

🕸📝Fergus Duniho wrote on Thu, Dec 23, 2004 05:47 AM UTC:
One more thing. The new code is making use of two new commands called store and restore. The store command saves the current board configuration, including both piece locations and flags, and the restore command restores the board configuration to what it was the last time it was stored. These commands allow some subroutines to try various possible moves without permanently changing the board configuration.

🕸📝Fergus Duniho wrote on Thu, Dec 23, 2004 05:41 AM UTC:
I am currently developing code for checking whether a player is checkmated
or stalemated. It is not all working right yet, but if anyone wants to
take a look at it, you will find it here:

/play/pbm/includes/checkmate.txt

I am using it with a new version of the Chess preset:

/play/pbm/play.php?game=Chess&settings=checkmate

This preset is only for testing and should not be used for ongoing games.

Also, so that single and double quotation marks can be entered in the form
fields for GAME Code, I have switched to storing strings in settings files
with the heredoc format. This will not affect current presets unless they
are resaved.

🕸📝Fergus Duniho wrote on Tue, Dec 21, 2004 05:08 AM UTC:
Control structure commands that introduce a body of code can now be ended
with a colon instead of a semicolon. These include if, elseif, else, do,
for, foreach, switch, case, and default. I did this, because I think it
looks better. In other languages that end lines with semicolons, these
commands normally do not end with semicolons. Semicolons are still allowed
for backwards compatibility with old code. The program code is now broken
up with a specialized parsing function instead of exploding on
semicolons.

The foreach command is now an alias for the for command. Both commands
work much like foreach from Perl or PHP. By using an array instead of a
string for naming the for variable, you can get both the key and the value
of each array member. For example, the following code lists all the spaces
of the board, assuming the 64-times limit of echo isn't exceeded:

foreach (key val) spaces:
  echo #key #val;
next;

🕸📝Fergus Duniho wrote on Tue, Dec 21, 2004 03:22 AM UTC:
I've added switch, case, and endswitch commands. These work like switch and case in C, but not in PHP. The case statement can be used only with constant labels, because it works as a computed goto, not as a series of tests. I've modified the break command to be able to break out of a switch block. Details are in the section on control structures.

🕸📝Fergus Duniho wrote on Mon, Dec 20, 2004 06:10 PM UTC:
Over the weekend, I added the ability to use parentheses for expressing
arrays. For example, this will now set an array of all white pieces in
Chess:

set white (K Q R B N P);

Arrays are parsed recursively, so that nested parentheses will yield
multi-dimensional arrays.

When lines are evaluated by the Polish notation calculator, the contents
of arrays are not automatically evaluated. For example

set a * (+ 4 5) (- 9 5)

should not evaluate to 36.

But arrays may be conditionally evaluated by the logical operators and,
or, nor, nand, and cond, and also be eval and fn. For example,

set a * eval (+4 5) eval (-9 5)

would yield 36.

When given arrays as arguments, the binary logical operators will evaluate
the first array first, then evaluate the second only if its value is needed
to determine the value of the expression. For example,

set a or (== 4 4) (!= 4 7)

will evaluate only (== 4 4)

The cond operator is the equivalent of ?: in C or PHP. It will evaluate an
expression, and if it is true, it will evaluate the array following the
expression, but if it is false, it will evaluate the second array
following the expression. For example,

cond != 6 6 (== 7 9) (<= 9 7)

will evaluate (<= 9 7) but not (== 7 9)

Last night, there was still a problem with using parentheses with
recursive functions. That problem is now fixed. It is now possible to
write a recursive function like this one for finding a number's
factorial:

def fac cond equal #0 1 1 (* #0 fn fac dec #0);

Note that #0 is now the first placeholder instead of #1. I changed all the
placeholders in chess.txt to accomodate this.

This particular function has been tested and shown to work. It first
checks whether the value passed to it is equal to 1, with 'equal #0 1'.
If it is 1, it returns 1. Otherwise, it evaluates the array (* #0 fn fac
dec #0), which multiples the value passed to the function, #0, with a
recursive function call of one less than the value passed, dec #0.

🕸📝Fergus Duniho wrote on Sat, Dec 18, 2004 02:35 AM UTC:
I have been busy improving GAME Code this week. Here are some of the latest
improvements. Instead of using explode to split a line of code into strings
of non-whitespace, I have written some parsing functions. One parsing
function checks whether a line of code is a move, returning each item in a
separate argument. If it's not a move, a second parsing function is used.
This function parses out quoted strings, arrays, and non-whitespace
strings. Here's how it works.

It goes through each character of a line. It normally skips over
whitespace. When it finds a double quotation mark immediately after
whitespace, it copies everything until the next one as a single string.
When it find a left parenthesis, it copies everything until the next right
parenthesis, then recursively calls the parsing function on this. This
generates an array. Otherwise, it copies as a single argument whatever
text falls between whitespace. Also, it does additional preprocessing only
on unquoted nonarrays. So if you want to use 'origin', 'dest', or
'moved' as strings rather than as special variables, you can quote them
to use the strings. This is required if you want to use setglobal to set
the value of one of these variables.

I've added target and check operators to the Polish notation calculator.
These work sort of like switch and case. They are used for speeding up the
search for pieces that might be checking the King. Details are in the
documentation.

The fn operator now accepts nameless functions as arrays, which allows the
creation of nameless lambda functions.

🕸📝Fergus Duniho wrote on Thu, Dec 16, 2004 04:56 AM UTC:
<P>Here's what the most recent changes to Game Courier are about. Previously, the entire GAME Code program would be interpreted in one big <B>for</B> loop. I put this into a function so that GAME Code's subroutines could be handled through recursive function calls. This made it easier for me to have subroutines return values. So easy, in fact, that the Polish Notation calculator now includes the sub operator, which calls the named subroutine with a list of arguments, runs it, and returns its value. In this way, multiple subroutine calls can be included in a single Polish Notation expression.</P> <P>Also, Game Courier used to read through every line of a GAME Code program, skipping certain lines depending upon the value of conditions in if-statements and loops. It now uses direct jumps to bypass code it won't be executing. This doesn't really affect what you can do with the language, but it makes it more efficient.</P>

100 comments displayed

LatestLater Reverse Order EarlierEarliest

Permalink to the exact comments currently displayed.