Fix 1992/vern/README.md
This commit is contained in:
1 parent
1f6e7f2aa0
commit
c1d602e0cf
1 file changed
+97
-95
+97
-95
@@ -12,134 +12,136 @@
|
|||||||
|
|
||||||
make all
|
make all
|
||||||
|
|
||||||
### To run
|
### To run:
|
||||||
|
|
||||||
./vern 3 # <-- default is 2
|
./vern 3 # <-- default is 2
|
||||||
|
|
||||||
## Judges' comments
|
## Try:
|
||||||
|
|
||||||
You might start off by giving the following input:
|
|
||||||
|
You might start off by giving the following input:
|
||||||
|
|
||||||
63 43
|
63 43
|
||||||
76 55
|
76 55
|
||||||
71 52
|
71 52
|
||||||
67 57 (this may take a while)
|
67 57 (this may take a while)
|
||||||
|
|
||||||
The judges assume no responsibility for the obfuscated opening
|
## Judges' comments:
|
||||||
suggested above. :-)
|
|
||||||
|
|
||||||
For a real quick game try:
|
The judges assume no responsibility for the obfuscated opening
|
||||||
|
suggested above. :-)
|
||||||
|
|
||||||
|
For a real quick game try:
|
||||||
|
|
||||||
./vern
|
./vern
|
||||||
|
|
||||||
65 55
|
65 55
|
||||||
66 46
|
66 46
|
||||||
|
|
||||||
NOTE: Move values must be restricted to the range 00 to 77.
|
NOTE: Move values must be restricted to the range 00 to 77.
|
||||||
|
|
||||||
NOTE: Because some mailers have problems with the original winning source,
|
NOTE: Because some mailers have problems with the original winning source,
|
||||||
a slightly modified version with shorter lines has been provided.
|
a slightly modified version with shorter lines has been provided.
|
||||||
|
|
||||||
## Author's comments
|
## Author's comments:
|
||||||
|
|
||||||
This program plays chess. You play the white pieces and the program
|
This program plays chess. You play the white pieces and the program
|
||||||
the black pieces. Moves are entered as a two-digit number specifying
|
the black pieces. Moves are entered as a two-digit number specifying
|
||||||
the coordinates of the piece to be moved followed by another two-digit
|
the coordinates of the piece to be moved followed by another two-digit
|
||||||
number specifying the coordinates of where to move it. Rows and
|
number specifying the coordinates of where to move it. Rows and
|
||||||
columns are numbered starting with (0,0) for the upper-lefthand corner
|
columns are numbered starting with (0,0) for the upper-lefthand corner
|
||||||
(black's queen's rook) and going to (7,7) for the lower-righthand
|
(black's queen's rook) and going to (7,7) for the lower-righthand
|
||||||
corner (white's king's rook). For example, the PK4 opening for white
|
corner (white's king's rook). For example, the PK4 opening for white
|
||||||
is indicated as "64 44". Moves are read using scanf() so care should
|
is indicated as "64 44". Moves are read using scanf() so care should
|
||||||
be taken to not enter the wrong number of fields.
|
be taken to not enter the wrong number of fields.
|
||||||
|
|
||||||
If the move you enter is illegal then you are just prompted again to
|
If the move you enter is illegal then you are just prompted again to
|
||||||
move. If the move is legal then the new position is displayed and the
|
move. If the move is legal then the new position is displayed and the
|
||||||
program starts computing its response. For every 64 board positions it
|
program starts computing its response. For every 64 board positions it
|
||||||
examines a "." is printed. Once it has chosen its move it simply
|
examines a "." is printed. Once it has chosen its move it simply
|
||||||
displays the board updated to reflect the move.
|
displays the board updated to reflect the move.
|
||||||
|
|
||||||
Your move is prompted for using a string like "1351 9 2 >". The first
|
Your move is prompted for using a string like "1351 9 2 >". The first
|
||||||
number is how many board positions the program examined when computing
|
number is how many board positions the program examined when computing
|
||||||
its previous response. The second number is its anticipated value for
|
its previous response. The second number is its anticipated value for
|
||||||
the move it just made (with larger numbers meaning an ultimately better
|
the move it just made (with larger numbers meaning an ultimately better
|
||||||
board position for it), and the third number is the evaluation it
|
board position for it), and the third number is the evaluation it
|
||||||
assigns to the your current position (larger numbers meaning better
|
assigns to the your current position (larger numbers meaning better
|
||||||
positions for you). A ">" indicates that you are not in check; for
|
positions for you). A ">" indicates that you are not in check; for
|
||||||
check it is changed to "!".
|
check it is changed to "!".
|
||||||
|
|
||||||
There are a few limitations on play:
|
There are a few limitations on play:
|
||||||
|
|
||||||
o castling can only be done on the king's side;
|
- castling can only be done on the king's side.
|
||||||
o prohibitions against castling out of or through check are
|
- prohibitions against castling out of or through check are not enforced.
|
||||||
not enforced;
|
- prohibitions against castling if the king or rook have moved are not enforced.
|
||||||
o prohibitions against castling if the king or rook have moved
|
- pawns are always promoted to queens.
|
||||||
are not enforced;
|
- en passant is not allowed.
|
||||||
o pawns are always promoted to queens;
|
- the board-position-repeated-three-times and fifty-moves stalemates are not
|
||||||
o en passant is not allowed;
|
recognized.
|
||||||
o the board-position-repeated-three-times and fifty-moves
|
|
||||||
stalemates are not recognized;
|
|
||||||
|
|
||||||
If you checkmate the computer it prints "Rats!" and exits. If your own
|
If you checkmate the computer it prints "Rats!" and exits. If your own
|
||||||
checkmate is imminent it prints "Har har." but doesn't exit so it can
|
checkmate is imminent it prints "Har har." but doesn't exit so it can
|
||||||
rub your nose in defeat (which may be a move or two away if you're
|
rub your nose in defeat (which may be a move or two away if you're
|
||||||
playing at a high "ply" - see the next paragraph). Stalemates are not
|
playing at a high "ply" - see the next paragraph). Stalemates are not
|
||||||
recognized per se, but when selecting its move the program assigns a
|
recognized per se, but when selecting its move the program assigns a
|
||||||
stalemate position a value of 0 so it will try for a stalemate if its
|
stalemate position a value of 0 so it will try for a stalemate if its
|
||||||
other options are worse.
|
other options are worse.
|
||||||
|
|
||||||
The program takes one optional argument indicating the ply (lookahead)
|
The program takes one optional argument indicating the ply (lookahead)
|
||||||
it should use. The default is 2, which is enough to keep it from
|
it should use. The default is 2, which is enough to keep it from
|
||||||
making flaming blunders. The higher the ply, the better the play, and
|
making flaming blunders. The higher the ply, the better the play, and
|
||||||
the longer you have to wait. For example, at a ply of 2, a response to
|
the longer you have to wait. For example, at a ply of 2, a response to
|
||||||
the PK4 opening takes about 1.8 CPU seconds on a SPARC ELC when
|
the PK4 opening takes about 1.8 CPU seconds on a SPARC ELC when
|
||||||
compiled -O with Sun cc. A ply of 3 takes 13 CPU seconds (and results
|
compiled -O with Sun cc. A ply of 3 takes 13 CPU seconds (and results
|
||||||
in a different response to PK4) and a ply of 4 takes a little under 4
|
in a different response to PK4) and a ply of 4 takes a little under 4
|
||||||
CPU minutes (and for PK4 comes up with the same response as a ply of
|
CPU minutes (and for PK4 comes up with the same response as a ply of
|
||||||
3). A ply of 3 is in general good enough to avoid not only flaming
|
3). A ply of 3 is in general good enough to avoid not only flaming
|
||||||
blunders but also immediately stupid moves altogether. A ply of 4
|
blunders but also immediately stupid moves altogether. A ply of 4
|
||||||
will find all mate-in-two's.
|
will find all mate-in-two's.
|
||||||
|
|
||||||
|
|
||||||
|
### Obfuscation
|
||||||
|
|
||||||
This program is obfuscated in a number of ways. First, it abuses the
|
This program is obfuscated in a number of ways. First, it abuses the
|
||||||
contest rule regarding ';', '{', and '}' in the source not counting
|
contest rule regarding ';', '{', and '}' in the source not counting
|
||||||
against the non-whitespace character limit if followed by whitespace.
|
against the non-whitespace character limit if followed by whitespace.
|
||||||
As can be seen from the build file, certain combinations of these
|
As can be seen from the build file, certain combinations of these
|
||||||
characters followed by a particular whitespace character are expanded
|
characters followed by a particular whitespace character are expanded
|
||||||
at build time into much-needed text. Without this hack the program
|
at build time into much-needed text. Without this hack the program
|
||||||
wouldn't pass the character limit. A nice side effect is that the
|
wouldn't pass the character limit. A nice side effect is that the
|
||||||
initial source is gloriously difficult to peruse.
|
initial source is gloriously difficult to peruse.
|
||||||
|
|
||||||
Second, the rather ho-hum step has been taking of naming each variable
|
Second, the rather ho-hum step has been taking of naming each variable
|
||||||
with a one or two letter identifier to render it meaningless (and save
|
with a one or two letter identifier to render it meaningless (and save
|
||||||
space). This tactic is rather effective in a complex program.
|
space). This tactic is rather effective in a complex program.
|
||||||
|
|
||||||
Third, the board is represented not as an array of pieces but rather as
|
Third, the board is represented not as an array of pieces but rather as
|
||||||
an array of function pointers (with a separate array representing
|
an array of function pointers (with a separate array representing
|
||||||
whether a piece is white or black). This obfuscates the program's
|
whether a piece is white or black). This obfuscates the program's
|
||||||
central data structure. There is one function per type of piece; when
|
central data structure. There is one function per type of piece; when
|
||||||
called they return 1 if the current move is illegal for that piece and
|
called they return 1 if the current move is illegal for that piece and
|
||||||
0 if it is legal. The functions also as a side effect set a global
|
0 if it is legal. The functions also as a side effect set a global
|
||||||
indicating the type of the piece (though the type can also be determined
|
indicating the type of the piece (though the type can also be determined
|
||||||
by comparing the function pointer with the function itself).
|
by comparing the function pointer with the function itself).
|
||||||
|
|
||||||
Fourth, there are no independent routines for generating potential
|
Fourth, there are no independent routines for generating potential
|
||||||
moves. Instead, the program generates its moves by brute force: for
|
moves. Instead, the program generates its moves by brute force: for
|
||||||
every piece it controls on the board, it attempts to move it to every
|
every piece it controls on the board, it attempts to move it to every
|
||||||
square on the board. Those moves that are legal it then explores to
|
square on the board. Those moves that are legal it then explores to
|
||||||
see their effects (using alpha-beta search). This tactic somewhat
|
see their effects (using alpha-beta search). This tactic somewhat
|
||||||
obfuscates the algorithm used by the program.
|
obfuscates the algorithm used by the program.
|
||||||
|
|
||||||
Finally, there are three key constants that occur throughout the
|
Finally, there are three key constants that occur throughout the
|
||||||
program: 64, 8, and 3 (lg 8). Rather than making these available at
|
program: 64, 8, and 3 (lg 8). Rather than making these available at
|
||||||
compile-time, which provides a hint as to what the program is up to,
|
compile-time, which provides a hint as to what the program is up to,
|
||||||
they are computed probabilistically at run-time. An instance of the
|
they are computed probabilistically at run-time. An instance of the
|
||||||
"Inspection Paradox" is used which happens to produce a value that on
|
"Inspection Paradox" is used which happens to produce a value that on
|
||||||
average is close to .64. 10000 instances of this value are computed,
|
average is close to .64. 10000 instances of this value are computed,
|
||||||
added up, and then divided by 100. Sometimes the value produced will
|
added up, and then divided by 100. Sometimes the value produced will
|
||||||
be 63 or 65 instead of 64 (but I've never observed any other values),
|
be 63 or 65 instead of 64 (but I've never observed any other values),
|
||||||
so the result is then rounded to the nearest multiple of 4, and then
|
so the result is then rounded to the nearest multiple of 4, and then
|
||||||
the other constants are derived from it.
|
the other constants are derived from it.
|
||||||
|
|
||||||
## Copyright and CC BY-SA 4.0 License:
|
## Copyright and CC BY-SA 4.0 License:
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user