Adventuring into Fortran

I wrote a Fortran IV-to-C translator in order to re-experience Adventure as though it were still the late 1970s.

This is a personal project, but I’ve moved it to a public Github repository on the slight chance anyone here is interested.

There are many ports of Adventure that are playable today. (In fact, there are far more than I realized five weeks ago when I embarked on this project.) As heroic as some of those efforts are, every one I tried altered the experience in at least one way.

  • Mixed-case text, visible prompts, a status bar, etc. These are simply cosmetic changes, but they always put me on alert because they indicate that there are likely other changes.
  • Corrected spelling and grammar. I want to re-experience the game with all the warts.
  • Extensions. I want to play the WOOD0350v2 version, but some ports are based on versions that had extended maps and extra puzzles.
  • Bugs. In particular, bugs that affect navigation are a particular pet peeve of mine. Adventure itself has some mistakes in the travel table, but some ports have introduced subtle bugs.
  • Elimination of cave hours and wizard mode. True, this doesn’t fit a modern computing environment, and it’s not part of the game, but I wanted to re-experience it.

I started out with the intent of making a Fortran IV interpreter but pivoted to making a translator because … reasons.

And, to be clear, I didn’t set out to make a tool that completely understands all of Fortran IV (as implemented for the PDP-10). Adventure uses only a fraction of the language, so the plan was to implement just that fraction, which made the project much more tractable.

I didn’t really know any version of Fortran before I started, so I’ve learned a lot along the way.

So anyway, I’ve got a modern C++ program that reads the Fortran source code and spits out a C translation. The translation is not pretty, but it should be perfectly portable C11.

Right now it handles WOOD0350v2 (and v1 as of yesterday).

I’m looking to see whether I can extend the translator to handle CROW0000 as well. The challenge there is the use of a system-provided floating point random number generator. A simplification I’d baked into the translator was that it wouldn’t have to handle REAL (or DOUBLE or COMPLEX). The Woods versions used an integer-based linear congruential random number generator.

10 Likes

Looks really cool. Trying to compile with g++, i get:

fatal error: format: No such file or directory
    9 | #include <format>

Looks cool!

I wrote an ultra-conservative Rust port of a very early version.

It’s listed as CRAW0000 on the Adventure family tree:

Source is here:

I kept the code organized as much like the Fortran code as possible to avoid accidentally introducing differences in behavior. There are only two differences I know of:

  1. I print an obviously new message instead of crashing when moving south from the swiss cheese room.
  2. There was a subtle invalid index bug dealing with dwarves. It had no visible symptoms in Fortran, but Rust would panic. I adjusted the math on one line slightly to avoid it.

While this is an extremely early version, I have thought about tackling a more “recent” one someday.

6 Likes
fatal error: format: No such file or directory
    9 | #include <format>

You need the command line option to tell the compiler that the translator uses C++20. For gcc and clang, I think that’s -std=c++20. The MSVC project uses /std:c++latest.

That’s just for the translator, by the way. The code generated by the translator is C11.

1 Like

The WOOD0350 versions have an out of bounds index right at the beginning of initialization. It accesses one element before the beginning of an array (offhand, I don’t remember which). I’d be surprised if that’s not also in CROW0000.

If it were, it would’ve crashed on Rust (which prevents indexing out of bounds) unless I made a mistake in translation that also happened to correct it. That seems pretty unlikely.

Thanks. Looks like my gcc is too old. I upgraded to 13.2 but not good enough. <format> is now present, but <print> isn’t. I think that’s a gcc 14 thing.

Looks like your c++ is too new for the old code :slight_smile:

Very nice! I’m going to follow along. Fortran was my first programming language in in 1970 or so, punch cards and all. At this point, I can hardly spell Fortran…

I upgraded to 13.2 but not good enough. <format> is now present, but <print> isn’t. I think that’s a gcc 14 thing.

Ugh. I forgot <format> and <print> didn’t come in the same standards update. So, yeah, the translator requires -std:c++23. Would it work with gcc 13.2? I don’t know.

1 Like

I read that 14 is needed for 23.