Merge pull request #1463 from xexyl/bellard2001
This commit is contained in:
15 files changed
+367
-106
No files matched your search
+12
-7
@@ -53,9 +53,10 @@ You can use it by typing:
|
||||
|
||||
or by giving the C source to its standard input.
|
||||
|
||||
`args` are given to the `main` function of `bellard.c` (`argv[0]` is
|
||||
`args` are given to the `main()` function of `bellard.c` (`argv[0]` is
|
||||
[bellard.c](bellard.c)).
|
||||
|
||||
|
||||
### Examples:
|
||||
|
||||
- Sample compilation and execution:
|
||||
@@ -80,21 +81,23 @@ An alternate syntax is to use it as a script interpreter: you can
|
||||
put `#!/usr/local/bin/otcc` at the beginning of your C source if
|
||||
you installed `otcc` at this place.
|
||||
|
||||
|
||||
### Supported C language subset (read joint example [bellard.otccex.c](bellard.otccex.c) to have an introduction to `OTCC` dialect)
|
||||
|
||||
|
||||
#### Expressions:
|
||||
|
||||
* binary operators, by decreasing priority order: `*` `/` `%`,
|
||||
* binary operators, in decreasing precedence order: `*` `/` `%`,
|
||||
`+` `-`, `>>` `<<`, `<` `<=` `>` `>=`, `==` `!=`, `&`,
|
||||
`^`, `|`, `=`, `&&`, `||`.
|
||||
|
||||
* `&&` and `||` have the same semantics as in C: left to right
|
||||
evaluation and early exit.
|
||||
evaluation and early exit (short-circuited).
|
||||
|
||||
* Parenthesis are supported.
|
||||
|
||||
* Unary operators: `&`, `*` (pointer indirection), `-`
|
||||
(negation), `+`, `!`, `~`, post fixed `++` and `--`.
|
||||
(negation), `+`, `!`, `~`, postfix `++` and `--`.
|
||||
|
||||
* Pointer indirection (`*`) only works with explicit cast to
|
||||
`char *`, `int *` or `int (*)()` (function pointer).
|
||||
@@ -118,7 +121,7 @@ you installed `otcc` at this place.
|
||||
uses the libc dynamic linker to resolve undefined symbols.
|
||||
|
||||
- Instructions: blocks (`{` `}`) are supported as in C. `if` and
|
||||
`else` can be used for tests. The `while` and `for` C looks are supported.
|
||||
`else` can be used for tests. The `while` and `for` C loops are supported.
|
||||
`break` can be used to exit loops. `return` is used for the return value of a
|
||||
function.
|
||||
|
||||
@@ -143,13 +146,15 @@ you installed `otcc` at this place.
|
||||
- Memory: the code, data, and symbol sizes are limited to 100KB
|
||||
(it can be changed in the source code).
|
||||
|
||||
|
||||
### Obfuscation:
|
||||
|
||||
No special effort was needed because obfuscation is almost
|
||||
unavoidable for such a program :-) Defines must be used to
|
||||
unavoidable for such a program :-) `#define`s must be used to
|
||||
compress the code, and integrated i386 code generator leads to non
|
||||
obvious code.
|
||||
|
||||
|
||||
### Portability:
|
||||
|
||||
`OTCC` only works on i386 linux because it generates i386 code. `OTCC`
|
||||
@@ -162,7 +167,7 @@ such support is currently integrated.
|
||||
It was successfully compiled with gcc version 2.95.2. You get some
|
||||
warnings because old K&R prototypes are used, some casts are implicit
|
||||
and some functions are used before being defined. `OTCC` uses the
|
||||
dynamic linker to resolve symbols with `dlsym()`, so `-ldl` must
|
||||
dynamic linker to resolve symbols with `dlsym(3)`, so `-ldl` must
|
||||
be used when you compile and link it.
|
||||
|
||||
|
||||
|
||||
@@ -15,9 +15,7 @@ make
|
||||
### Try:
|
||||
|
||||
```sh
|
||||
./cheong 1024
|
||||
./cheong 12345678901234567890
|
||||
./cheong 05305265226926441255040573044986873789
|
||||
./try.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -40,9 +38,9 @@ For example,
|
||||
|
||||
```sh
|
||||
$ cc -o cheong cheong.c
|
||||
$ cheong 1234567890
|
||||
$ ./cheong 1234567890
|
||||
35136
|
||||
$ cheong 0200000000000000000000000000
|
||||
$ ./cheong 0200000000000000000000000000
|
||||
14142135623730
|
||||
```
|
||||
|
||||
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# try.sh - demonstrate IOCCC winner 2001/cheong
|
||||
#
|
||||
|
||||
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||
# this way allows us to have the user specify a different compiler in an easy
|
||||
# way.
|
||||
if [[ -z "$CC" ]]; then
|
||||
CC="cc"
|
||||
fi
|
||||
|
||||
make CC="$CC" all >/dev/null || exit 1
|
||||
|
||||
# clear screen after compilation so that only the entry is shown
|
||||
clear
|
||||
|
||||
echo "$ ./cheong 1024" 1>&2
|
||||
./cheong 1024
|
||||
|
||||
echo "$ ./cheong 0512" 1>&2
|
||||
./cheong 0512
|
||||
|
||||
echo "$ ./cheong 12345678901234567890" 1>&2
|
||||
./cheong 12345678901234567890
|
||||
|
||||
echo "$ ./cheong 05305265226926441255040573044986873789" 1>&2
|
||||
./cheong 05305265226926441255040573044986873789
|
||||
|
||||
echo "$ ./cheong 1234567890" 1>&2
|
||||
./cheong 1234567890
|
||||
|
||||
echo "$ ./cheong 0200000000000000000000000000" 1>&2
|
||||
./cheong 0200000000000000000000000000
|
||||
|
||||
+17
-14
@@ -20,16 +20,13 @@ For more detailed information see [2001 herrmann1 in bugs.md](/bugs.md#2001-herr
|
||||
## To use:
|
||||
|
||||
```sh
|
||||
./herrmann1.sh 'prg=file'
|
||||
./herrmann1.sh 'prg=file'
|
||||
```
|
||||
|
||||
NOTE: this entry seems to rely on older versions of gcc for the compilation
|
||||
stage and as such if you wish to see that part like it was designed you will
|
||||
need an older compiler perhaps gcc 2.95.
|
||||
|
||||
NOTE: some files are missing and are not found in the archive either. See
|
||||
[bugs.md](/bugs.md) for more details.
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
@@ -56,7 +53,7 @@ on.
|
||||
## Author's remarks:
|
||||
|
||||
Many cool things have been done with the preprocessor,
|
||||
e.g. calculation of prime numbers or the tower of Hanoi. However,
|
||||
e.g. calculation of prime numbers or the Tower of Hanoi. However,
|
||||
up to now, no one proved that the preprocessor is Turing complete,
|
||||
and I wondered why. Well, the answer is simply that the
|
||||
preprocessor is _not_ Turing complete, at least not if the program
|
||||
@@ -86,8 +83,10 @@ example that you can solve NP hard problems in polynomial time!
|
||||
Turing machine running over the tape and doing its work in your
|
||||
terminal!
|
||||
|
||||
|
||||
### How to use it
|
||||
|
||||
|
||||
#### For the impatient
|
||||
|
||||
The info files `herrmann1.turing` and [herrmann1.gcd](herrmann1.gcd) are sample
|
||||
@@ -176,12 +175,12 @@ Some explanations:
|
||||
- The tape alphabet is always O and I.
|
||||
- The states can be anything starting with "st". "start" and
|
||||
"stop" are the start and stop states, respectively.
|
||||
- to define a state, use two lines: one for each letter on the
|
||||
- To define a state, use two lines: one for each letter on the
|
||||
tape. You may omit one of the lines if the Turing machine will
|
||||
never enter the state reading that letter. (In the example, the
|
||||
line defining st2_I has been left out.)
|
||||
line defining `st2_I` has been left out.)
|
||||
- The order of the lines is irrelevant.
|
||||
- You may use c-style comments. (Would you have guessed it?)
|
||||
- You may use C-style comments. (Would you have guessed it?)
|
||||
|
||||
Now, the program can be used with
|
||||
|
||||
@@ -191,8 +190,8 @@ Now, the program can be used with
|
||||
|
||||
But what happens if no tape is provided? Up to now, the Turing
|
||||
machine would start on an empty tape (that is, a tape filled with
|
||||
O's). For many programs, this doesn't make much sense (as is
|
||||
the case for "plus1.turing"). So you might want to provide a
|
||||
`O`s). For many programs, this doesn't make much sense (as is
|
||||
the case for `plus1.turing`). So you might want to provide a
|
||||
default tape by adding a line like
|
||||
|
||||
```c
|
||||
@@ -201,6 +200,7 @@ default tape by adding a line like
|
||||
|
||||
to your program.
|
||||
|
||||
|
||||
### Debugging
|
||||
|
||||
When writing long programs, the most common errors are to forget
|
||||
@@ -230,13 +230,14 @@ Tape:
|
||||
```
|
||||
|
||||
and the return code will be 1. As you can see, the Turing machine
|
||||
moved over the O's, but when it arrived at the `I` (still in state
|
||||
moved over the `O`s, but when it arrived at the `I` (still in state
|
||||
start), the error occurred.
|
||||
|
||||
Note that other kinds of errors can cause compilation to fail.
|
||||
If this happens, the build script will write the error message of
|
||||
gcc into a file called `error` and then exit.
|
||||
|
||||
|
||||
### What the build script does
|
||||
|
||||
In principle, the build script simply runs the preprocessor over
|
||||
@@ -264,7 +265,7 @@ with a `-D` before. I had a slight technical problem doing this
|
||||
(especially with the spaces that can appear within the tape
|
||||
argument). That made the build script a bit longer.
|
||||
|
||||
- It would be enough to pass the defines in the first
|
||||
- It would be enough to pass the `#define`s in the first
|
||||
preprocessing. The program then "remembers" them. However, it
|
||||
doesn't matter if they are passed in all pre-processes. (This
|
||||
doesn't sound very impressive, but it has required some extra
|
||||
@@ -280,6 +281,7 @@ directly, because the warnings would clobber the animation. I
|
||||
could have made the compile script output the error file in case
|
||||
of an error, but I didn't want to make it yet longer.)
|
||||
|
||||
|
||||
### Some technical details / obfuscations
|
||||
|
||||
- The program is compressed. In the first three preprocessing
|
||||
@@ -334,6 +336,7 @@ to use many variables more than once.
|
||||
"modern art of programming" - a mixture of program-like
|
||||
indenting and modern art. There are even some comments...
|
||||
|
||||
|
||||
### Compatibility
|
||||
|
||||
- It works with many versions of gcc. I tested it with versions
|
||||
@@ -349,12 +352,12 @@ inside comments (Well, _I_ like some well-placed `/*/*/`.) as
|
||||
well as some suggestions where to place some more parentheses
|
||||
(as if I didn't know the operator precedence).
|
||||
|
||||
- Different versions of cc all produced only rubbish. Apparently,
|
||||
- Different versions of `cc` all produced only rubbish. Apparently,
|
||||
the preprocessors didn't really work. (I don't feel guilty
|
||||
there, either. Even with very simple programs, they produced
|
||||
mysterious output.)
|
||||
|
||||
- For Mac-Users: It works with the C compiler of Codewarrior (an
|
||||
- For Mac-Users: It works with the C compiler of CodeWarrior (an
|
||||
old version). This compiler even leaves out all that unnecessary
|
||||
white space, so that no clean-up is needed. (It would be useful
|
||||
to write a kind of script which does the equivalent to the build
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#define tape O O O O O I I I I
|
||||
/* Search beginning of number. */
|
||||
#define start_O O, right, start
|
||||
/* Number found. Move one step to the left. */
|
||||
#define start_I I, left, st2
|
||||
/* Write a I and stop */
|
||||
#define st2_O I, left, stop
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
herrmann2
|
||||
herrmann2.orig
|
||||
prog.orig
|
||||
ioccc.out
|
||||
ioccc.out2
|
||||
cup.out
|
||||
cup.out2
|
||||
@@ -15,14 +15,9 @@ make
|
||||
### Try:
|
||||
|
||||
```sh
|
||||
./herrmann2 < herrmann2.ioccc
|
||||
./herrmann2 < herrmann2.cup
|
||||
./try.sh
|
||||
```
|
||||
|
||||
Try running each command a few times and notice the different output. Can you
|
||||
figure out why each is different?
|
||||
|
||||
|
||||
If you use vi(m) you can see a pattern in [herrmann2.cup](herrmann2.cup) and
|
||||
[herrmann2.ioccc][(herrmann2.ioccc]) by say:
|
||||
|
||||
@@ -51,34 +46,6 @@ and in [herrmann2.ioccc](herrmann2.ioccc) try:
|
||||
/n
|
||||
```
|
||||
|
||||
### Also try:
|
||||
|
||||
```sh
|
||||
./herrmann2 \
|
||||
'char*d,A[9876];e;b;*ad,a,c; tw,ndr,T; wri; ;*h; _,ar ;on;'\
|
||||
' ;l ;i(V)man,n {-!har ; =Aadre(0,&e,o||n -- +,o4,=9,l=b=8,'\
|
||||
'!( te-*Aim)|(0~l),srand (l),,!A,d=,b))&&+((A + te-A(&(*)=+ +95>'\
|
||||
'e?(*& c_*r=5,r+e-r +_:2-19<-+?|(d==d),!n ?*d| *( (char**)+V+), ('\
|
||||
' +0,*d-7 ) -r+8)c:7:+++7+! r: and%9- 85! ()-(r+o):(+w,_+ A*(=er'\
|
||||
'i+(o)+b)),!write,(=_((-b+*h)(1,A+b,!!((((-+, a >T^l,( o-95=+))w?'\
|
||||
'++ &&r:b<<2+a +w) ((!main(n*n,V) , +-) ),l)),w= +T-->o +o+;{ &!'\
|
||||
'a;}return _+= ' < herrmann2.ioccc > herrmann2.orig.c && \
|
||||
diff herrmann2.alt.c herrmann2.orig.c && echo "output matches with original code"
|
||||
```
|
||||
|
||||
|
||||
## Alternate code:
|
||||
|
||||
If you wish to use the original version that does not work for all platforms
|
||||
(and will not even compile with some versions of clang), you can make use of the
|
||||
[herrmann2.alt.c](herrmann2.alt.c) by running:
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
Use `herrmann2.alt` as you would `herrmann2` above.
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
@@ -90,8 +57,8 @@ if you concentrate on your focus you will find illumination!
|
||||
|
||||
You probably know those "magic eye" 3D pictures - pictures looking
|
||||
like random noise, but when you look "through" the paper, you
|
||||
either get a three dimensional picture or a head-ache. With this
|
||||
program, you can create your own 3D pictures in ascii art. And
|
||||
either get a three dimensional picture or a headache. With this
|
||||
program, you can create your own 3D pictures in ASCII art. And
|
||||
yes, the program itself is such a 3D picture.
|
||||
|
||||
|
||||
@@ -176,6 +143,7 @@ program length.
|
||||
big as possible, but small enough to be viewed without problems
|
||||
on normal-sized terminals.
|
||||
|
||||
|
||||
### Why this program should win
|
||||
|
||||
- The layout is of a completely new kind. And it describes what
|
||||
@@ -203,12 +171,12 @@ stuff doing mostly nothing.)
|
||||
obfuscated: It's (almost) only one big expression, with deep
|
||||
nesting of `()` and `?:`, and full of unnecessary operations which
|
||||
do not really help making it readable. And it contains a lot of
|
||||
"magic numbers". (My favourite is the "7" in line 15 (each
|
||||
"magic numbers". (My favourite is the `7` in line 15 (each
|
||||
one). Which is the other digit I could have put there instead,
|
||||
and what other changes to the program would have been necessary?
|
||||
Without violating the constraints of course.)
|
||||
|
||||
- The fact that the main loop of the program calls `main`
|
||||
- The fact that the main loop of the program calls `main()`
|
||||
recursively is nothing new. New however is that this program
|
||||
only needs a logarithmic recursion depth! (Find out how this
|
||||
works.)
|
||||
@@ -225,7 +193,7 @@ and let the result inspire you. ;-)
|
||||
|
||||
- I fear that gcc is the only compiler for which this program
|
||||
works. Due to the severe restrictions, I was forced to use
|
||||
declarations of int variables, functions and parameters without
|
||||
declarations of `int` variables, functions and parameters without
|
||||
specifying their type. The biggest problem was to put `int
|
||||
main(int c, char ** v){` into the program. After some time, I
|
||||
became convinced that this is impossible. Finally, at least I
|
||||
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# try.sh - demonstrate IOCCC winner 2001/herrmann2
|
||||
#
|
||||
|
||||
# make sure CC is set so that when we do make CC="$CC" it isn't empty. Doing it
|
||||
# this way allows us to have the user specify a different compiler in an easy
|
||||
# way.
|
||||
if [[ -z "$CC" ]]; then
|
||||
CC="cc"
|
||||
fi
|
||||
|
||||
make CC="$CC" all >/dev/null || exit 1
|
||||
|
||||
# clear screen after compilation so that only the entry is shown
|
||||
clear
|
||||
|
||||
# we need to remove some files for later
|
||||
rm -f ioccc.out ioccc.out2 cup.out cup.out2
|
||||
|
||||
echo "$ ./herrmann2 \
|
||||
'char*d,A[9876];e;b;*ad,a,c; tw,ndr,T; wri; ;*h; _,ar ;on;'\
|
||||
' ;l ;i(V)man,n {-!har ; =Aadre(0,&e,o||n -- +,o4,=9,l=b=8,'\
|
||||
'!( te-*Aim)|(0~l),srand (l),,!A,d=,b))&&+((A + te-A(&(*)=+ +95>'\
|
||||
'e?(*& c_*r=5,r+e-r +_:2-19<-+?|(d==d),!n ?*d| *( (char**)+V+), ('\
|
||||
' +0,*d-7 ) -r+8)c:7:+++7+! r: and%9- 85! ()-(r+o):(+w,_+ A*(=er'\
|
||||
'i+(o)+b)),!write,(=_((-b+*h)(1,A+b,!!((((-+, a >T^l,( o-95=+))w?'\
|
||||
'++ &&r:b<<2+a +w) ((!main(n*n,V) , +-) ),l)),w= +T-->o +o+;{ &!'\
|
||||
'a;}return _+= ' < herrmann2.ioccc > herrmann2.orig.c && \
|
||||
echo && diff -s herrmann2.alt.c herrmann2.orig.c" 1>&2
|
||||
|
||||
./herrmann2 \
|
||||
'char*d,A[9876];e;b;*ad,a,c; tw,ndr,T; wri; ;*h; _,ar ;on;'\
|
||||
' ;l ;i(V)man,n {-!har ; =Aadre(0,&e,o||n -- +,o4,=9,l=b=8,'\
|
||||
'!( te-*Aim)|(0~l),srand (l),,!A,d=,b))&&+((A + te-A(&(*)=+ +95>'\
|
||||
'e?(*& c_*r=5,r+e-r +_:2-19<-+?|(d==d),!n ?*d| *( (char**)+V+), ('\
|
||||
' +0,*d-7 ) -r+8)c:7:+++7+! r: and%9- 85! ()-(r+o):(+w,_+ A*(=er'\
|
||||
'i+(o)+b)),!write,(=_((-b+*h)(1,A+b,!!((((-+, a >T^l,( o-95=+))w?'\
|
||||
'++ &&r:b<<2+a +w) ((!main(n*n,V) , +-) ),l)),w= +T-->o +o+;{ &!'\
|
||||
'a;}return _+= ' < herrmann2.ioccc > herrmann2.orig.c && \
|
||||
echo && diff -s herrmann2.alt.c herrmann2.orig.c
|
||||
|
||||
echo 1>&2
|
||||
echo "./herrmann2 "234 84 045 5 6765 7487 65190 84 656 254 12 43931 818 0 6542 \
|
||||
341 45 567 76967 7244 606 976567 895 81898 095 68678 1843 4650547 \
|
||||
565980691 389 04974" < herrmann2.ioccc" 1>&2
|
||||
|
||||
./herrmann2 "234 84 045 5 6765 7487 65190 84 656 254 12 43931 818 0 6542 \
|
||||
341 45 567 76967 7244 606 976567 895 81898 095 68678 1843 4650547 \
|
||||
565980691 389 04974" < herrmann2.ioccc
|
||||
echo 1>&2
|
||||
|
||||
rm -f ioccc.out ioccc.out2
|
||||
read -r -n 1 -p "Press any key to test the output a couple times on herrmann2.ioccc: "
|
||||
echo "$ ./herrmann2 < herrmann2.ioccc" 1>&2
|
||||
./herrmann2 < herrmann2.ioccc | tee ioccc.out
|
||||
sleep 2
|
||||
echo "$ ./herrmann2 < herrmann2.ioccc" 1>&2
|
||||
./herrmann2 < herrmann2.ioccc | tee ioccc.out2
|
||||
echo "$ diff ioccc.out ioccc.out2" 1>&2
|
||||
diff ioccc.out ioccc.out2
|
||||
rm -f ioccc.out ioccc.out2
|
||||
echo 1>&2
|
||||
|
||||
read -r -n 1 -p "Press any key to test the output a couple times on herrmann2.cup: "
|
||||
echo "$ ./herrmann2 < herrmann2.cup" 1>&2
|
||||
./herrmann2 < herrmann2.cup | tee cup.out
|
||||
sleep 2
|
||||
echo "$ ./herrmann2 < herrmann2.cup" 1>&2
|
||||
./herrmann2 < herrmann2.cup | tee cup.out2
|
||||
echo "$ diff cup.out cup.out2" 1>&2
|
||||
diff cup.out cup.out2
|
||||
|
||||
rm -f cup.out cup.out2
|
||||
+83
-21
@@ -4,6 +4,9 @@
|
||||
make
|
||||
```
|
||||
|
||||
There is another version which lets you use the arrow keys rather than the more
|
||||
awkward `,` and `.` keys. See [alternate code](#alternate-code) below.
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
@@ -26,39 +29,92 @@ For more detailed information see [2001 kev in bugs.md](/bugs.md#2001-kev).
|
||||
|
||||
NOTE: each player's paddle is at the bottom and the opponent at the top.
|
||||
|
||||
If you need to change the speed you can reconfigure it like (say
|
||||
for over a network and not the same host):
|
||||
|
||||
```sh
|
||||
make clobber SPEED=50 all # default value which is very fast
|
||||
```
|
||||
|
||||
There is an alternate version which lets you use the arrow keys to control your
|
||||
paddle. See below Alternate code.
|
||||
|
||||
|
||||
### Try:
|
||||
|
||||
```sh
|
||||
./kev\
|
||||
./kev localhost
|
||||
./kev # in one terminal
|
||||
|
||||
./kev localhost # in another terminal on the same host
|
||||
```
|
||||
|
||||
If you need to change the speed you can reconfigure it like (say
|
||||
for over a network and not the same host):
|
||||
|
||||
```sh
|
||||
make clobber CDEFINE="-DSPEED=50" all # original default value which is very fast
|
||||
```
|
||||
|
||||
If you wish to change the port you can do so like:
|
||||
|
||||
```sh
|
||||
make clobber CDEFINE="-DPORT=3773" all
|
||||
```
|
||||
|
||||
Of course if you want a port < 1024 you'll need to be root so don't do that.
|
||||
|
||||
And if you know what you're doing you can redefine the call to the `socket(2)`
|
||||
syscall with the `l_` macro. Of course you can do more than one at the same
|
||||
time. For instance to change the speed and port:
|
||||
|
||||
```sh
|
||||
make clobber CDEFINE="-DSPEED=512 -DPORT=3773" all
|
||||
```
|
||||
|
||||
If you have `xterm` try on one system:
|
||||
|
||||
```sh
|
||||
xterm -geometry 80x40 -fg green -bg black -fn 9x15bold -e ./kev &
|
||||
```
|
||||
|
||||
and then the other, the client system:
|
||||
|
||||
```sh
|
||||
xterm -geometry 80x40 -fg green -bg black -fn 9x15bold -e ./kev localhost&
|
||||
```
|
||||
|
||||
This might look nicer than just the terminal itself.
|
||||
|
||||
|
||||
## Alternate code:
|
||||
|
||||
To use:
|
||||
This version allows you to use arrow keys on the keyboard rather than the more
|
||||
awkward `,` and `.` keys to move your paddle.
|
||||
|
||||
|
||||
### Alternate build:
|
||||
|
||||
```sh
|
||||
make alt
|
||||
```
|
||||
|
||||
You can reconfigure the macros described above in the same way.
|
||||
|
||||
|
||||
### Alternate use:
|
||||
|
||||
Use `kev.alt` as you would `kev`.
|
||||
|
||||
|
||||
What happens if you use both, one in one terminal and the other in another
|
||||
terminal?
|
||||
|
||||
|
||||
### Alternate try:
|
||||
|
||||
If you have `xterm` try on one system:
|
||||
|
||||
```sh
|
||||
xterm -geometry 80x40 -fg green -bg black -fn 9x15bold -e ./kev.alt &
|
||||
```
|
||||
|
||||
and then the other, the client system:
|
||||
|
||||
```sh
|
||||
xterm -geometry 80x40 -fg green -bg black -fn 9x15bold -e ./kev.alt localhost&
|
||||
```
|
||||
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
Continuing with this year's "retro game" theme, this is another old game;
|
||||
@@ -72,13 +128,14 @@ box.
|
||||
|
||||
## Author's remarks:
|
||||
|
||||
|
||||
**NETWORK PONG!**
|
||||
|
||||
### REQUIREMENTS
|
||||
|
||||
* TCP sockets
|
||||
* curses
|
||||
* `usleep()`
|
||||
* `usleep(3)`
|
||||
|
||||
### DESCRIPTION
|
||||
|
||||
@@ -89,6 +146,7 @@ terminal sizes (though both players must have the same terminal size) and game
|
||||
speeds. Each player has a paddle to hit the ball, and you get points for
|
||||
getting the ball past your opponent's paddle. It's pretty fun! :)
|
||||
|
||||
|
||||
### RUNNING
|
||||
|
||||
Run the server first without any command line arguments, i.e.
|
||||
@@ -105,8 +163,8 @@ the name of the machine running the server, e.g.
|
||||
```
|
||||
|
||||
Make sure that the terminals on both ends are the same size. Also, the TCP port
|
||||
number (5455) specified in the [Makefile](Makefile) mustn't be blocked by a
|
||||
firewall.
|
||||
number (by default 5455) specified in the [Makefile](Makefile) mustn't be
|
||||
blocked by a firewall.
|
||||
|
||||
Here's a good quick example to see it in action on your own
|
||||
machine, assuming you have `Xwindows`:
|
||||
@@ -116,6 +174,7 @@ xterm -geometry 80x40 -fg green -bg black -fn 9x15bold -e ./kev &
|
||||
xterm -geometry 80x40 -fg green -bg black -fn 9x15bold -e ./kev localhost&
|
||||
```
|
||||
|
||||
|
||||
### PLAYING
|
||||
|
||||
Your paddle is the one at the bottom of the screen, your opponent
|
||||
@@ -130,9 +189,9 @@ missed the ball.
|
||||
|
||||
You can control the speed of the ball by the motion of your paddle
|
||||
when the ball hits it. If your paddle is still, then the ball
|
||||
just bounces normally off it. If your paddle is moving in the
|
||||
just bounces normally off it. If your paddle is moving in the
|
||||
same direction as the ball, then the ball's speed in that
|
||||
direction will increase. If your paddle is moving in the opposite
|
||||
direction will increase. If your paddle is moving in the opposite
|
||||
direction to the ball, then the ball's speed in that direction
|
||||
will decrease (or if the ball is going slowly enough, it'll turn
|
||||
around).
|
||||
@@ -145,12 +204,13 @@ might need to be root anyway), in `Xwindows` try `xset r rate 250
|
||||
can reset it later).
|
||||
|
||||
Look below in the Building section for info on how to speed up or
|
||||
slow down the game (useful if your increase or decrease the
|
||||
slow down the game (useful if you increase or decrease the
|
||||
terminal size).
|
||||
|
||||
|
||||
### BUILDING
|
||||
|
||||
Just run `make`to use the Makefile as above. The `SPEED` variable in the
|
||||
Just run `make` to use the Makefile as above. The `SPEED` variable in the
|
||||
Makefile controls the speed of the game (defaults to `50`). This speed is the
|
||||
delay between frames in milliseconds. Thus a value of 0 will make the game go
|
||||
as fast as your network can handle, and values less than 50 are useful for
|
||||
@@ -165,7 +225,8 @@ dial-up.
|
||||
The TCP port to use for network communications is specified by the
|
||||
`PORT` variable in the Makefile. If the default of `5455` is
|
||||
blocked for whatever reason, you can change it to something else.
|
||||
Of course if you use a `port < 1024`, you'll need to be root.
|
||||
Of course if you use a port < 1024, you'll need to be root.
|
||||
|
||||
|
||||
### OBFUSCATION
|
||||
|
||||
@@ -184,6 +245,7 @@ Finally, the number of "non-whitespace characters" (as defined by
|
||||
the rules) in the file is exactly 2048, which I think is rather
|
||||
unexpectedly cool. :)
|
||||
|
||||
|
||||
### BUGS
|
||||
|
||||
There are 3 warnings when I compile with gcc 2.95.3 (`-Wall -ansi
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
#include <netdb.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef PORT
|
||||
#define PORT 5455
|
||||
#endif
|
||||
#ifndef SPEED
|
||||
#define SPEED 50
|
||||
#endif
|
||||
#ifndef l_
|
||||
#define l_ socket(il.sin_family=AF_INET,SOCK_STREAM,0)
|
||||
#endif
|
||||
#define o0(M,W) mvprintw(W,M?M-1:M,"%s%s ",M?" ":"",_)
|
||||
#define O0(M,W) M##M=(M+=W##M)-W##M
|
||||
#define l1(M,W) M.tv_##W##sec
|
||||
|
||||
@@ -5,6 +5,15 @@
|
||||
#include <netdb.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef PORT
|
||||
#define PORT 5455
|
||||
#endif
|
||||
#ifndef SPEED
|
||||
#define SPEED 50
|
||||
#endif
|
||||
#ifndef l_
|
||||
#define l_ socket(il.sin_family=AF_INET,SOCK_STREAM,0)
|
||||
#endif
|
||||
#define o0(M,W) mvprintw(W,M?M-1:M,"%s%s ",M?" ":"",_)
|
||||
#define O0(M,W) M##M=(M+=W##M)-W##M
|
||||
#define l1(M,W) M.tv_##W##sec
|
||||
|
||||
@@ -24,7 +24,7 @@ high (200x100) with a tiny font.
|
||||
|
||||
## Judges' remarks:
|
||||
|
||||
Do get lost in the programs line of thought! :-)
|
||||
Do get lost in the program's line of thought! :-)
|
||||
|
||||
|
||||
## Author's remarks:
|
||||
|
||||
+16
-4
@@ -5,6 +5,18 @@ make
|
||||
```
|
||||
|
||||
|
||||
### Bugs and (Mis)features:
|
||||
|
||||
The current status of this entry is:
|
||||
|
||||
```
|
||||
STATUS: missing files - please provide them
|
||||
```
|
||||
|
||||
For more detailed information see [2001 rosten in bugs.md](/bugs.md#2001-rosten).
|
||||
|
||||
|
||||
|
||||
## To use:
|
||||
|
||||
```sh
|
||||
@@ -39,10 +51,12 @@ cursor) in the wrong way. :-)
|
||||
|
||||
## Author's remarks:
|
||||
|
||||
|
||||
### NAME
|
||||
|
||||
`rosten` - make the mouse act as if it has been greased
|
||||
|
||||
|
||||
### SYNOPSIS
|
||||
|
||||
```sh
|
||||
@@ -66,7 +80,7 @@ It only takes one optional option: the greasiness factor. This is the
|
||||
number that the speed is divided by on each iteration. The default is
|
||||
1.03. A setting of 1 - no friction - is fun as is 0.99.
|
||||
|
||||
Being an X program, it recognised the `DISPLAY` variable.
|
||||
Being an X program, it recognises the `DISPLAY` variable.
|
||||
|
||||
|
||||
### PORTABILITY
|
||||
@@ -148,9 +162,7 @@ problems with its own include files, but none with my program.
|
||||
### ERRORS
|
||||
|
||||
The DEC compiler of this version: `DEC C V5.6-079 on Digital UNIX V4.0 (Rev.
|
||||
878)`
|
||||
|
||||
can't compile the code. It thinks that preprocessor lines can not have
|
||||
878)` can't compile the code. It thinks that preprocessor lines can not have
|
||||
whitespace preceding the `#`. Moving the preprocessor directives to the
|
||||
beginning of the line wrecks the layout but makes it compile.
|
||||
|
||||
|
||||
@@ -1423,8 +1423,8 @@ index a5745bc7f4fa28b834c004f4cf19633e40ad9165..5e5e5334f33f9dbd95c70eddece3189d
|
||||
{ a = 0; y ( a [ b ]
|
||||
```
|
||||
|
||||
But since it does not for the time being it is advisable to just redirect stderr
|
||||
to /dev/null (`2>/dev/null`).
|
||||
But since it does not for the time being it is advisable to just redirect
|
||||
`stderr` to `/dev/null` (`2>/dev/null`).
|
||||
|
||||
|
||||
## 1996 jonth
|
||||
@@ -1855,7 +1855,7 @@ If you have a fix for 64-bit systems this is welcome as an alternate version, as
|
||||
stated above. You might like to look at the otccelf version but note that it (at
|
||||
least in 64-bit linux and macOS) has compilation errors.
|
||||
|
||||
### Aside: why were there changes if INABIAF ?
|
||||
### Aside: why were there changes made if INABIAF ?
|
||||
|
||||
This is a good question. The reason is we believe it better to fix some obvious
|
||||
problems: there were some bugs that would very possibly prevent it from working
|
||||
@@ -1887,10 +1887,6 @@ This program deliberately crashes if it loses (which is what it aims to do).
|
||||
The author referred to the file `herrmann1.turing` but it does not exist not even
|
||||
in the archive. Do you have a copy? Please provide it!
|
||||
|
||||
### STATUS: missing files - please provide them
|
||||
|
||||
The author also referred to the file `times2.turing` but this is also missing in
|
||||
the archive. Do you have a copy? Please provide it!
|
||||
|
||||
### STATUS: known bug - please help us fix
|
||||
|
||||
@@ -1927,6 +1923,17 @@ Although it is independent of endianness both systems need the same character
|
||||
set. In other words both have to be ASCII or EBCDIC - not one of each.
|
||||
|
||||
|
||||
## 2001 rosten
|
||||
|
||||
|
||||
### STATUS: missing files - please provide them
|
||||
### Source code: [2001/rosten/rosten.c](2001/rosten/rosten.c)
|
||||
### Information: [2001/rosten/README.md](2001/rosten/README.md)
|
||||
|
||||
The author stated that there is a cat man page for this program in case one
|
||||
wanted to install it as a tool but this is missing.
|
||||
|
||||
|
||||
## 2001 schweikh
|
||||
|
||||
|
||||
@@ -1943,6 +1950,7 @@ There's also no way to escape meta characters.
|
||||
## 2001 westley
|
||||
|
||||
|
||||
### STATUS: missing files - please provide them
|
||||
### STATUS: uses gets() - change to fgets() if possible
|
||||
### Source code: [2001/westley/westley.c](2001/westley/westley.c)
|
||||
### Information: [2001/westley/README.md](2001/westley/README.md)
|
||||
@@ -1957,6 +1965,69 @@ The author referred to a file `card.gif` but this file is missing. Do you have
|
||||
it? Please provide it!
|
||||
|
||||
|
||||
## 2001 williams
|
||||
|
||||
|
||||
### STATUS: known bug - please help us fix
|
||||
### Source code: [2001/williams/williams.c](2001/williams/williams.c)
|
||||
### Information: [2001/williams/README.md](2001/williams/README.md)
|
||||
|
||||
There seem to be a couple bugs at least in this entry. The first one is that
|
||||
when it does reach a certain point it crashes. This is in the function `J()` (or
|
||||
one it calls?). But sometimes it seems to not get that far, just showing lines
|
||||
moving back and forth. This is also in `J()`. It is not confirmed but it might
|
||||
be that the lines are drawn by `XDrawString()`, the last part in `J()`.
|
||||
|
||||
`J()` has a `for` loop identified by `for` and also a couple `while` loops,
|
||||
identified by `R`.
|
||||
|
||||
Since the game never ends properly the score is not printed either.
|
||||
|
||||
It appears that the crash happens in more than one place. For instance it has
|
||||
happened at
|
||||
|
||||
```c
|
||||
XCheckMaskEvent(d, 4,&e)
|
||||
```
|
||||
|
||||
but it's also happened at
|
||||
|
||||
```c
|
||||
else XDrawPoint(d ,w,g,(l.s+=l.a)>>9, h=(l.c+=l.b)>>9)
|
||||
```
|
||||
|
||||
In both cases the pointer `d` was corrupted:
|
||||
|
||||
```
|
||||
(lldb) p d
|
||||
(Display *) 0x0000000000000001
|
||||
```
|
||||
|
||||
It is believed that it also happened at
|
||||
|
||||
```c
|
||||
XDrawString(d,w,g,W/3,H/2,m,B);
|
||||
```
|
||||
|
||||
in `J()` and for the same reason.
|
||||
|
||||
The loop seems to be stuck in the call to `usleep(3)` like:
|
||||
|
||||
```c
|
||||
usleep(p*200);
|
||||
```
|
||||
|
||||
which happens to be in a `while()` loop.
|
||||
|
||||
There is a way to get the code to crash. If you don't do anything until
|
||||
everything is destroyed (where you'd lose the game if it ended) and then you
|
||||
start to shoot your missiles repeatedly it will eventually crash. It appears not
|
||||
to be the case (though this was not tried as many times) if you start shooting
|
||||
when the missiles come down. The fact you can shoot after it starts that
|
||||
sleeping in a loop does suggest that it's not stuck only showing those lines and
|
||||
sleeping.
|
||||
|
||||
|
||||
# 2002
|
||||
|
||||
There was no IOCCC in 2002.
|
||||
|
||||
+18
-7
@@ -2493,6 +2493,8 @@ letter word that would match the format and because it's pain that clang forces
|
||||
this. :-) This fix makes a point of the author's notes on portability no longer
|
||||
valid, btw.
|
||||
|
||||
Cody also added the [try.sh](2001/cheong/try.sh) script.
|
||||
|
||||
He also fixed it to check the number of args.
|
||||
|
||||
|
||||
@@ -2554,6 +2556,9 @@ itself by itself which just showed the usage string and exited. The [script
|
||||
herrmann1.sh](2001/herrmann1/herrmann1.sh) is used to compile the program but
|
||||
it's also how you invoke the program.
|
||||
|
||||
Cody provided the file [plus1.turing](2001/herrmann1/plus1.turing) based on the
|
||||
author's remarks.
|
||||
|
||||
He also fixed the [script herrmann1.sh](2001/herrmann1/herrmann1.sh) for
|
||||
shellcheck. In particular there were quite a few:
|
||||
|
||||
@@ -2574,9 +2579,8 @@ compile with clang by changing the args of main to be `int` and `char **`,
|
||||
respectively, and changing specific references to the `argv` arg, casting to
|
||||
`long` (was `int` but the 64-bit fix requires `long`) which was its old type.
|
||||
|
||||
The original file, used for demonstration purposes, as well as if you want to
|
||||
see if your system works with the original code, is the alternate version. See
|
||||
the README.md for details.
|
||||
Cody also added the [try.sh](2001/herrmann2/try.sh) script which might be more
|
||||
useful than any other place as the command to try is quite long with C code.
|
||||
|
||||
For some reason the original code was missing (presumingly because it had been
|
||||
added to `.gitignore` by accident) but Cody restored it from the archive.
|
||||
@@ -2584,11 +2588,18 @@ added to `.gitignore` by accident) but Cody restored it from the archive.
|
||||
|
||||
## [2001/kev](2001/kev/kev.c) ([README.md](2001/kev/README.md]))
|
||||
|
||||
Cody slowed down the ball just a tad as it went too fast for the speed at which
|
||||
the paddles move even when holding down the movement keys.
|
||||
Cody slowed down the ball just a tad (it was already a `-D` macro that was used
|
||||
in the code) as it went too fast for the speed at which the paddles move even
|
||||
when holding down the movement keys (but see below).
|
||||
|
||||
Cody also provided an alternate version which lets you use the arrow keys on
|
||||
your keyboard instead of the more awkward '`,`' and '`.`'.
|
||||
Cody also provided an [alternate version](2001/kev/kev.alt.c) which lets you use
|
||||
the arrow keys on your keyboard instead of the more awkward '`,`' and '`.`'.
|
||||
|
||||
He updated both versions to have `#ifndef..#endif` pairs for the macros so one
|
||||
can more easily configure different settings without having to specify all of
|
||||
them. The speed, `SPEED`, will be set to 50 if it's not defined at the compiler
|
||||
line as 50 is what it used to be set to. This way it's more to the original but
|
||||
without having to sacrifice playability by running `make`.
|
||||
|
||||
|
||||
## [2001/ollinger](2001/ollinger/ollinger.c) ([README.md](2001/ollinger/README.md))
|
||||
|
||||
Reference in new issue
Block a user