fix Makefile and README.md for 2001/dgbeards

This commit is contained in:
Landon Curt Noll committed 2023-03-17 15:04:17 -07:00
1 parent 5ec473f7e9
commit 7621291e2f
2 files changed
+422 -321

No files matched your search

+262 -169
View File
@@ -1,18 +1,9 @@
#!/usr/bin/env make
#
# IOCCC 2001 entry Makefile
# IOCCC 2001 winning entry - dgbeards
################################################################################
#
# An Historical Makefile NOTE:
#
# The orig.Makefile, if it exits, is the original Makefile before this IOCCC
# year directory was reworked so that entries are in separate directories.
# This also applies to any orig.ansi.mk and orig.common.mk files.
#
# Several Makefiles were modified / formed in 2022, and as such it may have
# elements that are not historically compatible with way entries were built.
#
# Regarding individual entries:
#
# IOCCC winning entry code may not work on your system. Even with standards,
@@ -45,192 +36,294 @@
# See: http://creativecommons.org/licenses/by-sa/3.0/
SHELL= /bin/sh
CAT= cat
RM= rm
SED= sed
TRUE= true
#CINCLUDE= -I ${HOMEBREW_PREFIX}/include/SDL2
# optimization
#############################
# shell used by this Makefile
#############################
#
# Most compiles will safely use -O2. Some can use only -O.
# A few compilers have broken optimizers and thus you may
# not want anything.
SHELL= bash
#######################
# common tool locations
#######################
#
include ../../var.mk
# Set X11_LIBDIR to the directory where the X11 library resides
#
#X11_LIBDIR= /usr/X11R6/lib
#X11_LIBDIR= /usr/X11/lib
X11_LIBDIR= /opt/X11/lib
# Set X11_INCLUDEDIR to the directory where the X11 include files reside
#
#X11_INCDIR= /usr/X11R6/include
#X11_INCDIR= /usr/X11/include
X11_INCDIR= /opt/X11/include
# Common C compiler warnings to silence
#
#CSILENCE=
CSILENCE= -Wno-char-subscripts -Wno-error -Wno-implicit-function-declaration \
-Wno-format-security -Wno-implicit-int -Wno-return-type
# Common C compiler warning flags
#
#CWARN= ${CSILENCE}
#CWARN= -Wall ${CSILENCE}
#CWARN= -Wall -Wextra ${CSILENCE}
CWARN= -Wall -Wextra -pedantic ${CSILENCE}
# Compiler standard
#
#CSTD=
#CSTD= -ansi
CSTD= -std=gnu99
# Compiler bit architecture
#
# Some entries require 32-bitness:
# ARCH= -m32
#
# Some entries require 64-bitness:
# ARCH= -m64
#
# By default we assume nothing:
#
ARCH=
# Defines that are needed to compile
#
#CDEFINE=
CDEFINE= -DE=break -DF=char -DK=case -DP=int -DR=return -DI=0xFFF
# Include files that are needed to compile
#
CINCLUDE=
#CINCLUDE= -include stdlib.h
#CINCLUDE= -include stdio.h
#CINCLUDE= -include stdlib.h -include stdio.h
#CINCLUDE= -I ${X11_INCDIR} -I ${X11_INCDIR}/X11
#CINCLUDE= `${SDL2_CONFIG} --cflags`
# Optimization
#
# Most compiles will safely use -O2. Some can use only -O1 or -O.
# A few compilers have broken optimizers or this entry make break
# under those buggy optimizers and thus you may not want anything.
# Reasonable compilers will allow for -O3.
#
#OPT=
#OPT= -O
OPT= -O2
#OPT= -O1
#OPT= -O2
OPT= -O3
# flags for ANSI compiles
# Default flags for ANSI C compilation
#
# NOTE: Some ANSI compilers make use of -Xa to turn on ANSI mode,
# others such as gcc may want -ansi, others (Compaq Tru64 Unix)
# want -std1, and others may want nothing at all.
# Adjust the CFLAGS line as needed.
#
# NOTE: Some compilers cannot optimize, or optimize some entries
# incorrectly. You might want to turn on -O to see if your
# compiler can handle them.
#
#
#CFLAGS= -Xa ${OPT}
#CFLAGS= -std1 $(OPT)
CFLAGS= -ansi ${OPT}
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${OPT}
# NOTE: On some systems, the library path does not include the location
# of the X11 libraries. You might need to use a -L/path/to/X11/lib/dir
# in order to compile with these libs.
# Libraries needed to build
#
X11CCFLAGS= -I/usr/X11R6/include -I/usr/X11R6/include/X11 -I/usr/include/X11
#X11CCFLAGS=
X11LDFLAGS= -L/usr/X11R6/lib -Wl,-R/usr/X11R6/lib
#X11LDFLAGS=
LIBS=
#LIBS= -lm
#LIBS= -L ${X11_LIBDIR} -lX11
#LIBS= `${SDL2_CONFIG} --libs`
# ANSI compiler
#
# Set CC to the name of your ANSI compiler.
#
# Some entries seem to need gcc. If you have gcc, set
# both CC and MAY_NEED_GCC to gcc.
#
# If you do not have gcc, set CC to the name of your ANSI compiler, and
# set MAY_NEED_GCC to either ${CC} (and hope for the best) or to just :
# to disable such programs.
# C compiler to use
#
CC= cc
MAY_NEED_GCC= gcc
#CC=clang
#CC=gcc
# winners that compile under ANSI C
# Compiler add-ons or replacements for clang only
#
WINNERS= anonymous bellard bellard.otccex cheong coupard \
ctk dgbeards herrmann1 herrmann2 jason kev ollinger rosten \
schweikh westley williams
ALT_NAMES= westley.orig
DATA_FILES= anonymous_files bellard_files herrmann1_files herrmann2_files
all: ${WINNERS}
# Most likely to amaze
ifeq ($(CC),clang)
#
anonymous: anonymous.c
magic='${MAY_NEED_GCC} -O1'; \
X='-DA(X)=#X'; \
warning='-pedantic -Dprocessor'; \
$$magic $$warning -Dmagic= $$X "-DX=A($$magic \"$$X\")" \
-o anonymous anonymous.c
anonymous_files: anonymous.ten.c
# Best abuse of the rules
CSILENCE+= -Wno-comma -Wno-conditional-uninitialized -Wno-format-nonliteral \
-Wno-implicit-int-conversion -Wno-missing-prototypes \
-Wno-missing-variable-declarations -Wno-poison-system-directories \
-Wno-shadow -Wno-strict-prototypes
#
bellard: bellard.c
${CC} -rdynamic ${CFLAGS} bellard.c -o bellard -ldl
bellard_files: bellard.otccex.c
# Best short program
CWARN+= -Weverything
#
cheong: cheong.c
${CC} ${CFLAGS} cheong.c -o cheong
endif
# Most obfuscated sound
# Specific add-ons or replacements for gcc only
#
coupard: coupard.c
${CC} ${CFLAGS} -o coupard coupard.c
# Worst Driver
ifeq ($(CC),gcc)
#
ctk: ctk.c
${CC} ${CFLAGS} -o ctk ctk.c
# Worst AI
#CSILENCE+=
#
dgbeards: dgbeards.c
${CC} ${CFLAGS} -DE=break -DF=char -DK=case -DP=int -DR=return \
-DI=0xFFFF dgbeards.c -o dgbeards
# Best abuse of the C preprocessor
#CWARN+=
#
herrmann1: herrmann1.c herrmann1.sh
@echo "NOTE: $@ must be built/run using the script $@.sh"
${SHELL} ./herrmann1.sh
endif
herrmann1_files: herrmann1.gcd herrmann1.sh herrmann1.times2
# Most eye-crossing
##############################
# Special flags for this entry
##############################
#
# This entry requires the GCC -include feature.
ENTRY= dgbeards
PROG= ${ENTRY}
#
herrmann2: herrmann2.c
${MAY_NEED_GCC} ${CFLAGS} herrmann2.c -o herrmann2 \
-include /usr/include/stdlib.h -include /usr/include/stdio.h \
-include /usr/include/time.h -include /usr/include/unistd.h
herrmann2_files: herrmann2.cup herrmann2.ioccc
# Best Of Show
OBJ= ${PROG}.o
DATA=
TARGET= ${PROG}
#
jason: jason.c
${CC} ${CFLAGS} -o jason jason.c
ALT_OBJ=
ALT_TARGET=
# Best Curses Game
#################
# build the entry
#################
#
kev: kev.c
${CC} ${CFLAGS} -DPORT=5455 -DSPEED=50 -o kev kev.c \
-lcurses -ltermcap \
-Dl_="socket(il.sin_family=AF_INET,SOCK_STREAM,0)"
# Best primal ASCII graphics
#
ollinger: ollinger.c
${CC} ${CFLAGS} ollinger.c -o ollinger
# Best abuse of the user
#
rosten: rosten.c
${CC} ${CFLAGS} rosten.c ${X11CCFLAGS} ${X11LDFLAGS} -pedantic -lX11 \
-o rosten
# Best one-liner
#
schweikh: schweikh.c
${CC} ${CFLAGS} schweikh.c -o schweikh
# Best position-independant code
#
westley: westley.c
${CC} ${CFLAGS} westley.c -o westley
westley.orig: westley.orig.c
${CC} ${CFLAGS} westley.orig.c -o westley.orig
# Best position-independant code
#
williams: williams.c
${CC} williams.c ${X11CCFLAGS} ${X11LDFLAGS} -lX11 -o williams
everything: ${WINNERS} ${ALT_NAMES} ${DATA_FILES}
love:
@echo 'not war?'
haste:
${MAKE} waste
waste:
@echo 'waste'
clean:
${RM} -f *.o a.out core ${WINNERS}
clobber: clean
${RM} -f ${WINNERS}
${RM} -f ${ALT_NAMES}
nuke: clobber
all: data ${TARGET}
@${TRUE}
install: all
${CAT} ${WINNERS} ${ALT_NAMES} > /dev/null
.PHONY: all alt data everything clean clobber install \
love haste waste maker easter_egg sandwich \
supernova deep_magic magic charon pluto
${PROG}: ${PROG}.c
${CC} ${CFLAGS} $< -o $@ ${LIBS}
# alternative executable
#
alt: data ${ALT_TARGET}
@${TRUE}
# data files
#
data: ${DATA}
@${TRUE}
# both all and alt
#
everything: all alt
###############
# utility rules
###############
#
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
@-if [ -f indent.c ]; then \
echo ${RM} -f indent.c; \
${RM} -f indent.c; \
fi
clobber: clean
${RM} -f ${TARGET} ${ALT_TARGET}
@-if [ -e sandwich ]; then \
${RM} -f sandwich; \
echo 'ate sandwich'; \
fi
install:
@echo "Dr. Spock says that is not logical!"
@${TRUE}
# you may be able to misunderstand the source by reading indent.c
#
indent.c: ${PROG}.c
@if which "${GINDENT}" >/dev/null 2>&1; then \
echo ${RM} -f $@; \
${RM} -f $@; \
echo "${GINDENT} < $< > $@"; \
${GINDENT} < $< > $@; \
elif which "${INDENT}" >/dev/null 2>&1; then \
echo ${RM} -f $@; \
${RM} -f $@; \
echo "${INDENT} < $< > $@"; \
${INDENT} < $< > $@; \
else \
echo "no intent tool found, ident $< yourself, sorry"; \
echo "exit 1"; \
exit 1; \
fi
##################
# 133t hacker rulz
##################
#
love:
@echo 'not war?'
@${TRUE}
haste:
$(MAKE) waste
@${TRUE}
waste:
@echo 'haste'
@${TRUE}
maker:
@echo 'Participate in a maker faire'
@${TRUE}
easter_egg:
@echo "you expected to often misunderstand this $${RANDOM} magic"
@echo "chongo '<was here>' /\\oo/\\"
@echo "Eggy"
sandwich: easter_egg
@if [ `id -u` -eq 0 ]; then \
echo 'Okay.'; \
echo "$${RANDOM}`date +%s`$${RANDOM}" > $@; \
else \
echo 'What? Make it yourself.'; \
exit 1; \
fi
# Understand the history of the Homebrew Computer Club
# as well as the West Coast Computer Faire and
# you might be confused different. :-)
#
supernova: sandwich
@-if [ -r .code_anal ]; then \
${RM} -f .code_anal_v6; \
else \
echo "planet deniers, like some members of the IAU, are so cute when they try to defend their logic"; \
fi
@echo "A $@ helps ${MAKE} the elements that help form planets"
@${TRUE}
deep_magic: supernova
@-if [ -r .code_anal ]; then \
ccode_analysis --deep_magic 7889066cdbdf09b0408021754586e895be641cc9be29e7eafd3ca65359541f17 \
--FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \
else \
echo "Wrong! Do it again!"; \
sleep 2; \
echo "Wrong! Do it again!"; \
sleep 2; \
echo "Wrong! Do it again!"; \
fi
@${TRUE}
magic: deep_magic
@-if [ -r .code_anal ]; then \
ccode_analysis --level 20003 --mode 5717175 --FNV1a_hash_512_bit -v2 "${PROG}" "${PROG}.c"; \
else \
echo "If you don't eat yer meat, you can't have any pudding!"; \
echo "How can you have any pudding if you don't eat yer meat?!"; \
fi
@${TRUE}
# The IOCCC resident astronomer states
#
charon: magic
@echo "$@ is a dwarf planet"
@echo "dwarf is a type of planet"
@echo "therefore IAU, $@ is a planet"
pluto: charon
${MAKE} charon
@echo "$@ is a dwarf planet"
@echo "dwarf is a type of planet"
@echo "therefore, $@ is a planet"
@echo "having lots of planets is good feature because supernovae can help ${MAKE} a lot of them"
+160 -152
View File
@@ -1,4 +1,4 @@
Best AI:
# Best AI:
Doug Beardsley
Southern Adventist University
@@ -6,207 +6,215 @@ Best AI:
Cleveland, TN 37312
USA
# To build:
Judge's Remarks:
```sh
make
```
To build:
### To run:
make dgbeards
```sh
./dgbeards
```
Try:
### Try:
./dgbeards
```sh
echo "Do or do not. There is no try."
```
This is probably the worst AI we've ever seen. So, then, why did
the entry win? Because it's *trying* to lose.
## Judges' comments:
This is also one of the first chess games we've seen.
This is probably the worst AI we've ever seen. So, then, why did
the entry win? Because it's *trying* to lose.
Of particular interest is the author's decision that the program should
crash if it loses. I've played chess with a lot of people like that, and
I appreciate the realism.
This is also one of the first chess games we've seen.
Of particular interest is the author's decision that the program should
crash if it loses. I've played chess with a lot of people like that, and
I appreciate the realism.
Selected Author's Comments:
## Author's comments:
FAQ:
FAQ:
Q: What does this program do?
Q: What does this program do?
A: It lets the user play two player or single player games of suicide
chess. Suicide Chess (also known as Losing Chess) is a variant of normal
chess. It is played on the same board and uses the same pieces. Here is
a list of the differences:
A: It lets the user play two player or single player games of suicide
chess. Suicide Chess (also known as Losing Chess) is a variant of normal
chess. It is played on the same board and uses the same pieces. Here is
a list of the differences:
1. The object of the game is to get to a position where you have no legal
moves. This is usually accomplished by losing all of your pieces.
Sometimes, the game can end when you still have some pawns on the board,
but they are blocked and cannot move. The general rule is if a player
has no legal moves, the game is over. The winner is the player with fewer
pieces on the board. This is almost always the same player that had no
moves, but not always.
1. The object of the game is to get to a position where you have no legal
moves. This is usually accomplished by losing all of your pieces.
Sometimes, the game can end when you still have some pawns on the board,
but they are blocked and cannot move. The general rule is if a player
has no legal moves, the game is over. The winner is the player with fewer
pieces on the board. This is almost always the same player that had no
moves, but not always.
2. In suicide chess, piece captures are compulsory. If a player can
capture an opponent's piece, he is required to do so. If he can capture
more than one of the opponent's pieces or can capture one piece with more
than one of his own pieces, he can choose which capture to play.
2. In suicide chess, piece captures are compulsory. If a player can
capture an opponent's piece, he is required to do so. If he can capture
more than one of the opponent's pieces or can capture one piece with more
than one of his own pieces, he can choose which capture to play.
3. The king is not significant. There is no concept of check and the king
can be captured.
3. The king is not significant. There is no concept of check and the king
can be captured.
4. Because of rule 3, pawns are allowed to promote to a king.
4. Because of rule 3, pawns are allowed to promote to a king.
5. Castling is not allowed.
5. Castling is not allowed.
Q: How do you use this program?
Q: How do you use this program?
A: The program is fairly straightforward. When you start the program,
it displays the opening position for a game of suicide chess and waits
for user input. Commands are as follows:
A: The program is fairly straightforward. When you start the program,
it displays the opening position for a game of suicide chess and waits
for user input. Commands are as follows:
quit - Quits the program
g - Causes the computer to make a move
quit - Quits the program
g - Causes the computer to make a move
Moves are represented by the long algebraic notation for the move. For
those not familiar with long algebraic notation, a move consists of a
square to move from followed by a square to move to. Squares are denoted
by a letter and a number. The letter specifies the column or file of the
square and the number specifies the row rank. Files are named from left
to right by the letters a-h. Rows are numbered from bottom to top with
the numbers 1-8. A sample move from the opening position is e2e3. This
means to move a piece from square e2 to e3. From the opening position,
this corresponds to moving the king pawn forward one square. This is
generally to be considered one of the best opening moves in suicide
chess. All moves, captures and otherwise, are represented with this
notation. A special case is pawn promotion moves. They use the same
notation followed by an '=' and a letter representing the piece to
promote to. The letters are R,N,B,Q,K representing rook, knight, bishop,
queen, and king respectively. The letters must be upper case.
Moves are represented by the long algebraic notation for the move. For
those not familiar with long algebraic notation, a move consists of a
square to move from followed by a square to move to. Squares are denoted
by a letter and a number. The letter specifies the column or file of the
square and the number specifies the row rank. Files are named from left
to right by the letters a-h. Rows are numbered from bottom to top with
the numbers 1-8. A sample move from the opening position is e2e3. This
means to move a piece from square e2 to e3. From the opening position,
this corresponds to moving the king pawn forward one square. This is
generally to be considered one of the best opening moves in suicide
chess. All moves, captures and otherwise, are represented with this
notation. A special case is pawn promotion moves. They use the same
notation followed by an '=' and a letter representing the piece to
promote to. The letters are R,N,B,Q,K representing rook, knight, bishop,
queen, and king respectively. The letters must be upper case.
You can also specify a command line argument of a single digit to change
the search depth of the program. If no argument is specified, it
defaults to a depth of 3.
You can also specify a command line argument of a single digit to change
the search depth of the program. If no argument is specified, it
defaults to a depth of 3.
Q: Are there any limitations in your program?
Q: Are there any limitations in your program?
A: Yes. The first of the limitations is that you can only play legal
moves according to the rules of suicide chess. En passant captures are
not recognized. They are rarely encountered in suicide chess and when
they do happen, they usually do not change the outcome of the game. As
mentioned above, castling is not allowed either.
A: Yes. The first of the limitations is that you can only play legal
moves according to the rules of suicide chess. En passant captures are
not recognized. They are rarely encountered in suicide chess and when
they do happen, they usually do not change the outcome of the game. As
mentioned above, castling is not allowed either.
It also does not detect the end of the game. It can see sure wins or
losses several moves ahead, but does not announce the end of a game or
the winner. Given the existing code it is easy to do this, but it was
deemed unnecessary fluff.
It also does not detect the end of the game. It can see sure wins or
losses several moves ahead, but does not announce the end of a game or
the winner. Given the existing code it is easy to do this, but it was
deemed unnecessary fluff.
Q: What is the playing strength of this program?
Q: What is the playing strength of this program?
A: Playing strength is a relative term. Relative to other computer
programs that play suicide chess, it is about the bottom. There is one
freeware program in existence called kenny that this program can beat,
but that is about it.
A: Playing strength is a relative term. Relative to other computer
programs that play suicide chess, it is about the bottom. There is one
freeware program in existence called kenny that this program can beat,
but that is about it.
Suicide chess is a very tactical game. Most humans who do not have any
experience in suicide chess will lose to this program. The Free Internet
Chess Server (http://www.freechess.org) is a free online chess server
that supports suicide chess. This server keeps track of ratings. The
human ratings for suicide chess range from 1000 to about 2400. This
program would probably be rated somewhere around 1700-1900. It is better
than most players, but will get destroyed by experienced human opponents.
Suicide chess is a very tactical game. Most humans who do not have any
experience in suicide chess will lose to this program. The Free Internet
Chess Server (http://www.freechess.org) is a free online chess server
that supports suicide chess. This server keeps track of ratings. The
human ratings for suicide chess range from 1000 to about 2400. This
program would probably be rated somewhere around 1700-1900. It is better
than most players, but will get destroyed by experienced human opponents.
This program searches to a fixed depth of 3 ply. Because it does not
search very deep, it performs very poorly in quiet strategic positions.
In such positions, it will often just shuffle pieces around aimlessly
until a tactical exchange presents itself.
This program searches to a fixed depth of 3 ply. Because it does not
search very deep, it performs very poorly in quiet strategic positions.
In such positions, it will often just shuffle pieces around aimlessly
until a tactical exchange presents itself.
A small amount of randomness has been added to make the program a more
interesting opponent. The to avoid a call to srand(), rand() and the
extra code for the required include files, the time() function is used as
the source of random data. It is a slow function, and since it is
executed inside the search loop, there is a significant performance
decrease. To make it faster, replace the time() call with rand() and add
the line srand(time(0)); to the beginning of main(). I used the more
inefficient time() function to illustrate a different (and somewhat
obfuscated?) way of generating random numbers.
A small amount of randomness has been added to make the program a more
interesting opponent. The to avoid a call to srand(), rand() and the
extra code for the required include files, the time() function is used as
the source of random data. It is a slow function, and since it is
executed inside the search loop, there is a significant performance
decrease. To make it faster, replace the time() call with rand() and add
the line srand(time(0)); to the beginning of main(). I used the more
inefficient time() function to illustrate a different (and somewhat
obfuscated?) way of generating random numbers.
Q: Why is this program obfuscated?
Q: Why is this program obfuscated?
A: Here are several reasons:
A: Here are several reasons:
First, without preprocessing, the code is not easy to read. The
preprocessor is used to compress the code and obfuscate it. The main
obstacle to entering this program is the source code size limit. This is
the reason that the preprocessor was used so liberally. It is one of the
best ways to compress C source code.
First, without preprocessing, the code is not easy to read. The
preprocessor is used to compress the code and obfuscate it. The main
obstacle to entering this program is the source code size limit. This is
the reason that the preprocessor was used so liberally. It is one of the
best ways to compress C source code.
Second, when possible, variables in the program were made global. Their
names are not descriptive and they are used for a variety of purposes
throughout the program. Because of this, it is difficult to determine
exactly what the code does even after preprocessing and beautifying the
code.
Second, when possible, variables in the program were made global. Their
names are not descriptive and they are used for a variety of purposes
throughout the program. Because of this, it is difficult to determine
exactly what the code does even after preprocessing and beautifying the
code.
Third, all function names are a single character and are obviously not
descriptive of they're actual purpose. Again this serves the dual
purpose of compression and obfuscation.
Third, all function names are a single character and are obviously not
descriptive of they're actual purpose. Again this serves the dual
purpose of compression and obfuscation.
Fourth, most string variables have been encoded. This encoding serves
to obfuscate the program as well as reduce the number of countable
characters and get the program under the size limit of this year's IOCCC.
There are some places where other simple encoding methods are used to
hide the real purpose of strings. These layers of obscurity cannot be
penetrated by just preprocessing and beautifying the program.
Fourth, most string variables have been encoded. This encoding serves
to obfuscate the program as well as reduce the number of countable
characters and get the program under the size limit of this year's IOCCC.
There are some places where other simple encoding methods are used to
hide the real purpose of strings. These layers of obscurity cannot be
penetrated by just preprocessing and beautifying the program.
Fifth, various small obfuscations have been used in places all over the
program. Short circuit evaluation is used as a substitute for if()
statements in some places. The ternary operator is used. In the
author's opinion, use of the ternary operator is almost always a strong
argument for employee turnover.
Fifth, various small obfuscations have been used in places all over the
program. Short circuit evaluation is used as a substitute for if()
statements in some places. The ternary operator is used. In the
author's opinion, use of the ternary operator is almost always a strong
argument for employee turnover.
Last, if you have succeeded in wading through the previous layers of
obfuscation, you are confronted by the fact that the game that it
implements is an obscure game. Casual inspection of the program might
lead one to believe that it is an implementation of classic chess, but
this is not so.
Last, if you have succeeded in wading through the previous layers of
obfuscation, you are confronted by the fact that the game that it
implements is an obscure game. Casual inspection of the program might
lead one to believe that it is an implementation of classic chess, but
this is not so.
Q: What about the compiler warnings?
Q: What about the compiler warnings?
A: When compiled with gcc -Wall, the compiler generated the following
warnings:
A: When compiled with gcc -Wall, the compiler generated the following
warnings:
suggest parentheses around + or - in operand of &
array subscript has type 'char'
return type defaults to 'int'
control reaches end of non-void function
value computed is not used
suggest parentheses around + or - in operand of &
array subscript has type 'char'
return type defaults to 'int'
control reaches end of non-void function
value computed is not used
The "value computed is not used" warning happens because I use the &&
operator and take advantage of short circuit evaluation instead of using
an if() statement.
The "value computed is not used" warning happens because I use the &&
operator and take advantage of short circuit evaluation instead of using
an if() statement.
The "suggest parentheses..." warnings are given because of expressions
that depend on operator precedence details in the C language.
Eliminating these warnings would reduce obfuscation.
The "suggest parentheses..." warnings are given because of expressions
that depend on operator precedence details in the C language.
Eliminating these warnings would reduce obfuscation.
The other warnings are there because it would require more code to
eliminate them and that can't be done given the size limit.
The other warnings are there because it would require more code to
eliminate them and that can't be done given the size limit.
Q: Why does this program crash when it loses?
Q: Why does this program crash when it loses?
A: What better way to admit defeat? The author thought this was
appropriate sportsmanship for a program of this genre and can think of
no worse job than trying to find an elusive bug in an intentionally
obfuscated program.
A: What better way to admit defeat? The author thought this was
appropriate sportsmanship for a program of this genre and can think of
no worse job than trying to find an elusive bug in an intentionally
obfuscated program.
[judge's note: This was followed by a description of the bug, and
the comment:]
[judge's note: This was followed by a description of the bug, and
the comment:]
(Note, if this program wins, the author thinks it would be good to leave
this information out of the remarks and encourage others to try and
figure it out for themselves)
(Note, if this program wins, the author thinks it would be good to leave
this information out of the remarks and encourage others to try and
figure it out for themselves)
[should you be too lazy to figure it out yourself, here's the author's
fix. I would have rot13'd it, but the punctuation would have survived.]
[should you be too lazy to figure it out yourself, here's the author's
fix. I would have rot13'd it, but the punctuation would have survived.]
begin 644 fix.txt
M5&AI<R!B=6<@8V%N(&)E(&9I>&5D(&EN(&$@;G5M8F5R(&]F('=A>7,L(&)U