release winning entries of IOCCC28 under the year 2024

Congratulations to:

* 2024/anders - Prize in sound coding - layered music generator
* 2024/burton - Prize in pentagrammatology - wordle hard mode solver
* 2024/cable1 - Prize in bot talk - LLM inference engine
* 2024/cable2 - Prize in murky waters - salmon recipe
* 2024/carlini - Prize in perfect timing - Intel 4004 emulation
* 2024/codemeow - Prize in tray planting - bonsai generator
* 2024/endoh1 - Prize in patient pointillism - slow ray tracer in CPP
* 2024/endoh2 - Prize in solid body physics - rotating rigid body simulation
* 2024/ferguson1 - Prize in diabolical logistics - Oregon trail pact with the devil
* 2024/ferguson2 - Prize in yil-tas - Navajo code talker translator
* 2024/howe - Nice accent eh-ward - mini vi
* 2024/kramer - Prize in linguistic arithmetic - natural language numerical calculator
* 2024/kurdyukov1 - Prize in phased periodicity - phase of the Moon
* 2024/kurdyukov2 - Prize in art restoration - JPEG artifact removal
* 2024/kurdyukov3 - Prize in virtual quietus - gaming VM and doom
* 2024/kurdyukov4 - Prize in embiggening - encode without literals
* 2024/maffiodo - Prize in creative interpretation - Jav\*script interpreter
* 2024/mills - Prize in ℤ₃ - Infocom v3 story interpreter
* 2024/stedolan - Best one liner - icon from MD5
* 2024/straadt - Prize in imitative rebooting - OpenRISC CPU and Linux
* 2024/tmarrec - Prize in cyclonic coding - 3D tornado simulation
* 2024/tompng - Prize in quasi bijection - vortex encryptor decryptor
* 2024/weaver - Sur prize - rickroll

Ran `make update` to perform the above.
 	new file:   2024/burton/.entry.json
This commit is contained in:
Landon Curt Noll committed 2025-08-02 14:43:07 -07:00
1 parent 10512e6c79
commit 09750f8899
443 files changed
+182938 -231

No files matched your search

