Bug fix and add alt code to 2005/anon
Previously the alt rule in the Makefile defined NO_STTY which stops the code from using stty(1) at the beginning and at the end. The stty sane resulted in a bus error in macOS and since the sole purpose was to set echo back on I changed it to stty echo (which works). (The NO_STTY macro is still checked, see below.) Added alt code with vi(m) like movements. The way to get it to not use stty is to use either make alt-no_stty or no_stty. The former will compile into anon.alt and the latter will compile into anon. Format and typo fix README.md file.
This commit is contained in:
1 parent
86b6b2e41e
commit
d1a462593f
5 files changed
+306
-128
No files matched your search
+8
-3
@@ -131,15 +131,20 @@ all: data ${TARGET}
|
|||||||
${PROG}: ${PROG}.c
|
${PROG}: ${PROG}.c
|
||||||
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||||
|
|
||||||
${PROG}.alt: ${PROG}.c
|
no_stty: ${PROG}.c
|
||||||
${CC} ${CFLAGS} -DNO_STTY $< -o $@ ${LDFLAGS}
|
${CC} ${CFLAGS} -DNO_STTY $< -o ${PROG} ${LDFLAGS}
|
||||||
|
|
||||||
|
|
||||||
# alternative executable
|
# alternative executable
|
||||||
#
|
#
|
||||||
alt: data ${ALT_TARGET}
|
alt: data ${ALT_TARGET}
|
||||||
@${TRUE}
|
@${TRUE}
|
||||||
|
|
||||||
|
${PROG}.alt: ${PROG}.alt.c
|
||||||
|
${CC} ${CFLAGS} $< -o $@ ${LDFLAGS}
|
||||||
|
|
||||||
|
alt-no_stty: ${PROG}.alt.c
|
||||||
|
${CC} ${CFLAGS} -DNO_STTY $< -o ${PROG}.alt ${LDFLAGS}
|
||||||
|
|
||||||
# data files
|
# data files
|
||||||
#
|
#
|
||||||
data: ${DATA}
|
data: ${DATA}
|
||||||
|
|||||||
+111
-119
@@ -4,8 +4,15 @@
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
||||||
NOTE: if your shell does not support `stty` then see the alternate version
|
NOTE: there is an alternate version for vi(m) like movements. See [alternate
|
||||||
described in the section below.
|
version](#alternate-code) below. If your terminal has problems with the
|
||||||
|
`stty(1)` commands try:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make anon-no_stty
|
||||||
|
```
|
||||||
|
|
||||||
|
This will compile [anon.c](anon.c) as `anon` to not use `stty(1)`.
|
||||||
|
|
||||||
|
|
||||||
### Bugs and (Mis)features:
|
### Bugs and (Mis)features:
|
||||||
@@ -33,17 +40,6 @@ For more detailed information see [2005 anon in bugs.md](/bugs.md#2005-anon).
|
|||||||
./anon 3 3 3
|
./anon 3 3 3
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Alternate version:
|
|
||||||
|
|
||||||
To use this version:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
make alt
|
|
||||||
```
|
|
||||||
|
|
||||||
Use `anon.alt` as you would `anon`.
|
|
||||||
|
|
||||||
After a very large number of moves this program will deliberately force itself
|
After a very large number of moves this program will deliberately force itself
|
||||||
to destroy its runtime stack. This is the author's way to prevent you from being
|
to destroy its runtime stack. This is the author's way to prevent you from being
|
||||||
frustrated (which might happen as it likes to create unsolvable puzzles just to
|
frustrated (which might happen as it likes to create unsolvable puzzles just to
|
||||||
@@ -56,16 +52,16 @@ This is supposed to happen. As is written in the
|
|||||||
That's not a bug, that's a feature.
|
That's not a bug, that's a feature.
|
||||||
```
|
```
|
||||||
|
|
||||||
If you want to see this in action you can easily do this with the alt version:
|
If you want to see this in action you can easily do this:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yes 'please crash on me :-)' | ./anon.alt 4 4
|
yes 'please crash on me :-)' | ./anon 4 4
|
||||||
```
|
```
|
||||||
|
|
||||||
What happens if you specify a larger board? For instance:
|
What happens if you specify a larger board? For instance:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
yes 'please crash on me :-)' | ./anon.alt 10 10 10
|
yes 'please crash on me :-)' | ./anon 10 10 10
|
||||||
```
|
```
|
||||||
|
|
||||||
If you specify more than three args the program might also crash or do
|
If you specify more than three args the program might also crash or do
|
||||||
@@ -73,6 +69,38 @@ something strange. This might also happen if you specify excessively large board
|
|||||||
dimensions. Try `100 100 100` for instance and see what happens!
|
dimensions. Try `100 100 100` for instance and see what happens!
|
||||||
|
|
||||||
|
|
||||||
|
## Alternate version:
|
||||||
|
|
||||||
|
The alternate version uses `vi(m)` like movement keys.
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate build:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make alt
|
||||||
|
```
|
||||||
|
|
||||||
|
To compile the version without `stty(1)`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make alt-no_stty
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Alternate use:
|
||||||
|
|
||||||
|
Use `anon.alt` as you would `anon` with the change in movements:
|
||||||
|
|
||||||
|
```
|
||||||
|
k | Move empty spot up
|
||||||
|
h | Move empty spot left
|
||||||
|
j | Move empty spot down
|
||||||
|
l | Move empty spot right
|
||||||
|
J | Move empty spot forwards
|
||||||
|
K | Move empty spot backwards
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Judges' remarks:
|
## Judges' remarks:
|
||||||
|
|
||||||
Taking the 4x4 board with 15 tiles to a whole new level, this entry takes this
|
Taking the 4x4 board with 15 tiles to a whole new level, this entry takes this
|
||||||
@@ -152,7 +180,7 @@ o | Move empty spot backwards
|
|||||||
```
|
```
|
||||||
|
|
||||||
**NOTE:** as a measure of alleviating counter-productivity due to addiction to
|
**NOTE:** as a measure of alleviating counter-productivity due to addiction to
|
||||||
this game, particularly for those hardcore gamers who insist on solving a\
|
this game, particularly for those hardcore gamers who insist on solving a
|
||||||
10x10x10 puzzle during work hours, and also to give an upper bound to user
|
10x10x10 puzzle during work hours, and also to give an upper bound to user
|
||||||
frustration when the program generates an unsolvable puzzle (which it does
|
frustration when the program generates an unsolvable puzzle (which it does
|
||||||
roughly half the time, just to hook you), the program will, after a very large
|
roughly half the time, just to hook you), the program will, after a very large
|
||||||
@@ -160,10 +188,11 @@ number of moves (which is system-specific) terminate itself by forcefully
|
|||||||
destroying its own runtime stack. This will result in a core dump and/or an
|
destroying its own runtime stack. This will result in a core dump and/or an
|
||||||
abnormal termination message; but this is a feature, not a bug! :-)
|
abnormal termination message; but this is a feature, not a bug! :-)
|
||||||
|
|
||||||
|
|
||||||
### COMPILE NOTES
|
### COMPILE NOTES
|
||||||
|
|
||||||
This program complies with ANSI/C99. It uses ANSI terminal control sequences,
|
This program complies with ANSI/C99. It uses ANSI terminal control sequences,
|
||||||
and so requires a terminal that understands ANSI sequences, such as vt100 or
|
and so requires a terminal that understands ANSI sequences, such as VT100 or
|
||||||
xterm.
|
xterm.
|
||||||
|
|
||||||
Some compilers may emit lots of warnings about how things ought to be
|
Some compilers may emit lots of warnings about how things ought to be
|
||||||
@@ -181,6 +210,7 @@ recursion, among other things. :-)
|
|||||||
|
|
||||||
See spoilers below for more notes about portability.
|
See spoilers below for more notes about portability.
|
||||||
|
|
||||||
|
|
||||||
### ABOUT THE CODE
|
### ABOUT THE CODE
|
||||||
|
|
||||||
Clearly, the author is very, very confused. Although he has broken up the file
|
Clearly, the author is very, very confused. Although he has broken up the file
|
||||||
@@ -191,17 +221,17 @@ something is clearly very, very wrong.
|
|||||||
|
|
||||||
In fact, the closer you look at this code, the more you realize something is
|
In fact, the closer you look at this code, the more you realize something is
|
||||||
horribly wrong with it. For example, why is it that the first statement in
|
horribly wrong with it. For example, why is it that the first statement in
|
||||||
`main()` is a `return`? What do all those nested `do`-loops do? (pun intended) Why
|
`main()` is a `return`? What do all those nested `do` loops do (pun intended)? Why
|
||||||
is the first statement inside the first `do`-loop a mere integer literal? Why
|
is the first statement inside the first `do` loop a mere integer literal? Why
|
||||||
are there such strange statements, like that empty string on line 65, or that
|
are there such strange statements, like that empty string on line 65, or that
|
||||||
isolated `||` on line 68?
|
isolated `||` on line 68?
|
||||||
|
|
||||||
But wait... why aren't any statements terminated by semicolons? Why is there
|
But wait... why aren't any statements terminated by semicolons? Why is there
|
||||||
only ONE semicolon in the entire program?! Why is the author opening nested
|
only ONE semicolon in the entire program?! Why is the author opening nested
|
||||||
blocks by such strange things as `||` and `(`, and closing them by `||` and `))`? The
|
blocks by such strange things as `||` and `(`, and closing them by `||` and `))`? The
|
||||||
`for`-loop isn't a `for`-loop! The `do`-loop isn't a `do`-loop! Or... are they? Well,
|
`for` loop isn't a `for` loop! The `do` loop isn't a `do` loop! Or... are they? Well,
|
||||||
the `for`-loop is defined in terms of a `while`-loop. But wait, the `while` loop is
|
the `for` loop is defined in terms of a `while` loop. But wait, the `while` loop is
|
||||||
defined in terms of the `do`-loop. And the `do`-loop is defined in terms of ...
|
defined in terms of the `do` loop. And the `do` loop is defined in terms of ...
|
||||||
Huh???
|
Huh???
|
||||||
|
|
||||||
And that `switch` statement toward the end of the program... wait a minute,
|
And that `switch` statement toward the end of the program... wait a minute,
|
||||||
@@ -217,7 +247,7 @@ expert, it is probably easier to understand the program in its original form.
|
|||||||
(And even then.) But that's just so, so wrong...
|
(And even then.) But that's just so, so wrong...
|
||||||
|
|
||||||
The entire program consists of a single expression, returned from `main()`.
|
The entire program consists of a single expression, returned from `main()`.
|
||||||
There are no `if`-statements, no `for`-loops or any looping or control constructs
|
There are no `if` statements, no `for` loops or any looping or control constructs
|
||||||
besides the `return`, in spite of the misleading appearance of the original
|
besides the `return`, in spite of the misleading appearance of the original
|
||||||
source. :) Yes I know, this has been attempted before, using `?:` and the bad
|
source. :) Yes I know, this has been attempted before, using `?:` and the bad
|
||||||
old comma operator. BUT this program does NOT use the `?:` operator, and there
|
old comma operator. BUT this program does NOT use the `?:` operator, and there
|
||||||
@@ -255,58 +285,19 @@ on the following architectures:
|
|||||||
It probably will also compile and work on many (all?) other \*nix platforms as
|
It probably will also compile and work on many (all?) other \*nix platforms as
|
||||||
well. How does it achieve this incredible feat?
|
well. How does it achieve this incredible feat?
|
||||||
|
|
||||||
|
|
||||||
### SPOILER
|
### SPOILER
|
||||||
|
|
||||||
.
|
Read the following only if you give up figuring it out :-)
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
(Read the following only if you give up figuring it out :-) )
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
.
|
|
||||||
|
|
||||||
#### The Evil Hack
|
#### The Evil Hack
|
||||||
|
|
||||||
The program (ab)uses an implicit assumption underlying practically all
|
The program (ab)uses an implicit assumption underlying practically all
|
||||||
architectures, and that is that parameters to C functions are implicit local
|
architectures, and that is that parameters to C functions are implicit local
|
||||||
variables allocated on the runtime stack. This runtime stack is a contiguous
|
variables allocated on the runtime stack. This runtime stack is a contiguous
|
||||||
section of memory, and therefore, after N recursive calls of `main()` to itself,
|
section of memory, and therefore, after `N` recursive calls of `main()` to
|
||||||
there is enough room on the stack to store whatever the program desires, so
|
itself, there is enough room on the stack to store whatever the program desires,
|
||||||
long as it does not exceed the maximum stack size.
|
so long as it does not exceed the maximum stack size.
|
||||||
|
|
||||||
(Theoretically, the runtime stack doesn't **have** to be contiguous... but all
|
(Theoretically, the runtime stack doesn't **have** to be contiguous... but all
|
||||||
current architectures that are worth consideration make this assumption. I
|
current architectures that are worth consideration make this assumption. I
|
||||||
@@ -316,32 +307,32 @@ theoretically it shouldn't even work in the first place.) :-)
|
|||||||
There are two types of architectures the program must handle: those that
|
There are two types of architectures the program must handle: those that
|
||||||
allocate the stack top-down, and those that allocate the stack bottom-up. The
|
allocate the stack top-down, and those that allocate the stack bottom-up. The
|
||||||
program correctly detects this at runtime, and adjusts itself accordingly.
|
program correctly detects this at runtime, and adjusts itself accordingly.
|
||||||
:-) (It is a simple matter of testing if the address of argc in a recursive
|
:-) (It is a simple matter of testing if the address of `argc` in a recursive
|
||||||
call is greater or less than in the parent call.)
|
call is greater or less than in the parent call.)
|
||||||
|
|
||||||
To avoid having to handle issues of int sizes, memory alignment, what exactly
|
To avoid having to handle issues of `int` sizes, memory alignment, what exactly
|
||||||
is on the stack between successive locations of argc, etc., the program
|
is on the stack between successive locations of `argc`, etc., the program
|
||||||
(ab)uses the fact that argc must necessarily be allocated on an aligned
|
(ab)uses the fact that `argc` must necessarily be allocated on an aligned
|
||||||
address, and therefore, the range of memory between two `argc`s is aligned, and
|
address, and therefore, the range of memory between two `argc`s is aligned, and
|
||||||
therefore safe to use as an array of longs.[\*] The program also compares the
|
therefore safe to use as an array of `long`s.[\*] The program also compares the
|
||||||
pointers as `long*` pointers, so that it will not have to deal with mapping
|
pointers as `long*` pointers, so that it will not have to deal with mapping
|
||||||
bytes to larger types. The initial memory allocation is done by recursively
|
bytes to larger types. The initial memory allocation is done by recursively
|
||||||
calling `main()` until there is enough space on the stack (the exact number of
|
calling `main()` until there is enough space on the stack (the exact number of
|
||||||
recursive calls is, of course, architecture-dependent).
|
recursive calls is, of course, architecture-dependent).
|
||||||
|
|
||||||
[\*] long was chosen instead of int, in order to skirt around pointer-size
|
[\*] `long` was chosen instead of `int`, in order to skirt around pointer-size
|
||||||
issues on architectures like ia64. It really can be made anything large enough
|
issues on architectures like ia64. It really can be made anything large enough
|
||||||
to hold both ints and pointers. `:-)`
|
to hold both `int`s and pointers. `:-)`
|
||||||
|
|
||||||
After the stack is deemed to have grown deep enough to be a sufficiently long
|
After the stack is deemed to have grown deep enough to be a sufficiently `long`
|
||||||
array (pun intended), the program begins its real code. It uses argc to keep
|
array (pun intended), the program begins its real code. It uses `argc` to keep
|
||||||
track of what it's supposed to be doing (since `main()` is the only function),
|
track of what it's supposed to be doing (since `main()` is the only function),
|
||||||
and `argv` to point to the base of this array (which is computed differently
|
and `argv` to point to the base of this array (which is computed differently
|
||||||
based on how the architecture allocates the stack). Since this fills up the
|
based on how the architecture allocates the stack). Since this fills up the
|
||||||
only two variables in the program, everything else is stored in the `MASS` [\*\*]
|
only two variables in the program, everything else is stored in the `MASS` [\*\*]
|
||||||
array.
|
array.
|
||||||
|
|
||||||
[\*\*] for "Memory Allocated by Stack Smashing" `:-)`
|
[\*\*] for "Memory Allocated by Stack Smashing" :-)
|
||||||
|
|
||||||
Note that from this point on, all bets are off as to what the contents of the
|
Note that from this point on, all bets are off as to what the contents of the
|
||||||
runtime stack are below the current recursive call to `main()`. We are
|
runtime stack are below the current recursive call to `main()`. We are
|
||||||
@@ -352,6 +343,7 @@ program doesn't need the comma operator. :-) (I was going to skirt around the
|
|||||||
issue by indirectly calling `exit()`, such as via `bsearch()` or `raise()`, but I
|
issue by indirectly calling `exit()`, such as via `bsearch()` or `raise()`, but I
|
||||||
was getting too close to the size limit.)
|
was getting too close to the size limit.)
|
||||||
|
|
||||||
|
|
||||||
#### Some notes about the macros
|
#### Some notes about the macros
|
||||||
|
|
||||||
In spite of the frightening appearance, it is probably easiest to understand
|
In spite of the frightening appearance, it is probably easiest to understand
|
||||||
@@ -374,7 +366,7 @@ a pointer to the top-level `argc`, to compute the location of the top-level
|
|||||||
`argv`. This is done before the rest of the `MASS` is used, since otherwise they
|
`argv`. This is done before the rest of the `MASS` is used, since otherwise they
|
||||||
may be overwritten.
|
may be overwritten.
|
||||||
|
|
||||||
`do(x,y)` has nothing to do with `do`-loops. :-) It defines a "state" in `main()`,
|
`do(x,y)` has nothing to do with `do` loops. :-) It defines a "state" in `main()`,
|
||||||
essentially, what to do when `main()` is called with `argc` containing a
|
essentially, what to do when `main()` is called with `argc` containing a
|
||||||
particular value. (This is why the user must never run the program with more
|
particular value. (This is why the user must never run the program with more
|
||||||
than 3 arguments. :-) The state number is `x`, and `y` is the code. The program's
|
than 3 arguments. :-) The state number is `x`, and `y` is the code. The program's
|
||||||
@@ -389,7 +381,7 @@ allocation. It's the only state that needs to return a value from the boolean
|
|||||||
expression, since once the `MASS` is initialized any return value can simply be
|
expression, since once the `MASS` is initialized any return value can simply be
|
||||||
stored in a well-known location in the `MASS`.
|
stored in a well-known location in the `MASS`.
|
||||||
|
|
||||||
`if(p,q,r,s)` is, in fact, an if-statement. `:-)` It is equivalent to:
|
`if(p,q,r,s)` is, in fact, an `if` statement. :-) It is equivalent to:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
if (p) { q; r } else {s}
|
if (p) { q; r } else {s}
|
||||||
@@ -401,7 +393,7 @@ expressions. Keep in mind that all statements are assumed to evaluate to
|
|||||||
false. The proof that this macro in fact implements an `if-then-else` construct
|
false. The proof that this macro in fact implements an `if-then-else` construct
|
||||||
is left as an exercise for the reader.
|
is left as an exercise for the reader.
|
||||||
|
|
||||||
`while(x,y,z)` is actually a `while`-loop after all. :-) It implements the loop
|
`while(x,y,z)` is actually a `while` loop after all. :-) It implements the loop
|
||||||
using, of course, recursive calls to `main()`. However, this macro doesn't
|
using, of course, recursive calls to `main()`. However, this macro doesn't
|
||||||
actually run a `while` loop; it implements the loop in the state numbered `x`. It
|
actually run a `while` loop; it implements the loop in the state numbered `x`. It
|
||||||
is used for defining a `while` loop, which can then be called from another state
|
is used for defining a `while` loop, which can then be called from another state
|
||||||
@@ -409,7 +401,7 @@ using `f(x)`. (The reason we can't directly implement a `while` loop inside
|
|||||||
another state ought to be clear: we can't recursively call `main()` to enter
|
another state ought to be clear: we can't recursively call `main()` to enter
|
||||||
into the middle of a state.)
|
into the middle of a state.)
|
||||||
|
|
||||||
However, it _is_ possible to implement a `for`-loop directly inside a state! The
|
However, it _is_ possible to implement a `for` loop directly inside a state! The
|
||||||
`for(s,i,x,y,z,Z)` macro does exactly this. Well, actually, technically speaking
|
`for(s,i,x,y,z,Z)` macro does exactly this. Well, actually, technically speaking
|
||||||
this macro can only be used as the last thing in a state, because it secretly
|
this macro can only be used as the last thing in a state, because it secretly
|
||||||
closes the current state and opens a new one behind the programmer's back.
|
closes the current state and opens a new one behind the programmer's back.
|
||||||
@@ -434,7 +426,7 @@ other_code;
|
|||||||
```
|
```
|
||||||
|
|
||||||
Note the "wrong" indentation in the former: the author prefers to write it
|
Note the "wrong" indentation in the former: the author prefers to write it
|
||||||
that way, since the analogy to the usual `for`-loop is clearer. This is why it's
|
that way, since the analogy to the usual `for` loop is clearer. This is why it's
|
||||||
easier to understand the pre-CPP code, since after CPP, the macro reshuffles
|
easier to understand the pre-CPP code, since after CPP, the macro reshuffles
|
||||||
`some_code` after `other_code` so that it can close the current state and define
|
`some_code` after `other_code` so that it can close the current state and define
|
||||||
the one containing the loop body. (Have I told you that the author of this
|
the one containing the loop body. (Have I told you that the author of this
|
||||||
@@ -445,7 +437,7 @@ indentation.)
|
|||||||
In spite of all appearances, `switch()` really is just a shorthand macro for
|
In spite of all appearances, `switch()` really is just a shorthand macro for
|
||||||
reducing code size. The evil choice of macro name is just to instill more
|
reducing code size. The evil choice of macro name is just to instill more
|
||||||
confusion into the would-be decipherer of this entry. :-) After all, `case()`
|
confusion into the would-be decipherer of this entry. :-) After all, `case()`
|
||||||
really _is_ the equivalent of a case statement, implemented using `&&`, and
|
really _is_ the equivalent of a `case` statement, implemented using `&&`, and
|
||||||
conveniently encapsulating code common to the cases in the only `switch`
|
conveniently encapsulating code common to the cases in the only `switch`
|
||||||
statement in the program, which is the code that decides what to do with a
|
statement in the program, which is the code that decides what to do with a
|
||||||
key press. What could be more fun than to define such a case in terms of a
|
key press. What could be more fun than to define such a case in terms of a
|
||||||
@@ -458,25 +450,25 @@ program, and what the various state numbers are meant to do:
|
|||||||
#### MASS usage map
|
#### MASS usage map
|
||||||
|
|
||||||
```
|
```
|
||||||
0 | Function return value
|
0 | Function return value
|
||||||
1 | Function argument 1\
|
1 | Function argument 1
|
||||||
2 | Function argument 2\
|
2 | Function argument 2
|
||||||
3 | Function argument 3\
|
3 | Function argument 3
|
||||||
4 | Scratch register 1\
|
4 | Scratch register 1
|
||||||
5 | Scratch register 2\
|
5 | Scratch register 2
|
||||||
6 | Scratch register 3\
|
6 | Scratch register 3
|
||||||
7 | Scratch register 4\
|
7 | Scratch register 4
|
||||||
8 | Value of original argv :-)\
|
8 | Value of original argv :-)
|
||||||
9 | Value of original argc :-)\
|
9 | Value of original argc :-)
|
||||||
11 | Zero register (always set to 0)\
|
11 | Zero register (always set to 0)
|
||||||
12 | Width of board\
|
12 | Width of board
|
||||||
13 | Length of board\
|
13 | Length of board
|
||||||
14 | Height of board\
|
14 | Height of board
|
||||||
15 | Current position of hole\
|
15 | Current position of hole
|
||||||
16 | Random seed for rand_r()\
|
16 | Random seed for rand_r(3)
|
||||||
18 | Scratch register used by state 18 :-)\
|
18 | Scratch register used by state 18 :-)
|
||||||
31 | field width for printing tiles\
|
31 | field width for printing tiles
|
||||||
32 | Start of board data\
|
32 | Start of board data
|
||||||
```
|
```
|
||||||
|
|
||||||
(**CAVEAT:** not all of these mappings ended up in the final version of the
|
(**CAVEAT:** not all of these mappings ended up in the final version of the
|
||||||
@@ -492,22 +484,22 @@ to be on all tested architectures.)
|
|||||||
#### State number assignments
|
#### State number assignments
|
||||||
|
|
||||||
```
|
```
|
||||||
1 | showhelp\
|
1 | showhelp
|
||||||
2 | showhelp\
|
2 | showhelp
|
||||||
3 | is 2D: start init\
|
3 | is 2D: start init
|
||||||
4 | is 3D: start init\
|
4 | is 3D: start init
|
||||||
5 | find allocation type\
|
5 | find allocation type
|
||||||
6 | MASS init, bottom-up\
|
6 | MASS init, bottom-up
|
||||||
7 | MASS init, top-down\
|
7 | MASS init, top-down
|
||||||
8 | main program\
|
8 | main program
|
||||||
9 | generate() outer loop\
|
9 | generate() outer loop
|
||||||
13 | render()\
|
13 | render()
|
||||||
14 | render() loop\
|
14 | render() loop
|
||||||
15 | exit(0)\
|
15 | exit(0)
|
||||||
16 | pick a tile that hasn't occurred yet\
|
16 | pick a tile that hasn't occurred yet
|
||||||
17 | inner loop of 16.\
|
17 | inner loop of 16.
|
||||||
18 | main loop\
|
18 | main loop
|
||||||
19 | checkwin() loop\
|
19 | checkwin() loop
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that some of the manually-implemented states (those not implemented by
|
Note that some of the manually-implemented states (those not implemented by
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Defines */
|
||||||
|
|
||||||
|
#ifndef NO_STTY
|
||||||
|
#define S1 system("stty cbreak -echo")||
|
||||||
|
#define S2 system("stty echo")||
|
||||||
|
#else
|
||||||
|
#define S1
|
||||||
|
#define S2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define A(i) (((q*)R(8))[i])
|
||||||
|
#define B p(b)
|
||||||
|
#define C p(&a)
|
||||||
|
#define H(i) sscanf(A(i),"%ld",&R(i+11))&0 ||
|
||||||
|
#define P q*
|
||||||
|
#define M(a,b) main((i)(a),(P)(b))
|
||||||
|
|
||||||
|
#define p(x) ((i*)(x))
|
||||||
|
#define D T(B-C,C-B)
|
||||||
|
#define T(x,y) ((a&1)*((i)(x))+(~a&1)*((i)(y)))
|
||||||
|
#define R(x) (*(B+x))
|
||||||
|
#define q char*
|
||||||
|
#define Q(x) ((q)(x))
|
||||||
|
#define W(x,y) ((B[x]=(i)(y))&0)||
|
||||||
|
#define BS (w*l*h)
|
||||||
|
#define do(x,y) (a-x||y)&&
|
||||||
|
#define f(x) M(x,b)
|
||||||
|
#define if(p,q,r,s) ((p)&&!(q)||(s))&&(r)||
|
||||||
|
#define i long
|
||||||
|
#define I (int)
|
||||||
|
|
||||||
|
#define while(x,y,z) do(x, y && !(z) && f(a))
|
||||||
|
#define for(s,i,x,y,z,Z) W(i,x)f(s)||Z) && while(s,R(i)-y,z||W(i,R(i)+1)0)(s
|
||||||
|
#define return return do
|
||||||
|
#define w R(12)
|
||||||
|
#define l R(13)
|
||||||
|
#define h R(14)
|
||||||
|
#define X(i) (R(i)%w)
|
||||||
|
#define Y(i) ((R(i)%(w*l))/w)
|
||||||
|
|
||||||
|
#define Z(i) (R(i)/(w*l))
|
||||||
|
#define pr !printf
|
||||||
|
#define switch(x) (W(32+R(15),R(32+x+R(15))) W(32+x+R(15),0) (B[15]+=x)|1)
|
||||||
|
#define case(k,x,y) R(a)==k && x && switch(y) && f(13)||
|
||||||
|
#define TL(i) R(32+R(i))
|
||||||
|
|
||||||
|
|
||||||
|
/* Main program */
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int a, P b)
|
||||||
|
{
|
||||||
|
return (1 >> 1 ^ 1, M(6 + !!M(5, C), C))
|
||||||
|
do
|
||||||
|
(
|
||||||
|
13,
|
||||||
|
pr("\x1b[;H") ||
|
||||||
|
|
||||||
|
for (14, 4, 0, BS, !X(4) && pr(
|
||||||
|
"%*s",
|
||||||
|
I(l - Y(4)),
|
||||||
|
""
|
||||||
|
)
|
||||||
|
||
|
||||||
|
|
||||||
|
if (TL(4), pr(
|
||||||
|
"%*ld", I
|
||||||
|
R(31),
|
||||||
|
TL(4)), 0,
|
||||||
|
pr("%*.*s", I
|
||||||
|
R(31),
|
||||||
|
I R(31), "#####")
|
||||||
|
)
|
||||||
|
if (X(4) == w - 1, pr("\n"), 0, pr("%*s", I(l + 1), "")) (
|
||||||
|
(R(4) + 1) % (w * l) == 0 && l > 1) &&
|
||||||
|
pr("\n"), 0))
|
||||||
|
do
|
||||||
|
(
|
||||||
|
1 & ~1,
|
||||||
|
pr("Syntax: %s <x> <y> [<z>]\n", b[0]) || f(15)
|
||||||
|
) ((a & ~1)
|
||||||
|
- 6 || D >> 12
|
||||||
|
&& (*(p(T(C, b)) + 8) = *p(Q(b) + (Q(&b) - Q(C)))
|
||||||
|
)
|
||||||
|
&& (*(p(T(C, b)) + 9) = *p(b)) && M(
|
||||||
|
8, T(C, b))
|
||||||
|
||
|
||||||
|
|
||||||
|
f(a)) &&
|
||||||
|
do
|
||||||
|
(
|
||||||
|
8,
|
||||||
|
if (R(9) & 1, H(1) H(
|
||||||
|
2) 0, W(14,
|
||||||
|
l) W(13, 1) 0,
|
||||||
|
H(1
|
||||||
|
)
|
||||||
|
H(2)
|
||||||
|
H(3)
|
||||||
|
0) (srand(time(0)), 0
|
||||||
|
) || for (9, 4, 0, BS, f(16)
|
||||||
|
|| W(R(4) + 32, R(0)) ! R(0) && W(15, R(4)) 0,
|
||||||
|
|
||||||
|
W(
|
||||||
|
31,
|
||||||
|
snprintf(A(0), 1, "%ld", BS))
|
||||||
|
S1 pr("\x1b[2J") ||
|
||||||
|
f(13)
|
||||||
|
||
|
||||||
|
|
||||||
|
f(18) ||
|
||||||
|
f(15)
|
||||||
|
))
|
||||||
|
do
|
||||||
|
(
|
||||||
|
16, W(0, rand() % BS
|
||||||
|
) W(1, 0)
|
||||||
|
for (17, 5, 0, R(4), !(
|
||||||
|
TL(
|
||||||
|
5) - R(0)) && !(
|
||||||
|
W(1, 1)
|
||||||
|
W(5, R(4) - 1)
|
||||||
|
0), R(1) && f(16))
|
||||||
|
)
|
||||||
|
do
|
||||||
|
(
|
||||||
|
18, W(0, 0
|
||||||
|
) for (19, 4, 0, BS, TL(4) - (R(4) + 1)
|
||||||
|
% BS && (
|
||||||
|
W(0, 1)
|
||||||
|
W(4, BS - 1
|
||||||
|
) 0) || 0, !R(0) &&
|
||||||
|
|
||||||
|
pr(
|
||||||
|
"You win!\n"
|
||||||
|
)
|
||||||
|
||
|
||||||
|
R(0) && (
|
||||||
|
W(a, getchar())
|
||||||
|
case ('k',
|
||||||
|
0 < Z(15),
|
||||||
|
-w * l)
|
||||||
|
case ('h',
|
||||||
|
0 < X(15),
|
||||||
|
-1)
|
||||||
|
case ('j',
|
||||||
|
Z(15) < h - 1,
|
||||||
|
w * l)
|
||||||
|
case ('l',
|
||||||
|
X(15) < w - 1,
|
||||||
|
1)
|
||||||
|
case ('J',
|
||||||
|
Y(15) < l - 1,
|
||||||
|
w)
|
||||||
|
case ('K',
|
||||||
|
0 < Y(15), -w
|
||||||
|
)
|
||||||
|
R(a) == 'q' && !
|
||||||
|
|
||||||
|
pr(
|
||||||
|
"You lose :-)\n"
|
||||||
|
)
|
||||||
|
&& f(15) || f(a))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
do
|
||||||
|
(
|
||||||
|
15, S2
|
||||||
|
(exit(0), a)
|
||||||
|
) (a - 5 || C < p(b));
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#ifndef NO_STTY
|
#ifndef NO_STTY
|
||||||
#define S1 system("stty cbreak -echo")||
|
#define S1 system("stty cbreak -echo")||
|
||||||
#define S2 system("stty sane")||
|
#define S2 system("stty echo")||
|
||||||
#else
|
#else
|
||||||
#define S1
|
#define S1
|
||||||
#define S2
|
#define S2
|
||||||
|
|||||||
+10
-5
@@ -2880,11 +2880,16 @@ suite.
|
|||||||
|
|
||||||
## [2005/anon](2005/anon/anon.c) ([README.md](2005/anon/README.md]))
|
## [2005/anon](2005/anon/anon.c) ([README.md](2005/anon/README.md]))
|
||||||
|
|
||||||
The author stated that if `stty` does not work right on your system you can
|
Cody fixed a problem where in some systems (like macOS) the `stty sane` would
|
||||||
compile it differently so that the program does not use `stty`. Cody set this
|
not work and end up causing a bus error. Instead of `stty sane` it uses `stty
|
||||||
up so that one need not update the [Makefile](Makefile). There's a fun command
|
echo` which is what it was trying to accomplish.
|
||||||
that Cody provided, to try, to see a feature that the author implemented. See
|
|
||||||
the README.md for details.
|
The author noted that one can define `NO_STTY` to not use `stty(1)` at all
|
||||||
|
(either to prevent having to hit enter or to turn echo off/on) which is
|
||||||
|
explained in the README.md.
|
||||||
|
|
||||||
|
Cody added the [alt code](2005/anon/README.md#alternate-code) with vi(m) like
|
||||||
|
movements.
|
||||||
|
|
||||||
|
|
||||||
## [2005/giljade](2005/giljade/giljade.c) ([README.md](2005/giljade/README.md]))
|
## [2005/giljade](2005/giljade/giljade.c) ([README.md](2005/giljade/README.md]))
|
||||||
|
|||||||
Reference in new issue
Block a user