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 Earliest Comments Only For Pages | Games | Rated Pages | Rated Games | Subjects of Discussion ]

Comments/Ratings for a Single Item

EarliestEarlier Reverse Order LaterLatest
Game Courier Developer's Guide. Learn how to design and program Chess variants for Game Courier.[All Comments] [Add Comment or Rating]
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 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?


🕸📝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.

🕸📝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: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.

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 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 Mon, Sep 22, 2008 01:53 AM UTC:
Very good; thank you!

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?


🕸📝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;

🕸📝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.

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

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;

🕸📝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.

🕸📝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.

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.


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?

🕸📝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.

🕸📝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 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 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.


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 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 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.

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?

25 comments displayed

EarliestEarlier Reverse Order LaterLatest

Permalink to the exact comments currently displayed.