+185
View File
@@ -0,0 +1,185 @@
{
"no_comment" : "mandatory comment: because comments were removed from the original JSON spec",
"entry_JSON_format_version" : "1.2 2024-09-25",
"award" : "Prize in \u2124\u2083",
"year" : 2024,
"dir" : "mills",
"entry_id" : "2024_mills",
"title" : "z3",
"abstract" : "Infocom v3 story interpreter",
"author_set" : [
{
"author_handle" : "Christopher_Mills"
}
],
"manifest" : [
{
"file_path" : "prog.c",
"inventory_order" : 20,
"OK_to_edit" : true,
"display_as" : "c",
"display_via_github" : true,
"entry_text" : "entry source code"
},
{
"file_path" : "Makefile",
"inventory_order" : 30,
"OK_to_edit" : true,
"display_as" : "makefile",
"display_via_github" : true,
"entry_text" : "entry Makefile"
},
{
"file_path" : "prog.alt.c",
"inventory_order" : 40,
"OK_to_edit" : true,
"display_as" : "c",
"display_via_github" : true,
"entry_text" : "alternate source code"
},
{
"file_path" : "prog.orig.c",
"inventory_order" : 50,
"OK_to_edit" : false,
"display_as" : "c",
"display_via_github" : true,
"entry_text" : "original source code"
},
{
"file_path" : "try.alt.sh",
"inventory_order" : 100,
"OK_to_edit" : true,
"display_as" : "shellscript",
"display_via_github" : true,
"entry_text" : "script to try alternate code"
},
{
"file_path" : "try.sh",
"inventory_order" : 100,
"OK_to_edit" : true,
"display_as" : "shellscript",
"display_via_github" : true,
"entry_text" : "script to try entry"
},
{
"file_path" : "2024_mills.tar.bz2",
"inventory_order" : 1415926535,
"OK_to_edit" : false,
"display_as" : "tbz2",
"display_via_github" : false,
"entry_text" : "download entry tarball"
},
{
"file_path" : ".entry.json",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "json",
"display_via_github" : true,
"entry_text" : "entry summary and manifest in JSON"
},
{
"file_path" : ".gitignore",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "gitignore",
"display_via_github" : true,
"entry_text" : "list of files that should not be committed under git"
},
{
"file_path" : ".path",
"inventory_order" : 4000000000,
"OK_to_edit" : false,
"display_as" : "path",
"display_via_github" : false,
"entry_text" : "directory path from top level directory"
},
{
"file_path" : "README.md",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "markdown",
"display_via_github" : true,
"entry_text" : "markdown source for this web page"
},
{
"file_path" : "advent.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Colossal Cave Adventure"
},
{
"file_path" : "curses-r10.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Hunting about in the attic of your family home"
},
{
"file_path" : "fantasydimension.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Fantasy world adventure via an enigmatic airlock"
},
{
"file_path" : "minizork.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Demo version of the original Zork"
},
{
"file_path" : "moonglow.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Spacecraft lands in a nearby corn field"
},
{
"file_path" : "sampler1_R55.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "1984 Infocom interactive fiction tutorial with 4 game samples"
},
{
"file_path" : "sampler2.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "1997 Infocom interactive fiction tutorial with 3 game samples"
},
{
"file_path" : "submarine-sabotage.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Serving aboard top-secret Puny class submarine"
},
{
"file_path" : "tristam.z3",
"inventory_order" : 4000000000,
"OK_to_edit" : true,
"display_as" : "binary",
"display_via_github" : true,
"entry_text" : "Surviving on Tristam island after a crash"
},
{
"file_path" : "index.html",
"inventory_order" : 4294967295,
"OK_to_edit" : false,
"display_as" : "html",
"display_via_github" : false,
"entry_text" : "this web page"
}
]
}
+1
View File
@@ -0,0 +1 @@
*.sav
+1
View File
@@ -0,0 +1 @@
2024/mills
Binary file not shown.
+214
View File
@@ -0,0 +1,214 @@
#!/usr/bin/env make
#
# 2024/mills
#############################
# shell used by this Makefile
#############################
SHELL= bash
#######################
# common tool locations
#######################
include ../../var.mk
#####################
# C compiler settings
#####################
# Common C compiler warnings to silence
#
# Example: CSILENCE= -Wno-poison-system-directories
#
CSILENCE= -Wno-implicit-function-declaration -Wno-incompatible-pointer-types \
-Wno-parentheses -Wno-pointer-sign -Wno-builtin-declaration-mismatch -Wno-unused-value
# Attempt to silence unknown warning options
#
CUNKNOWN= -Wno-unknown-warning-option
# Common C compiler warning flags
#
# NOTE: The addition of -pedantic to CWARN is a challenge that
# You may wish to avoid if it proves too problematic.
# There is NO penalty for removing -pedantic from CWARN.
#
CWARN= -Wall -Wextra -pedantic ${CSILENCE} ${CUNKNOWN}
# Compiler standard
#
CSTD= -std=gnu17
# Compiler bit architecture
#
# Example for 32-bitness: ARCH= -m32
# Example for 64-bitness: ARCH= -m64
#
# NOTE: Normally one should NOT specify a specific architecture.
#
ARCH=
# Defines that are needed to compile
#
# Example: -Dfoo -Dbar=baz
#
CDEFINE=
# Include files that are needed to compile
#
# Example: CINCLUDE= -include stdio.h
#
CINCLUDE=
# Other flags to pass to the C compiler
#
# Example: COTHER= -fno-math-errno
#
COTHER=
# Optimization
#
# NOTE: Feel free to change the level of compiler optimization.
# The "-O3" is just a friendly default you might wish to try.
#
# Example: OPT= -O0 -g
#
OPT= -O3
# Default flags for ANSI C compilation
#
CFLAGS= ${CSTD} ${CWARN} ${ARCH} ${CDEFINE} ${CINCLUDE} ${COTHER} ${OPT}
# Libraries needed to build
#
# Example: LDFLAGS= -lncurses -lm
#
LDFLAGS=
# C compiler to use
#
# NOTE: The IOCCC Judges recommend you leave CC as just "cc"
# and NOT set it to clang, or gcc, or something else
# unless you have a STRONG reason to do so.
#
# Setting CC to something other than "cc" makes your
# code less portable to those who do not have your
# particular C compiler. **hint**
#
# If you want to test your code with a particular C compiler,
# use the make command line. For example:
#
# make all CC=clang
# make all CC=gcc
#
CC= cc
# Compiler add-ons or replacements for clang only
#
ifeq "$(findstring $(CLANG),${CC})" "$(CLANG)"
#
# NOTE: This code is only invoked when CC is "clang"
# such as when you use the make command line:
#
# make all CC=clang
#
CSILENCE+= -Wno-comma -Wno-implicit-function-declaration -Wno-implicit-int-conversion \
-Wno-incompatible-pointer-types -Wno-missing-variable-declarations \
-Wno-parentheses -Wno-pointer-sign -Wno-poison-system-directories \
-Wno-extra-semi-stmt -Wno-misleading-indentation -Wno-unsafe-buffer-usage
#
CWARN+= -Weverything
#
endif
# Specific add-ons or replacements for gcc only
#
ifeq "$(findstring $(GCC),${CC})" "$(GCC)"
#
# NOTE: This code is only invoked when CC is "gcc"
# such as when you use the make command line:
#
# make all CC=gcc
#
CSILENCE+=
#
CWARN+=
#
endif
###########################################
# Special Makefile variables for this entry
###########################################
ENTRY= prog
PROG= ${ENTRY}
#
OBJ= ${PROG}.o
TARGET= ${PROG}
#
ALT_OBJ= ${PROG}.alt.o
ALT_TARGET= ${PROG}.alt
# list any data files supplied with your submission
#
# Example: DATA= curds whey
#
DATA= advent.z3 curses-r10.z3 fantasydimension.z3 minizork.z3 moonglow.z3 \
sampler1_R55.z3 sampler2.z3 submarine-sabotage.z3 tristam.z3
#################
# build the entry
#################
all: data ${TARGET}
@${TRUE}
.PHONY: all alt data everything clean clobber
# how to compile
#
${PROG}: ${PROG}.c
${CC} ${CFLAGS} ${PROG}.c -o $@ ${LDFLAGS}
# alternative executable
#
alt: data ${ALT_TARGET}
@${TRUE}
${PROG}.alt: ${PROG}.alt.c
${CC} ${CFLAGS} ${PROG}.alt.c -o $@ ${LDFLAGS}
# data files
#
data: ${DATA}
@${TRUE}
# both all and alt
#
everything: all alt
@${TRUE}
###############
# utility rules
###############
#
clean:
${RM} -f ${OBJ} ${ALT_OBJ}
clobber: clean
${RM} -f ${TARGET} ${ALT_TARGET}
${RM} -rf *.dSYM
######################################
# optional include of 1337 hacker rulz
######################################
-include 1337.mk ../1337.mk ../../1337.mk
+282
View File
@@ -0,0 +1,282 @@
## To build:
``` <!---sh-->
make all
```
## To use:
``` <!---sh-->
./prog foo.z3 foo.sav
```
The `foo.z3` is an [Infocom][2] version 3 [Z-machine][3] file,
and `foo.sav` is file that is written when you enter the command `SAVE`
and read when you enter the command `RESTORE`.
## Try:
``` <!---sh-->
./try.sh
For your first try, we suggest selecting games 0 or 1
```
## Alternate code:
### Alternate build:
``` <!---sh-->
make alt
```
### Alternate use:
``` <!---sh-->
./try.alt.sh
For your first try, we suggest selecting games 0 or 1
```
## Judges' remarks:
What is the "**Prize in ℤ₃**"? The "_double-struck Z_" is **NOT**
a reference to a set of integers, nor is the "_double-struck Z subscript
3_" a reference to a ring of 3-adic integers. Instead, it is a reference
to the 3rd version of a certain [virtual machine](https://en.wikipedia.org/wiki/Z-machine).
To fully appreciate the brilliance of this implementation, we suggest
illuminating the source code. But be careful not to get lost in the
labyrinthine twists and turns of this source code and get eaten by a Grue!
## Author's remarks:
### West of House
```
You are standing in an open field west of a white house, with a boarded
front door.
There is a small mailbox here.
```
These are the opening lines from the legendary [Zork][1], one of the most
influential and successful games of the early computer era. You can play a
demo version with the submitted program using the following command:
``` <!---sh-->
./prog minizork.z3 minizork.sav
``` <!---sh-->
_Minizork_ is a publicly-available demo version of the original _Zork_, but
the program can play any of the classic [Infocom][2] text adventure games that
run on the version 3 of the [Z-machine][3], a [virtual machine][4] which
Infocom used to run its mainframe-developed games on the 8-bit microcomputers
of the 1980's.
Although there were several iterations of the Z-machine, this program
implements version 3, which was used for dozens of Infocom's most famous and
influential [interactive fiction][5] games of the 1980's, including:
- The _Zork_ Trilogy (_Zork I_, _Zork II_ and _Zork III_) and the related
Enchanter Trilogy (_Enchanter_, _Sorcerer_ and _Spellbreaker_)
- The _Planetfall_ series (_Planetfall_ and _Stationfall_)
- _The Hitchhiker's Guide to the Galaxy_ (by Douglas Adams)
- _The Lurking Horror_ (Lovecraftian horror)
- _Plundered Hearts_ (romance)
- _Leather Godesses of Phobos_ (best left unsaid)
If you are new to interactive fiction, you might want to try one of the two
Infocom "four-in-one" demo samplers. These include a gentle introductory
tutorial to interactive fiction and some sample puzzles from _Zork I_,
_Planetfall_, _Infidel_, _The Witness_, _Trinity_ and _Leather Godesses of
Phobos_. You can run them by typing:
``` <!---sh-->
./prog sampler1_R55.z3 sampler1.sav
```
or
``` <!---sh-->
./prog sampler2.z3 sampler2.sav
```
In addition to the Infocom games, there is an entire community of interactive
fiction authors who write modern games which can be downloaded from sites
like [The Interactive Fiction Database][6], [The Interactive Fiction Wiki][7],
and [The Interactive Fiction Archive][8]. I've included a few "story files"
compiled for the Z3 machine from these sites for your enjoyment, but I'll
point out in particular [Curses][9] by Graham Nelson, the author of
[Inform][10], a literate programming system for writing interactive fiction.
You can of course run it with
``` <!---sh-->
./prog curses-r10.z3 curses.sav
```
By now you've probably figured out that `prog` takes two command-line
arguments, the first being the "story file" which is the game itself, and
the second (optional) parameter being the "save file", which is the file
the game will write if you type `SAVE` and read if you type `RESTORE`.
The second parameter is optional, but if you don't use it, you won't be able
to `SAVE` your game (think of this as an "Ironman" mode). Make sure that if
you switch story files, you also switch save files, because a `RESTORE` from
an unrelated story file will invoke what the C Standard Committee refers to
as ["Undefined Behavior"][22].
You can use this command-line template to run any other "version 3" games you
find, including the original Infocom ones. If you are lucky, you can find
the original files in one of the (sadly out-of-print) collections like
[The Lost Treasures of Infocom][11], or you could download a copy of the
[Zork Trilogy][12] (which was given away free as part of an Activision
promotion long ago). There are of course other places one might find Infocom
story files, but since they are not in the public domain I cannot give
pointers to them. Maybe Microsoft will decide to release them from
abandonware status now that they have bought Activision...
Finally, I have also included a copy of [Colossal Cave Adventure][13], which
may be better known by it's PDP-10 file name _ADVENT_. You can run it with
``` <!---sh-->
./prog advent.z3 advent.sav
```
_ADVENT_ is the original interactive fiction title by Crowther and Woods that
inspired _Zork_ and gave us hacker shibboleths like [Xyzzy][14] and "You are
in a maze of twisty little passages, all alike."
### It is pitch black. You are likely to be eaten by a grue.
So what makes the Z3 machine an interesting obfuscation target? Good question!
The IOCCC has seen all manner of virtual machines over the years, from
Commodore PETs to IBM PC's that can run Windows&trade; and even a mainframe or
two, so what is so challenging about a VM that ran on the TRS-80 and the
Apple II?
Well, a lot really. If you've got nothing better to do, take a look at the
[Z-Machine Standards Document][15] which is a detailed reverse-engineering
effort of Infocom's interpreter. A Z-machine implementation has to handle
the byte-code for an exceptionally complicated byte-code interpreter, which
in turn has to do a lot of high-level operations such as:
- Text encryption, decryption and decompression using a packed 5-bit modal
encoding and tables of "abbreviations"
- Lexical input parsing and mapping words through a compressed dictionary
and a "word separator" table
- Screen output that includes automatic word-wrapping and a status line
that shows the current room, number of moves and score (or current time,
for timed games like _Deadline_).
- Maintaining an "Object tree" that holds the state of the objects in the
game, their containment relationships, _attributes_ (openable, open, worn,
concealed, locked, etc.) and _properties_ (name, description, capacity,
exits, methods, etc.)
- Support for "virtual memory" -- the virtual machine's address space was
larger than the 16-bit addressing of the computers of the era, and certainly
larger than the 32 kilobytes of physical memory. These restrictions require
the interpreter to deal with multiple types of addresses to get at the
different types of storage.
- File I/O for saving, restoring and restarting the game.
- Dynamic memory areas such as the "header" and various other tables that
are used as sideband global communication between the interpreter and the
story file. Either or both can change the state, so it needs to be
explicitly checked.
- An exceptionally [CISC][16]-like variable-length bytecode with variadic
parameters and complicated encodings.
The interpreter is complicated because of the Herculean task the _Zork_
implementors set for themselves. _Zork_ itself was originally written on a
PDP-10 mainframe at MIT running a version of Lisp called [MDL][17]. It was
designed to have a more natural parser than the two-word parser of _ADVENT_.
_Zork_ itself escaped into the wild because of MIT's connection to
[ARPANET][18]. Contributions and requests from the player-base caused the
program to grow in size until it filled the mainframe's megabyte of memory.
When the newly-founded Infocom decided to port their grad-school project to
the world of microcomputers, they needed to somehow move a megabyte of MDL
code onto 8-bit microcomputers with 32 kilobytes of memory. They got there by
chopping the program into three separate parts, creating a stripped-down
subset of MDL called [ZIL][19] (for Zork Implementation Language) and
targeting the compiled ZIL bytecode to run on the Z-machine interpreter. The
Z-machine data types were specifically designed to reduce the memory footprint
as much as possible (including packed properties and compressed string
encodings) but the ZIL code was still too large (at over 100 kilobytes), so
the interpreter was designed to page in parts of the story file from the
floppy disk, one of the first uses of [virtual memory][20] on personal
computers.
All of the above was described in a much clearer fashion by Infocom employees
in a paper called [How to Fit a Large Program into a Small Machine][21],
which I only discovered after writing the previous paragraph, alas. I include
it here for the curious, because you can never have enough links in your
IOCCC write-up.
### A hollow voice says "Fool."
It took me many iterations to make the interpreter fit inside the IOCCC size
limits.
The original quite compact C program was maybe still 50% too large even after
doing as much minification as possible. I won't go into the details of the
next iterations of reduction (that would spoil all the fun), but suffice to
say, the steps I took share some similarities to the steps the _Zork_
implementors took to do their heroic reduction. It was only by completely
throwing out any attempt to make the source code look "pretty" was I able to
cross the `iocccsize` Rule 2b limitation of 2,053, and this included abusing
the whitespace rules.
Of course, by time the contest was announced, the size limit had increased
which means I had to go back and undo some of my heroics because now I had
enough wiggle room to make the source more picturesque. I have however
included a version of the original source (`prog.alt.c`) for your perusal and
amusement.
[1]: https://en.wikipedia.org/wiki/Zork "Zork"
[2]: https://en.wikipedia.org/wiki/Infocom "Infocom"
[3]: https://en.wikipedia.org/wiki/Z-machine "Z-machine"
[4]: https://en.wikipedia.org/wiki/Virtual_machine "Virtual machine"
[5]: https://en.wikipedia.org/wiki/Interactive_fiction "Interactive fiction"
[6]: https://ifdb.org "IFDB"
[7]: https://www.ifwiki.org "IFWiki"
[8]: https://www.ifarchive.org "IFArchive"
[9]: https://ifdb.org/viewgame?id=plvzam05bmz3enh8 "Curses"
[10]: https://ganelson.github.io/inform-website "Inform 7"
[11]: https://en.wikipedia.org/wiki/The_Lost_Treasures_of_Infocom
"The Lost Treasures of Infocom"
[12]: http://www.infocom-if.org/downloads/downloads.html "Zork Trilogy"
[13]: https://en.wikipedia.org/wiki/Colossal_Cave_Adventure
"Collosal Cave Adventure"
[14]: https://en.wikipedia.org/wiki/Xyzzy_(computing) "Xyzzy"
[15]: https://www.inform-fiction.org/zmachine/standards "Z-Machine Standards"
[16]: https://en.wikipedia.org/wiki/Complex_instruction_set_computer "CISC"
[17]: https://en.wikipedia.org/wiki/MDL_(programming_language) "MDL"
[18]: https://en.wikipedia.org/wiki/ARPANET "ARPANET"
[19]: https://www.ifwiki.org/ZIL "ZIL"
[20]: https://en.wikipedia.org/wiki/Virtual_memory "Virtual Memory"
[21]: https://mud.co.uk/richard/htflpism.htm "ZIL paper"
[22]: https://en.wikipedia.org/wiki/Undefined_behavior "Undefined Behavior"
<!--
Copyright © 1984-2025 by Landon Curt Noll and Leonid A. Broukhis. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
Binary file not shown.
Binary file not shown.
Binary file not shown.
+773
View File
@@ -0,0 +1,773 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!-- START: two lines up starts content from: inc/top.default.html -->
<!-- END: this line ends content from: inc/top.default.html -->
<!-- START: this line starts content from: inc/head.default.html -->
<head>
<link rel="stylesheet" href="../../ioccc.css">
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100..900&display=swap" rel="stylesheet">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<title>2024/mills - Prize in ℤ₃</title>
<link rel="icon" type="image/x-icon" href="../../favicon.ico">
<meta name="description" content="2024 IOCCC entry mills - Prize in ℤ₃">
<meta name="keywords" content="IOCCC, 2024, IOCCC 2024, IOCCC entry, mills, Prize in ℤ₃">
</head>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!! DO NOT MODIFY THIS FILE - This file is generated by a tool !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- END: this line ends content from: inc/head.default.html -->
<!-- -->
<!-- This web page was formed via the tool: bin/readme2index.sh -->
<!-- The content of main section of this web page came from: 2024/mills/README.md -->
<!-- -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2024/mills/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2024/mills/README.md !!! -->
<!-- !!! Do not modify this web page, instead modify the file: 2024/mills/README.md !!! -->
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<!-- Markdown content was converted into HTML via the tool: bin/md2html.sh -->
<!-- START: this line starts content from: inc/body.default.html -->
<body>
<!-- END: this line ends content from: inc/body.default.html -->
<!-- START: this line starts content from: inc/topbar.default.html -->
<div class="theader">
<nav class="topbar">
<div class="container">
<div class="logo">
<a href="../../index.html" class="logo-link">
IOCCC
</a>
</div>
<div class="topbar-items">
<div class="item">
<span class="item-header">
Entries
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../years.html" class="sub-item-link">
Winning entries
</a>
</div>
<div class="outfit-font">
<a href="../../authors.html" class="sub-item-link">
Winning authors
</a>
</div>
<div class="outfit-font">
<a href="../../location.html" class="sub-item-link">
Location of authors
</a>
</div>
<div class="outfit-font">
<a href="../../bugs.html" class="sub-item-link">
Bugs and (mis)features
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_an_entry" class="sub-item-link">
Fixing entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#fix_author" class="sub-item-link">
Updating author info
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
Status
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../news.html" class="sub-item-link">
News
</a>
</div>
<div class="outfit-font">
<a href="../../status.html" class="sub-item-link">
Contest status
</a>
</div>
<div class="outfit-font">
<a href="../../next/rules.html" class="sub-item-link">
IOCCC rules
</a>
</div>
<div class="outfit-font">
<a href="../../next/guidelines.html" class="sub-item-link">
IOCCC guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../markdown.html" class="sub-item-link">
Markdown guidelines
</a>
</div>
<div class="outfit-font">
<a href="../../SECURITY.html" class="sub-item-link">
Security policy
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
FAQ
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../faq.html" class="sub-item-link">
Frequently asked questions
</a>
</div>
<div class="outfit-font">
<a href="../../quick-start.html#enter" class="sub-item-link">
Enter the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#compiling" class="sub-item-link">
Compiling entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#running_entries" class="sub-item-link">
Running entries
</a>
</div>
<div class="outfit-font">
<a href="../../faq.html#help" class="sub-item-link">
How to help
</a>
</div>
</div>
</div>
<div class="item">
<span class="item-header">
About
</span>
<div class="sub-item">
<div class="outfit-font">
<a href="../../index.html" class="sub-item-link">
Home page
</a>
</div>
<div class="outfit-font">
<a href="../../social.html" class="sub-item-link">
IOCCC social media
</a>
</div>
<div class="outfit-font">
<a href="../../about.html" class="sub-item-link">
About the IOCCC
</a>
</div>
<div class="outfit-font">
<a href="../../judges.html" class="sub-item-link">
The judges
</a>
</div>
<div class="outfit-font">
<a href="../../thanks-for-help.html" class="sub-item-link">
Thanks for the help
</a>
</div>
<div class="outfit-font">
<a href="../../contact.html" class="sub-item-link">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</nav>
<div class="header-mobile-menu">
<noscript>
<a href="../../nojs-menu.html" class="topbar-js-label">
Please Enable JavaScript
</a>
</noscript>
<button id="header-open-menu-button" class="topbar-mobile-menu">
<img
src="../../png/hamburger-icon-open.png"
alt="hamburger style menu icon - open state"
width=48
height=48>
</button>
<button id="header-close-menu-button" class="hide-content">
<img
src="../../png/hamburger-icon-closed.png"
alt="hamburger style menu icon - closed state"
width=48
height=48>
</button>
<div id="mobile-menu-panel" class="hide-content">
<div class="mobile-menu-container">
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Entries
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../years.html">
Winning entries
</a>
<a class="mobile-submenu-item" href="../../authors.html">
Winning authors
</a>
<a class="mobile-submenu-item" href="../../location.html">
Location of authors
</a>
<a class="mobile-submenu-item" href="../../bugs.html">
Bugs and (mis)features
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_an_entry">
Fixing entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#fix_author">
Updating author info
</a>
<a class="mobile-submenu-item" href="../../thanks-for-help.html">
Thanks for the help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
Status
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../news.html">
News
</a>
<a class="mobile-submenu-item" href="../../status.html">
Contest status
</a>
<a class="mobile-submenu-item" href="../../next/rules.html">
IOCCC rules
</a>
<a class="mobile-submenu-item" href="../../next/guidelines.html">
IOCCC guidelines
</a>
<a class="mobile-submenu-item" href="../../markdown.html">
Markdown guidelines
</a>
<a class="mobile-submenu-item" href="../../SECURITY.html">
Security policy
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
FAQ
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../faq.html">
Frequently asked questions
</a>
<a class="mobile-submenu-item" href="../../quick-start.html#enter">
Enter the IOCCC
</a>
<a class="mobile-submenu-item" href="../../faq.html#compiling">
Compiling entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#running_entries">
Running entries
</a>
<a class="mobile-submenu-item" href="../../faq.html#help">
How to help
</a>
</div>
</div>
<div class="mobile-menu-wrapper">
<div class="mobile-menu-item">
About
</div>
<div class="mobile-submenu-wrapper">
<a class="mobile-submenu-item" href="../../index.html">
Home page
</a>
<a class="mobile-submenu-item" href="../../social.html">
IOCCC social media
</a>
<a class="mobile-submenu-item" href="../../about.html">
About the IOCCC
</a>
<a class="mobile-submenu-item" href="../../judges.html">
The judges
</a>
<a class="mobile-submenu-item" href="../../contact.html">
Contact us
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
var headerOpenMenuButton = document.getElementById("header-open-menu-button");
var headerCloseMenuButton = document.getElementById("header-close-menu-button");
var mobileMenuPanel = document.getElementById("mobile-menu-panel");
headerOpenMenuButton.addEventListener("click", () => {
headerOpenMenuButton.classList.remove("topbar-mobile-menu");
headerOpenMenuButton.classList.add("hide-content");
headerCloseMenuButton.classList.remove("hide-content");
headerCloseMenuButton.classList.add("topbar-mobile-menu");
mobileMenuPanel.classList.remove("hide-content");
mobileMenuPanel.classList.add("topbar-mobile-panel");
});
headerCloseMenuButton.addEventListener("click", () => {
headerCloseMenuButton.classList.remove("topbar-mobile-menu");
headerCloseMenuButton.classList.add("hide-content");
mobileMenuPanel.classList.add("hide-content");
mobileMenuPanel.classList.remove("topbar-mobile-panel");
headerOpenMenuButton.classList.add("topbar-mobile-menu");
headerOpenMenuButton.classList.remove("hide-content");
});
</script>
<!-- END: this line ends content from: inc/topbar.default.html -->
<!-- START: this line starts content from: inc/header.default.html -->
<div class="header">
<a href="../../2011/zucker/index.html">
<img src="../../png/ioccc.png"
alt="IOCCC image by Matt Zucker"
width=300
height=110>
</a>
<h1>The International Obfuscated C Code Contest</h1>
<h2>2024/mills - Prize in ℤ₃</h2>
<h3>Infocom v3 story interpreter</h3>
</div>
<!-- END: this line ends content from: inc/header.default.html -->
<!-- START: this line starts content from: inc/navbar.mid.html -->
<div class="navbar">
<a class="Left" href="../maffiodo/index.html">&larr; 2024/maffiodo</a>
<a class="Left" href="../index.html">&uarr; 2024 &uarr;</a>
<a class="Left" href="../stedolan/index.html">2024/stedolan &rarr;</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2024/mills/prog.c">C code</a>
<a class="Right" href="https://github.com/ioccc-src/winner/blob/master/2024/mills/Makefile">Makefile</a>
<a class="Right" href="#inventory">Inventory</a>
<a class="Right" href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2024%2Fmills%2Findex.html">&#x2713;</a>
</div>
<!-- END: this line ends content from: inc/navbar.mid.html -->
<!-- START: this line starts content from: inc/before-content.default.html -->
<div class="content" id="content">
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-author.sh -->
<h2 id="author">Author:</h2>
<ul>
<li>Name: <a href="../../authors.html#Christopher_Mills">Christopher Mills</a><br>
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)</li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
<!-- END: this line ends content for HTML phase 20 by: bin/output-index-author.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- BEFORE: 1st line of markdown file: 2024/mills/README.md -->
<h2 id="to-build">To build:</h2>
<pre><code> make all</code></pre>
<h2 id="to-use">To use:</h2>
<pre><code> ./prog foo.z3 foo.sav</code></pre>
<p>The <code>foo.z3</code> is an <a href="https://en.wikipedia.org/wiki/Infocom" title="Infocom">Infocom</a> version 3 <a href="https://en.wikipedia.org/wiki/Z-machine" title="Z-machine">Z-machine</a> file,
and <code>foo.sav</code> is file that is written when you enter the command <code>SAVE</code>
and read when you enter the command <code>RESTORE</code>.</p>
<h2 id="try">Try:</h2>
<pre><code> ./try.sh
For your first try, we suggest selecting games 0 or 1</code></pre>
<h2 id="alternate-code">Alternate code:</h2>
<h3 id="alternate-build">Alternate build:</h3>
<pre><code> make alt</code></pre>
<h3 id="alternate-use">Alternate use:</h3>
<pre><code> ./try.alt.sh
For your first try, we suggest selecting games 0 or 1</code></pre>
<h2 id="judges-remarks">Judges’ remarks:</h2>
<p>What is the “<strong>Prize in ℤ₃</strong>”? The “<em>double-struck Z</em>” is <strong>NOT</strong>
a reference to a set of integers, nor is the “<em>double-struck Z subscript
3</em>” a reference to a ring of 3-adic integers. Instead, it is a reference
to the 3rd version of a certain <a href="https://en.wikipedia.org/wiki/Z-machine">virtual machine</a>.</p>
<p>To fully appreciate the brilliance of this implementation, we suggest
illuminating the source code. But be careful not to get lost in the
labyrinthine twists and turns of this source code and get eaten by a Grue!</p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<h3 id="west-of-house">West of House</h3>
<pre><code> You are standing in an open field west of a white house, with a boarded
front door.
There is a small mailbox here.</code></pre>
<p>These are the opening lines from the legendary <a href="https://en.wikipedia.org/wiki/Zork" title="Zork">Zork</a>, one of the most
influential and successful games of the early computer era. You can play a
demo version with the submitted program using the following command:</p>
<pre><code> ./prog minizork.z3 minizork.sav</code></pre>
<p><em>Minizork</em> is a publicly-available demo version of the original <em>Zork</em>, but
the program can play any of the classic <a href="https://en.wikipedia.org/wiki/Infocom" title="Infocom">Infocom</a> text adventure games that
run on the version 3 of the <a href="https://en.wikipedia.org/wiki/Z-machine" title="Z-machine">Z-machine</a>, a <a href="https://en.wikipedia.org/wiki/Virtual_machine" title="Virtual machine">virtual machine</a> which
Infocom used to run its mainframe-developed games on the 8-bit microcomputers
of the 1980’s.</p>
<p>Although there were several iterations of the Z-machine, this program
implements version 3, which was used for dozens of Infocom’s most famous and
influential <a href="https://en.wikipedia.org/wiki/Interactive_fiction" title="Interactive fiction">interactive fiction</a> games of the 1980’s, including:</p>
<ul>
<li>The <em>Zork</em> Trilogy (<em>Zork I</em>, <em>Zork II</em> and <em>Zork III</em>) and the related
Enchanter Trilogy (<em>Enchanter</em>, <em>Sorcerer</em> and <em>Spellbreaker</em>)</li>
<li>The <em>Planetfall</em> series (<em>Planetfall</em> and <em>Stationfall</em>)</li>
<li><em>The Hitchhiker’s Guide to the Galaxy</em> (by Douglas Adams)</li>
<li><em>The Lurking Horror</em> (Lovecraftian horror)</li>
<li><em>Plundered Hearts</em> (romance)</li>
<li><em>Leather Godesses of Phobos</em> (best left unsaid)</li>
</ul>
<p>If you are new to interactive fiction, you might want to try one of the two
Infocom “four-in-one” demo samplers. These include a gentle introductory
tutorial to interactive fiction and some sample puzzles from <em>Zork I</em>,
<em>Planetfall</em>, <em>Infidel</em>, <em>The Witness</em>, <em>Trinity</em> and <em>Leather Godesses of
Phobos</em>. You can run them by typing:</p>
<pre><code> ./prog sampler1_R55.z3 sampler1.sav</code></pre>
<p>or</p>
<pre><code> ./prog sampler2.z3 sampler2.sav</code></pre>
<p>In addition to the Infocom games, there is an entire community of interactive
fiction authors who write modern games which can be downloaded from sites
like <a href="https://ifdb.org" title="IFDB">The Interactive Fiction Database</a>, <a href="https://www.ifwiki.org" title="IFWiki">The Interactive Fiction Wiki</a>,
and <a href="https://www.ifarchive.org" title="IFArchive">The Interactive Fiction Archive</a>. I’ve included a few “story files”
compiled for the Z3 machine from these sites for your enjoyment, but I’ll
point out in particular <a href="https://ifdb.org/viewgame?id=plvzam05bmz3enh8" title="Curses">Curses</a> by Graham Nelson, the author of
<a href="https://ganelson.github.io/inform-website" title="Inform 7">Inform</a>, a literate programming system for writing interactive fiction.
You can of course run it with</p>
<pre><code> ./prog curses-r10.z3 curses.sav</code></pre>
<p>By now you’ve probably figured out that <code>prog</code> takes two command-line
arguments, the first being the “story file” which is the game itself, and
the second (optional) parameter being the “save file”, which is the file
the game will write if you type <code>SAVE</code> and read if you type <code>RESTORE</code>.
The second parameter is optional, but if you don’t use it, you won’t be able
to <code>SAVE</code> your game (think of this as an “Ironman” mode). Make sure that if
you switch story files, you also switch save files, because a <code>RESTORE</code> from
an unrelated story file will invoke what the C Standard Committee refers to
as <a href="https://en.wikipedia.org/wiki/Undefined_behavior" title="Undefined Behavior">“Undefined Behavior”</a>.</p>
<p>You can use this command-line template to run any other “version 3” games you
find, including the original Infocom ones. If you are lucky, you can find
the original files in one of the (sadly out-of-print) collections like
<a href="https://en.wikipedia.org/wiki/The_Lost_Treasures_of_Infocom" title="The Lost Treasures of Infocom">The Lost Treasures of Infocom</a>, or you could download a copy of the
<a href="http://www.infocom-if.org/downloads/downloads.html" title="Zork Trilogy">Zork Trilogy</a> (which was given away free as part of an Activision
promotion long ago). There are of course other places one might find Infocom
story files, but since they are not in the public domain I cannot give
pointers to them. Maybe Microsoft will decide to release them from
abandonware status now that they have bought Activision…</p>
<p>Finally, I have also included a copy of <a href="https://en.wikipedia.org/wiki/Colossal_Cave_Adventure" title="Collosal Cave Adventure">Colossal Cave Adventure</a>, which
may be better known by it’s PDP-10 file name <em>ADVENT</em>. You can run it with</p>
<pre><code> ./prog advent.z3 advent.sav</code></pre>
<p><em>ADVENT</em> is the original interactive fiction title by Crowther and Woods that
inspired <em>Zork</em> and gave us hacker shibboleths like <a href="https://en.wikipedia.org/wiki/Xyzzy_(computing)" title="Xyzzy">Xyzzy</a> and “You are
in a maze of twisty little passages, all alike.”</p>
<h3 id="it-is-pitch-black.-you-are-likely-to-be-eaten-by-a-grue.">It is pitch black. You are likely to be eaten by a grue.</h3>
<p>So what makes the Z3 machine an interesting obfuscation target? Good question!</p>
<p>The IOCCC has seen all manner of virtual machines over the years, from
Commodore PETs to IBM PC’s that can run Windows™ and even a mainframe or
two, so what is so challenging about a VM that ran on the TRS-80 and the
Apple II?</p>
<p>Well, a lot really. If you’ve got nothing better to do, take a look at the
<a href="https://www.inform-fiction.org/zmachine/standards" title="Z-Machine Standards">Z-Machine Standards Document</a> which is a detailed reverse-engineering
effort of Infocom’s interpreter. A Z-machine implementation has to handle
the byte-code for an exceptionally complicated byte-code interpreter, which
in turn has to do a lot of high-level operations such as:</p>
<ul>
<li>Text encryption, decryption and decompression using a packed 5-bit modal
encoding and tables of “abbreviations”</li>
<li>Lexical input parsing and mapping words through a compressed dictionary
and a “word separator” table</li>
<li>Screen output that includes automatic word-wrapping and a status line
that shows the current room, number of moves and score (or current time,
for timed games like <em>Deadline</em>).</li>
<li>Maintaining an “Object tree” that holds the state of the objects in the
game, their containment relationships, <em>attributes</em> (openable, open, worn,
concealed, locked, etc.) and <em>properties</em> (name, description, capacity,
exits, methods, etc.)</li>
<li>Support for “virtual memory” – the virtual machine’s address space was
larger than the 16-bit addressing of the computers of the era, and certainly
larger than the 32 kilobytes of physical memory. These restrictions require
the interpreter to deal with multiple types of addresses to get at the
different types of storage.</li>
<li>File I/O for saving, restoring and restarting the game.</li>
<li>Dynamic memory areas such as the “header” and various other tables that
are used as sideband global communication between the interpreter and the
story file. Either or both can change the state, so it needs to be
explicitly checked.</li>
<li>An exceptionally <a href="https://en.wikipedia.org/wiki/Complex_instruction_set_computer" title="CISC">CISC</a>-like variable-length bytecode with variadic
parameters and complicated encodings.</li>
</ul>
<p>The interpreter is complicated because of the Herculean task the <em>Zork</em>
implementors set for themselves. <em>Zork</em> itself was originally written on a
PDP-10 mainframe at MIT running a version of Lisp called <a href="https://en.wikipedia.org/wiki/MDL_(programming_language)" title="MDL">MDL</a>. It was
designed to have a more natural parser than the two-word parser of <em>ADVENT</em>.
<em>Zork</em> itself escaped into the wild because of MIT’s connection to
<a href="https://en.wikipedia.org/wiki/ARPANET" title="ARPANET">ARPANET</a>. Contributions and requests from the player-base caused the
program to grow in size until it filled the mainframe’s megabyte of memory.
When the newly-founded Infocom decided to port their grad-school project to
the world of microcomputers, they needed to somehow move a megabyte of MDL
code onto 8-bit microcomputers with 32 kilobytes of memory. They got there by
chopping the program into three separate parts, creating a stripped-down
subset of MDL called <a href="https://www.ifwiki.org/ZIL" title="ZIL">ZIL</a> (for Zork Implementation Language) and
targeting the compiled ZIL bytecode to run on the Z-machine interpreter. The
Z-machine data types were specifically designed to reduce the memory footprint
as much as possible (including packed properties and compressed string
encodings) but the ZIL code was still too large (at over 100 kilobytes), so
the interpreter was designed to page in parts of the story file from the
floppy disk, one of the first uses of <a href="https://en.wikipedia.org/wiki/Virtual_memory" title="Virtual Memory">virtual memory</a> on personal
computers.</p>
<p>All of the above was described in a much clearer fashion by Infocom employees
in a paper called <a href="https://mud.co.uk/richard/htflpism.htm" title="ZIL paper">How to Fit a Large Program into a Small Machine</a>,
which I only discovered after writing the previous paragraph, alas. I include
it here for the curious, because you can never have enough links in your
IOCCC write-up.</p>
<h3 id="a-hollow-voice-says-fool.">A hollow voice says “Fool.”</h3>
<p>It took me many iterations to make the interpreter fit inside the IOCCC size
limits.</p>
<p>The original quite compact C program was maybe still 50% too large even after
doing as much minification as possible. I won’t go into the details of the
next iterations of reduction (that would spoil all the fun), but suffice to
say, the steps I took share some similarities to the steps the <em>Zork</em>
implementors took to do their heroic reduction. It was only by completely
throwing out any attempt to make the source code look “pretty” was I able to
cross the <code>iocccsize</code> Rule 2b limitation of 2,053, and this included abusing
the whitespace rules.</p>
<p>Of course, by time the contest was announced, the size limit had increased
which means I had to go back and undo some of my heroics because now I had
enough wiggle room to make the source more picturesque. I have however
included a version of the original source (<code>prog.alt.c</code>) for your perusal and
amusement.</p>
<!--
Copyright © 1984-2025 by Landon Curt Noll and Leonid A. Broukhis. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<!-- AFTER: last line of markdown file: 2024/mills/README.md -->
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
<div id="inventory">
<h1 id="inventory-for-2024mills">Inventory for 2024/mills</h1>
</div>
<h2 id="primary-files">Primary files</h2>
<ul>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/prog.c">prog.c</a> - entry source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/Makefile">Makefile</a> - entry Makefile</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/prog.alt.c">prog.alt.c</a> - alternate source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/prog.orig.c">prog.orig.c</a> - original source code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/try.alt.sh">try.alt.sh</a> - script to try alternate code</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/try.sh">try.sh</a> - script to try entry</li>
</ul>
<h2 id="secondary-files">Secondary files</h2>
<ul>
<li><a href="2024_mills.tar.bz2">2024_mills.tar.bz2</a> - download entry tarball</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/README.md">README.md</a> - markdown source for this web page</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/advent.z3">advent.z3</a> - Colossal Cave Adventure</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/curses-r10.z3">curses-r10.z3</a> - Hunting about in the attic of your family home</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/.entry.json">.entry.json</a> - entry summary and manifest in JSON</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/fantasydimension.z3">fantasydimension.z3</a> - Fantasy world adventure via an enigmatic airlock</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/minizork.z3">minizork.z3</a> - Demo version of the original Zork</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/moonglow.z3">moonglow.z3</a> - Spacecraft lands in a nearby corn field</li>
<li><a href=".path">.path</a> - directory path from top level directory</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/sampler1_R55.z3">sampler1_R55.z3</a> - 1984 Infocom interactive fiction tutorial with 4 game samples</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/sampler2.z3">sampler2.z3</a> - 1997 Infocom interactive fiction tutorial with 3 game samples</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/submarine-sabotage.z3">submarine-sabotage.z3</a> - Serving aboard top-secret Puny class submarine</li>
<li><a href="https://github.com/ioccc-src/winner/blob/master/2024/mills/tristam.z3">tristam.z3</a> - Surviving on Tristam island after a crash</li>
<li><a href="index.html">index.html</a> - this web page</li>
</ul>
<hr style="width:10%;text-align:left;margin-left:0">
<h4>
Jump to: <a href="#">top</a>
</h4>
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
<!-- END: this line ends content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
</div>
<!-- END: this line ends content from: inc/after-content.default.html -->
<!-- START: this line starts content from: inc/footer.inventory.html -->
<!--
Copyright © 1984-2025 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:
Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/
-->
<div class="footer">
<div id="copyright"><h3>Copyright &copy; 1984-2025 by Landon Curt Noll:
<a href="https://creativecommons.org/faq/#what-does-some-rights-reserved-mean"
target="_blank"
rel="license noopener noreferrer">Some Rights Reserved</a></h3>
<p>
This work is <b>licensed by Landon Curt Noll</b> under
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/?ref=chooser-v1"
target="_blank"
rel="license noopener noreferrer"
style="display:inline-block;">CC BY-SA 4.0</a></b>.
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/cc.png"
alt="cc inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/by.png"
alt="person inside circle symbol">
<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;"
src="../../png/sa.png"
alt="arrow looping back on itself inside circle symbol"><br>
You should <b>carefully review</b> the
<b><a href="https://creativecommons.org/licenses/by-sa/4.0/legalcode.en"
target="_blank"
rel="license noopener noreferrer">CC BY-SA 4.0 LEGAL CODE</a></b>
before using the licensed material.<br>
You may wish to review the
<b><a href="../../license.html"
target="_blank"
rel="license noopener noreferrer">highlights of some of the key features and terms</a></b>
of <b>CC BY-SA 4.0</b>.<br>
</p>
</div>
<div id="coda"><h3>Coda</h3>
<p>
<a href="https://validator.w3.org/nu/?doc=https%3A%2F%2Fwww.ioccc.org%2F2024%2Fmills%2Findex.html" rel="nofollow">Nu HTML check this web page</a><br>
<a href="#top">Jump to top</a> <a href="#content">Jump to Content</a> <a href="#inventory">Jump to Inventory</a><br>
</p>
</div>
</div>
<!-- END: this line ends content from: inc/footer.inventory.html -->
<!-- START: this line starts content from: inc/bottom.default.html -->
</body>
</html>
<!-- END: this line ends content from: inc/bottom.default.html -->
Binary file not shown.
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
unsigned short*y,*k,*J; unsigned char*x,Y[9<<14],*m=256+Y,**v,*E[]={
" :!","_SP a_bZ'","|a_ bmV_b|V|Wc eXo \250 f a \303f [ \243 c- M D_f 'Pp MP9 M-^|O\\ V ) NV ObP&VaP5V N- QM ggP\25V^ Dl[SOmXSMXbSMXbSIaSMXbSMXbSMXbo2^| P!|_Vba oZa!|Yp Jpf ~Yp JpbQI|Z_dZb KbmXSPXbSPXbSPXb c WQg NV JqP\23VaYP@W Db5"," \\ Xf L pPT X c T!bb!|VZ'"," R Qd R!b }b"," :bb!"," $ Lbo_ o$ Nb oZ_ ) O a_ZlP\\Z_$ Mb|_ c KVP: a_Vl^ lal ","Z","Waam``!","cr"," <!"," >!"," B_"," D_|a Dl[SOVb 'l"," $ Ob!|_Vbbao_ gg*'f R _QM baaP4 "," Mo$Zb_o; ","2m^| J(oQR ggYp>YqZ N` SMP4 Qa ,W5","2[SOm D_Yx^ Dl5","WQX|W|]|kZ ","1Y Cl^|Od M7VaP> X#$ Ob!a0PN|Od M7VaP> Y#=Y_ Lg \\ \2027 Z#| Re|=V RdVcPN w7 Z#=PN|Od M7VaP> ClV1","\r0123456789.,!?_#'\"/\\-:()","jVnVmVSXWbmZ ","|XoQO PSO coVr| \210g M coPN SPXboVr R Jf N5 ; } QU MSV co ``Wbm"," C_ L -} U) Q R-1^[l} h) I1 -[_a|[l \226Vf ^[SO_ h) T R[SOl D_`[l1","alZQP l"," ` Xf MZ q} X c T!bbZ'8PJZ|Z "," $*QKb| O*g'ciV","X9","\0337\33[H\33[K\33[7m\0\33[;72H\33[0;1m\0\0338","^f O u7 ^co Reo I= RdZc xb7"," N'f Q QKSMZhPv N) OZaSK`} ` Lf [ `SNZbZb `!b!|Vb0PxZr L hPoZ Nf JPT M) YZ N) KZ} Z AbO\\PP SKZc \243b7^"," ggz{ ,`| P% c KVP<V6{ *f6{ * f6{ #` 9'*f6{ #a 9'*'f6{ M$ Lb_*)6{ *g*)6{ *h; { *g; { K:_g6{ N:|_hVl{ Q:|_|gVcVl{ M* 9} V*|{ \\* Y$ Nbo&*'la _'l l{ * bb!; { *b_; { j.o_ gg*) X _QM M a!PU a_PP*` R!bb!; { U.|_ gg*)V' Ib; { ` gg._ gg; { *b; { * c; { *d; { *e; { *e*d c; "," Wgz r6{ M/6{ N/6{ L/{ M`_QMa; { #a 9{ #` 9{ 0{ { I&{ $ Ob!a0{ 5; { Yd``Wbm{ b0{ M#PJV|; { [c; "," Wgz5Y; { 5^; { W0m{ W0 U75Y; { { 2 Juo[c [^m V! x Yim]aSI x v56{ X_ Jto[c `^m V! w Yim wQI`n v5Z Xl6{ X_Yto[c d R^mnjl Ni P|YYxV`P> Yi w vX KcsZ Xl N!m{ V5; { V{ Ys{ U7{ 3{ Y6"," ggz d2 bmX^aof J} (| ,f L % qZ P2; { * bb+'8{ * b+'l{ Y.|_QM N+Va8} +Val{ 3^[l2 am _Wc c jY^wYfsWXo Rc \\ \210 f , \243f & hbZlP\36Zl am^*al*_*a_c \234^Xo b hc ]W| P!mX|V t`|X ) >VVmZ m*a|_aVl'SJ*bZ'la|Z bW`cVl^ P P\bVmZaP@ R hc 8YXoP\26*a_ [SJ*b|\"V``8``*c K'P95{ 7{ ={ y; { |{ V K9} 'V'|"," Yi\\ \377oP\260X Bl'QMz _Pq{ cPk{ oPe{ sP_{ PJ{ , WhPS{ PJ{ :XPX :'POP Z8aa aSJ`oQN Kgz(P5{ XP0{ X#P*{ ZQI Ob,oZ Bl QO i QL @bzPPP\n{ PJ{ @P<{ AP6{ PJ{ ?P,{ PJ{ BP\""}
#define L s; } if(!c--) { t
; long t,s,C; int main(int c, char**g){ unsigned char*r=!v?v=g,"C":c[47+g];
long S=s,T=t; if(!C)while(c=*r){ short z=s,w=t,q=*++r-72; c-=32>c?6:79;
if(0>c)main(c,E); else{ r+=6>c; if(C)C=c-44||t--; else{ { if(c>4&&16>c)s=t;
L=t[q[E]]; L; r+=q; L>>=q; L; r+=q*!t; L<<=q; L=q; L=T; L=*y--; L=x-m; L=*x++;
L=1; L=S; L=-1; L; J=m+t; L=k-J; L=0; L=t[m]; L--; L++; L+=L-=L=z*w; L=z/w;
L=z<w; L&=L|=L=1<<t; L; y=k; L; k=y; L[m]=L; x=t+m; L; k=t+J; L; T=t; S=L=t[k];
L[k]=L=!t; L; if(t)exit(0); L=open(v[t],0); L=creat(v[t],384); L; close(t);
L=read(t,x,s); L=write(t,x,s); L=t<0?srand(-t),0:rand()%t+1; L; C=t--; L;
break; L; *++y=t; L; break; } } } } }
+33
View File
@@ -0,0 +1,33 @@
short unsigned*y,*k,*J; char unsigned*x,Y[9<<14],*m=256+Y,**v,*E[]={ "T:!","_SPUa_bZ'","|a_ bmV_b|V|WcReXoT\2\
50UfRaUT\303fR[T\243Uc-TMTD_fR'PpTMP9TM-^|O\\RVU)RNVTObP&VaP5VTN-UQMUTggP\25V^TDl[SOmXSMXbSMXbSIaSMXbSMXbSMXb\
o2^|TP!|_VbaUoZa!|YpTJpfR~YpTJpbQI|Z_dZbTKbmXSPXbSPXbSPXbUcRWQgRNVTJqP\23VaYP@WTDb5","R\\TXfRLUpPTTXUcTT!bb!|\
VZ'", "RRTQdTR!bT}b" ,"T:bb!" , " $TLbo_Ro$TNbUoZ_ )ROUa_ZlP\\Z_$TMb|_ cRKVP:Ua_Vl^UlalU",
"Z","Waam``!","cr","T<!","T>!", "TB_","TD_|aTDl[SOVbU'l"," $TOb!|_Vbbao_Tgg*'fRRU_QMUbaaP\
4U"," RMo$Zb_o; U","2m^|TJ(oQR" "TggYp>YqZRN`USMP4UQaR,W5","2[SOmTD_Yx^TDl5","WQX|W|]|kZU"
,"1YTCl^|OdRM7VaP>TX#$TOb!a0PN" "|OdRM" "7VaP>TY#=Y_TJgR\\T\2027TZ#|TRe|=VTRdVcPNTw7TZ#=PN|OdRM7V\
aP>TClV1","\r0123456789.,!?_#'" "\"/\\" "-:()","jVnVmVSXWbmZU","|XoQORPSOUcoVr|UT\210gRMUcoPNUSPXb\
oVrRRUTJfRN5U; } UQURMSVUcoU``" "Wbm" , "TC_RLU-} UTU)RQTR-1^[l} UTh)RI1U-[_a|[lT\226VfR^[SO_Th)RTT\
R[SOlTD_`[l1","alZQPUl","R`TXfRMZUq} TXUc" "TT!bbZ'8PJZ" "|ZU"," $*QKb|TO*g'ciV","X9", "\03\
37\33[H\33[K\33[7m \0 \33[;72H\33[0;1m\0" "\0338","^f" "ROTu7U^coUTReoRI=UTRdZcTxb7","T\
N'fRQUQKSMZhPvUTN)ROZaSK`} UR`TLfR[U`SN" "ZbZbT`!b!|" "Vb0PxZrRLThPoZTNfRJPTUTM)RYZTN\
)RKZ} ZTAbO\\PPUSKZcT\243b7^","Tggz{ ," "`|RP% cRKV" "P<V" "6{ *f6{ * f6{ #` 9'*f6{ #a"
" 9'*'f6{ RM$TLb_*)6{ *g*)6{ *h; {" " *g; { RK" ":_g6{" " RN:|_hVl{ RQ:|_|gVcVl{ RM\
* 9} V*|{ R\\*RY$TNbo&*'laU_'l Ul{ " "* bb!; { *b_" "; { Rj" ".o_Tgg*)RXU_QMRMUa!PUUa_PP*`T\
R!bb!; { RU.|_Tgg*)V'RIb; { `Tgg." "_Tgg; { *b; { * c; { *d; {" " *e; { *e*d c; ","TWgz r6{ \
TM/6{ TN/6{ TL/{ RM`_QMa; { #a 9" "{ #` 9{ 0{ { RI&{ $TOb!a" "0{ 5; { Yd``Wbm{ b0{ RM#\
PJV|; { [c; ","TWgz5Y; { 5^; { W" "0m{ W0TU75Y; { { 2TJuo[cR[^m" "TV!UxTYim]aSIUxUv56{ TX_TJto[\
cR`^mTV!UwTYimUwQI`nUv5ZTXl6{ TX" "_Yto[" "cRdTR^mnjl" "TNiRP|YYxV`P>TYiUwUvXTKcsZTXlT\
N!m{ V5; { V{ Ys{ TU7{ 3{ Y6" , "Tggz " "Rd2 bmX^ao" "fRJ} (|U,fRLU%UqZUP2; { * bb+'8"
#define L s; } { { { { } { } } { ; ; } { { ; { ; } } { ; { } } ; } } } if(!c--) { t
"{ * b+'l{ RY.|_QMRN+Va8} +Va" "l{ 3^[l2 am _Wc c" "RjY^wYfsWXoTRcR\\T\210UfR,UT\\
243fR&UThbZlP\36Zl am^*al*_*a_" "cR\234^XoRbThcR]W|" "TP!mX|VRt`|XU)R>VVmZRm*a|_aVl\
'SJ*bZ'la|Z bW`cVl^UP\vP\bVmZa" "P@URRThcR8YXoP\26*a" "_R[SJ*b|\"V``8``*cRK'P95{ 7{"
" ={ y; { |{ V RK9} 'V'|","TYi\\T\377oP\260XTBl'QMzT_Pq" "{ TcPk{" " ToPe{ TsP_{ PJ{ ,TWhPS{ PJ{ \
T:XPXT:'POP\fZ8aaUaSJ`oQNTKgz(P5{ XP0{ X#P*{ ZQITOb,oZTBl" "UQORi" "UQLT@bzPPP\n{ PJ{ U@P<{ UAP6{"
" PJ{ U?P,{ PJ{ UBP\""} ; long t,s,C; int main( int c,char **g){ char unsigned*r=!v?v=g,"C":c[47
+g]; long S=s,T=t; if(!C)while(c=*r){ short z=s,w=t,q=*++r- 72; c-=32>c?6:79; if(0>c)main(c,
E); else{ r+=6>c; if(C)C=c-44||t--; else{ { if(c>4&&16>c)s=t ; L=t[q[E]]; L; r+=q; L>>=q; L; r
+=q*!t; L<<=q; L=q; L=T; L=*y--; L=x-m; L=*x++; L=1; L=S; L=-1 ; L; J=m+t; L=k-J; L=0; L=t[m]; L--
; L++; L+=L-=L=z*w; L=z/w; L=z<w; L&=L|=L=1<<t; L; y=k; L; k=y; L[m]=L; x=t+m; L; k=t+J; L; T=t; S=L=t[k]; L[k
]=L=!t; L; if(t)exit(0); L=open(v[t],0); L=creat(v[t],384); L; close(t); L=read(t,x,s); L=write(t,x,s); L=t<0?
srand(-t),0:rand()%t+1; L; C=t--; L; break; L; *++y=t; L; break; } } } } { { { } ; { } { } { ; } { } } } { } }
+33
View File
@@ -0,0 +1,33 @@
short unsigned*y,*k,*J; char unsigned*x,Y[9<<14],*m=256+Y,**v,*E[]={ "T:!","_SPUa_bZ'","|a_ bmV_b|V|WcReXoT\2\
50UfRaUT\303fR[T\243Uc-TMTD_fR'PpTMP9TM-^|O\\RVU)RNVTObP&VaP5VTN-UQMUTggP\25V^TDl[SOmXSMXbSMXbSIaSMXbSMXbSMXb\
o2^|TP!|_VbaUoZa!|YpTJpfR~YpTJpbQI|Z_dZbTKbmXSPXbSPXbSPXbUcRWQgRNVTJqP\23VaYP@WTDb5","R\\TXfRLUpPTTXUcTT!bb!|\
VZ'", "RRTQdTR!bT}b" ,"T:bb!" , " $TLbo_Ro$TNbUoZ_ )ROUa_ZlP\\Z_$TMb|_ cRKVP:Ua_Vl^UlalU",
"Z","Waam``!","cr","T<!","T>!", "TB_","TD_|aTDl[SOVbU'l"," $TOb!|_Vbbao_Tgg*'fRRU_QMUbaaP\
4U"," RMo$Zb_o; U","2m^|TJ(oQR" "TggYp>YqZRN`USMP4UQaR,W5","2[SOmTD_Yx^TDl5","WQX|W|]|kZU"
,"1YTCl^|OdRM7VaP>TX#$TOb!a0PN" "|OdRM" "7VaP>TY#=Y_TJgR\\T\2027TZ#|TRe|=VTRdVcPNTw7TZ#=PN|OdRM7V\
aP>TClV1","\r0123456789.,!?_#'" "\"/\\" "-:()","jVnVmVSXWbmZU","|XoQORPSOUcoVr|UT\210gRMUcoPNUSPXb\
oVrRRUTJfRN5U; } UQURMSVUcoU``" "Wbm" , "TC_RLU-} UTU)RQTR-1^[l} UTh)RI1U-[_a|[lT\226VfR^[SO_Th)RTT\
R[SOlTD_`[l1","alZQPUl","R`TXfRMZUq} TXUc" "TT!bbZ'8PJZ" "|ZU"," $*QKb|TO*g'ciV","X9", "\03\
37\33[H\33[K\33[7m \0 \33[;72H\33[0;1m\0" "\0338","^f" "ROTu7U^coUTReoRI=UTRdZcTxb7","T\
N'fRQUQKSMZhPvUTN)ROZaSK`} UR`TLfR[U`SN" "ZbZbT`!b!|" "Vb0PxZrRLThPoZTNfRJPTUTM)RYZTN\
)RKZ} ZTAbO\\PPUSKZcT\243b7^","Tggz{ ," "`|RP% cRKV" "P<V" "6{ *f6{ * f6{ #` 9'*f6{ #a"
" 9'*'f6{ RM$TLb_*)6{ *g*)6{ *h; {" " *g; { RK" ":_g6{" " RN:|_hVl{ RQ:|_|gVcVl{ RM\
* 9} V*|{ R\\*RY$TNbo&*'laU_'l Ul{ " "* bb!; { *b_" "; { Rj" ".o_Tgg*)RXU_QMRMUa!PUUa_PP*`T\
R!bb!; { RU.|_Tgg*)V'RIb; { `Tgg." "_Tgg; { *b; { * c; { *d; {" " *e; { *e*d c; ","TWgz r6{ \
TM/6{ TN/6{ TL/{ RM`_QMa; { #a 9" "{ #` 9{ 0{ { RI&{ $TOb!a" "0{ 5; { Yd``Wbm{ b0{ RM#\
PJV|; { [c; ","TWgz5Y; { 5^; { W" "0m{ W0TU75Y; { { 2TJuo[cR[^m" "TV!UxTYim]aSIUxUv56{ TX_TJto[\
cR`^mTV!UwTYimUwQI`nUv5ZTXl6{ TX" "_Yto[" "cRdTR^mnjl" "TNiRP|YYxV`P>TYiUwUvXTKcsZTXlT\
N!m{ V5; { V{ Ys{ TU7{ 3{ Y6" , "Tggz " "Rd2 bmX^ao" "fRJ} (|U,fRLU%UqZUP2; { * bb+'8"
#define L s; } { { { { } { } } { ; ; } { { ; { ; } } { ; { } } ; } } } if(!c--) { t
"{ * b+'l{ RY.|_QMRN+Va8} +Va" "l{ 3^[l2 am _Wc c" "RjY^wYfsWXoTRcR\\T\210UfR,UT\\
243fR&UThbZlP\36Zl am^*al*_*a_" "cR\234^XoRbThcR]W|" "TP!mX|VRt`|XU)R>VVmZRm*a|_aVl\
'SJ*bZ'la|Z bW`cVl^UP\vP\bVmZa" "P@URRThcR8YXoP\26*a" "_R[SJ*b|\"V``8``*cRK'P95{ 7{"
" ={ y; { |{ V RK9} 'V'|","TYi\\T\377oP\260XTBl'QMzT_Pq" "{ TcPk{" " ToPe{ TsP_{ PJ{ ,TWhPS{ PJ{ \
T:XPXT:'POP\fZ8aaUaSJ`oQNTKgz(P5{ XP0{ X#P*{ ZQITOb,oZTBl" "UQORi" "UQLT@bzPPP\n{ PJ{ U@P<{ UAP6{"
" PJ{ U?P,{ PJ{ UBP\""} ; long t,s,C; int main( int c,char **g){ char unsigned*r=!v?v=g,"C":c[47
+g]; long S=s,T=t; if(!C)while(c=*r){ short z=s,w=t,q=*++r- 72; c-=32>c?6:79; if(0>c)main(c,
E); else{ r+=6>c; if(C)C=c-44||t--; else{ { if(c>4&&16>c)s=t ; L=t[q[E]]; L; r+=q; L>>=q; L; r
+=q*!t; L<<=q; L=q; L=T; L=*y--; L=x-m; L=*x++; L=1; L=S; L=-1 ; L; J=m+t; L=k-J; L=0; L=t[m]; L--
; L++; L+=L-=L=z*w; L=z/w; L=z<w; L&=L|=L=1<<t; L; y=k; L; k=y; L[m]=L; x=t+m; L; k=t+J; L; T=t; S=L=t[k]; L[k
]=L=!t; L; if(t)exit(0); L=open(v[t],0); L=creat(v[t],384); L; close(t); L=read(t,x,s); L=write(t,x,s); L=t<0?
srand(-t),0:rand()%t+1; L; C=t--; L; break; L; *++y=t; L; break; } } } } { { { } ; { } { } { ; } { } } } { } }
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env bash
#
# try.alt.sh - demonstrate alternate 2024/mills
# 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.
#
[[ -z "$CC" ]] && CC="cc"
# make sure the program has been built
#
make CC="$CC" alt >/dev/null || exit 1
# clear the screen
#
clear
# admire the source
#
read -r -n 1 -p "Press any key to admire the source code: "
echo 1>&2
echo 1>&2
cat prog.alt.c 1>&2
echo 1>&2
# select a game
#
read -r -n 1 -p "Press any key to when ready: "
export SELECT=""
while [[ -z $SELECT ]]; do
export NAME=""
export Z3=""
export SAVE=""
echo 1>&2
echo 'Select a game (if in doubt try 0 or 1 first):' 1>&2
echo 1>&2
echo ' 0 minizork - Demo version of the original Zork' 1<&2
echo ' 1 advent - Colossal Cave Adventure' 1>&2
echo ' 2 curses - Hunting about in the attic of your family home' 1>&2
echo ' 3 fantasydimension - Fantasy world adventure via an enigmatic airlock' 1>&2
echo ' 4 moonglow - Spacecraft lands in a nearby corn field' 1>&2
echo ' 5 submarine-sabotage - Serving aboard top-secret Puny class submarine' 1>&2
echo ' 6 tristam - Surviving on Tristam island after a crash' 1>&2
echo ' 7 sampler1_R55 - 1984 Infocom interactive fiction tutorial with 4 game samples' 1>&2
echo ' 8 sampler2 - 1997 Infocom interactive fiction tutorial with 3 game samples' 1>&2
echo ' 9 ((Enter a z3 filename))' 1>&2
# *.z3
echo 1>&2
echo ' NOTE: For 9: Search and download a .z3 file from: https://ifdb.org/#games' 1>&2
echo ' After entering 9, give the path to the .z3 file you downloaded.' 1>&2
echo 1>&2
echo ' q Quit without running a game' 1>&2
echo 1>&2
read -r -n 1 -p "Enter your selection: " SELECT
echo 1>&2
echo 1>&2
# validate prompt
#
case "$SELECT" in
0) NAME="minizork" ;;
1) NAME="advent" ;;
2) NAME="curses-r10" ;;
3) NAME="fantasydimension" ;;
4) NAME="submarine-sabotage" ;;
5) NAME="moonglow" ;;
6) NAME="tristam" ;;
7) NAME="sampler1_R55" ;;
8) NAME="sampler2" ;;
9) NAME="//tbd//" ;;
q) exit 0 ;;
Q) exit 0 ;;
*) echo 'ERROR: invalid selection, try again' 1>&2
SELECT="" # ask for a different selection
continue ;;
esac
# case: enter z3 file path
#
if [[ $NAME == "//tbd//" ]]; then
read -r -p "Enter path to a z3 file: " Z3
echo 1>&2
echo 1>&2
NAME=$(basename "$Z3" .z3)
SAVE="$NAME.sav"
# else: form save filename and Z3 filename
#
else
Z3="$NAME.z3"
SAVE="$NAME.sav"
fi
# Z3 file must be a readable non-empty z3 file
#
if [[ ! -e $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 file does not exist: $Z3" 1>&2
echo 1>&2
continue
fi
if [[ ! -f $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a file: $Z3" 1>&2
echo 1>&2
continue
fi
if [[ ! -r $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a readable file: $Z3" 1>&2
echo 1>&2
continue
fi
if [[ ! -s $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a non-empty readable file: $Z3" 1>&2
echo 1>&2
continue
fi
# SAVE must be a writable file
#
if [[ ! -e $SAVE ]]; then
touch "$SAVE"
select="$?"
if [[ $select -ne 0 || ! -f $SAVE ]]; then
SELECT="" # ask for a different selection
echo "ERROR: cannot create save file: $SAVE" 1>&2
echo 1>&2
continue
fi
fi
if [[ ! -f $SAVE ]]; then
SELECT="" # ask for a different selection
echo "ERROR: save is not a file: $SAVE" 1>&2
echo 1>&2
continue
fi
if [[ ! -w $SAVE ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a writble file: $SAVE" 1>&2
echo 1>&2
continue
fi
done
# run the game
#
echo 'Please note these general commands:' 1>&2
echo 1>&2
echo ' quit exit the game (be sure to save first!)' 1>&2
echo ' save save game state to file (2nd arg)' 1>&2
echo ' restore restore game state from file (2nd arg)' 1>&2
echo 1>&2
read -r -n 1 -p "Press any key to run ./prog.alt $Z3 $SAVE: "
clear
./prog.alt "$Z3" "$SAVE"
echo 1>&2
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env bash
#
# try.sh - demonstrate 2024/mills
# 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.
#
[[ -z "$CC" ]] && CC="cc"
# make sure the program has been built
#
make CC="$CC" all >/dev/null || exit 1
# clear the screen
#
clear
# admire the source
#
read -r -n 1 -p "Press any key to admire the source code: "
echo 1>&2
echo 1>&2
cat prog.c 1>&2
echo 1>&2
# select a game
#
read -r -n 1 -p "Press any key to when ready: "
export SELECT=""
while [[ -z $SELECT ]]; do
export NAME=""
export Z3=""
export SAVE=""
echo 1>&2
echo 'Select a game (if in doubt try 0 or 1 first):' 1>&2
echo 1>&2
echo ' 0 minizork - Demo version of the original Zork' 1<&2
echo ' 1 advent - Colossal Cave Adventure' 1>&2
echo ' 2 curses - Hunting about in the attic of your family home' 1>&2
echo ' 3 fantasydimension - Fantasy world adventure via an enigmatic airlock' 1>&2
echo ' 4 moonglow - Spacecraft lands in a nearby corn field' 1>&2
echo ' 5 submarine-sabotage - Serving aboard top-secret Puny class submarine' 1>&2
echo ' 6 tristam - Surviving on Tristam island after a crash' 1>&2
echo ' 7 sampler1_R55 - 1984 Infocom interactive fiction tutorial with 4 game samples' 1>&2
echo ' 8 sampler2 - 1997 Infocom interactive fiction tutorial with 3 game samples' 1>&2
echo ' 9 ((Enter a z3 filename))' 1>&2
# *.z3
echo 1>&2
echo ' NOTE: For 9: Search and download a .z3 file from: https://ifdb.org/#games' 1>&2
echo ' After entering 9, give the path to the .z3 file you downloaded.' 1>&2
echo 1>&2
echo ' q Quit without running a game' 1>&2
echo 1>&2
read -r -n 1 -p "Enter your selection: " SELECT
echo 1>&2
echo 1>&2
# validate prompt
#
case "$SELECT" in
0) NAME="minizork" ;;
1) NAME="advent" ;;
2) NAME="curses-r10" ;;
3) NAME="fantasydimension" ;;
4) NAME="submarine-sabotage" ;;
5) NAME="moonglow" ;;
6) NAME="tristam" ;;
7) NAME="sampler1_R55" ;;
8) NAME="sampler2" ;;
9) NAME="//tbd//" ;;
q) exit 0 ;;
Q) exit 0 ;;
*) echo 'ERROR: invalid selection, try again' 1>&2
SELECT="" # ask for a different selection
continue ;;
esac
# case: enter z3 file path
#
if [[ $NAME == "//tbd//" ]]; then
read -r -p "Enter path to a z3 file: " Z3
echo 1>&2
echo 1>&2
NAME=$(basename "$Z3" .z3)
SAVE="$NAME.sav"
# else: form save filename and Z3 filename
#
else
Z3="$NAME.z3"
SAVE="$NAME.sav"
fi
# Z3 file must be a readable non-empty z3 file
#
if [[ ! -e $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 file does not exist: $Z3" 1>&2
echo 1>&2
continue
fi
if [[ ! -f $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a file: $Z3" 1>&2
echo 1>&2
continue
fi
if [[ ! -r $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a readable file: $Z3" 1>&2
echo 1>&2
continue
fi
if [[ ! -s $Z3 ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a non-empty readable file: $Z3" 1>&2
echo 1>&2
continue
fi
# SAVE must be a writable file
#
if [[ ! -e $SAVE ]]; then
touch "$SAVE"
select="$?"
if [[ $select -ne 0 || ! -f $SAVE ]]; then
SELECT="" # ask for a different selection
echo "ERROR: cannot create save file: $SAVE" 1>&2
echo 1>&2
continue
fi
fi
if [[ ! -f $SAVE ]]; then
SELECT="" # ask for a different selection
echo "ERROR: save is not a file: $SAVE" 1>&2
echo 1>&2
continue
fi
if [[ ! -w $SAVE ]]; then
SELECT="" # ask for a different selection
echo "ERROR: z3 is not a writble file: $SAVE" 1>&2
echo 1>&2
continue
fi
done
# run the game
#
echo 'Please note these general commands:' 1>&2
echo 1>&2
echo ' quit exit the game (be sure to save first!)' 1>&2
echo ' save save game state to file (2nd arg)' 1>&2
echo ' restore restore game state from file (2nd arg)' 1>&2
echo 1>&2
read -r -n 1 -p "Press any key to run ./prog $Z3 $SAVE: "
clear
./prog "$Z3" "$SAVE"
echo 1>&2