git @ Cat's Eye Technologies RUBE / multi-step-interactive
multi-step-interactive

Tree @multi-step-interactive (Download .tar.gz)

RUBE

Distribution version 1.6.

©1997-2014 Chris Pressey, Cat's Eye Technologies. All rights reserved. Distributed under a BSD-style license; see the file LICENSE.

What is RUBE?

RUBE is a twisted programming language in tribute to Rube Goldberg, creator of all those unique cartoon contrivances, who showed the world that anything can be done in a more complicated fashion than necessary. The RUBE programming language has some similarities to said contrivances.

Anyone who's played The Incredible Machine (and to some extent, Donkey Kong) will understand RUBE almost immediately. "Instructions" in the program interact to execute the algorithm required. I made the choice to use a "warehouse" paradigm for these interacting instructions (because this is what happens to your brain when you work at a lumberyard. Which, I submit, is far better than what happens to your brain when you go to grad school.)

The RUBE language can be described as a two-dimensional "bully automaton": like a cellular automaton, but certain state transitions force other, non-adjacent cells to assume certain states. Although this may sound like an interesting notion, the number of interactions climbs quickly as more objects do things, and things get much messier than they do in a regular ol' cellular automaton like John Conway's Game of Life. Also unlike a regular cellular automaton, RUBE supports rudimentary input and output functionality.

Examples

Because implementing an algorithm in RUBE is a clumsy job of co-ordinating concurrently operating sections of the playfield, few non-trivial RUBE programs exist. In particular, it has never to the author's knowledge been shown that RUBE is Turing-complete. On the other hand, it has never been shown that it's not.

Sadly, the ubiquitous "Hello, world!" in RUBE is a very unfriendly

4666622767662
85ccfc07f2c41
OOOOOOOOOOOOO
ccccccccccccc
=============

Or an equally ugly

(21646c726f77202c6f6c6c6548
===========================

                           O F
                           c
                           =

Language Description

A RUBE program is a two-dimensional grid of ASCII characters, or at least represented by characters drawn from the ASCII set.

Integral are the crates, 0 to f. These represent data. They also represent movable boxes which are subject to gravity, being pushed around, and conveyor belts, among other things.

Girders = are stationary parts of the program on which crates can be piled. When there's no girder directly below a crate, that crate falls.

Dozers ( and ) push crates around. Dozers are subject to gravity, and must travel on girders. Dozers turn around when there is a , in front and above them. As an interesting side effect they also replicate themselves at ,'s.

Ramps / and \\ are used for dozers to move from girder to girder.

Conveyor belts > and < carry crates along with no help needed from dozers. Note that conveyor belots do not affect dozer motion.

Winches up W and down M move crates from girder to girder.

"Swinches" move crates up V or down A and then switch states.

Gates K compare crates to a reference crate and move the crate depending on if it's less than, or more than/equal to the reference crate.

 t   | t = target crate     l = lesser crates
 K   | r = reference crate  g = greater than or equal to
lrg  |

Packers + and Unpackers - perform 4-bit arithmetic on crates:

 +      +     -      -
12  ->   3   ef  ->   1
===    ===   ===    ===

Furnaces F destroy everything one space left, right, below, and above them.

Replicators : make a copy below them of whatever is above them, usually a crate or a dozer. Special replicators ; only make copies of crates. Upside-down special replicators . work like ; but make a copy above them of what's below them.

Dozers turn around when they hit certain instructions. Crumble walls * disappear after being hit horizontally by a dozer.

Program output provides a print mechanism. If there is a c crate below the O, the value specified by the two crates above the O (if they exist) is output as an ASCII character. If there is a b crate below the O, they are output as the decimal representation, in ASCII, of the byte (numerical) value of the crates.

The following outputs a space:

2
0
O
c
=

Table of Instructions

Symbol  Name                    Bump R  Bump L  Surface Gravity

Implemented:
        space                   pass    pass    no      no
0..f    crate                   move r  move l  yes     yes
(       dozer right             move r  move l  yes     yes
)       dozer left              move r  move l  yes     yes
=       girder                  rev     rev     yes     no
F       furnace                 die     die     die     no
\       ramp                    +1 elev +1 elev yes     no
/       ramp                    +1 elev +1 elev yes     no
>       conveyor belt right     rev     rev     yes     no
<       conveyor belt left      rev     rev     yes     no
:       replicator              rev     rev     yes     no
;       special replicator      rev     rev     yes     no
.       upside down replicator  rev     rev     yes     no
,       turn signal                             no      no
*       crumble-wall            break   break   yes     no
O       output                  rev     rev     yes     no
        b       byte<-crate crate
        c       char<-crate crate
K       gate                    rev     rev     yes     no
W       winch up                rev     rev     yes     no
M       winch down              rev     rev     yes     no
V       swinch up               rev     rev     yes     no
A       swinch down             rev     rev     yes     no
+       packer                  rev     rev     yes     no
-       unpacker                rev     rev     yes     no
C       crate killer            die cr  die cr  die cr  no
D       dozer killer            die doz die doz die doz no


Planned:
I       input                   input   input   yes     no
        b       byte->crate crate
        c       char->crate crate
T       scale                   rev     rev     yes     no
|       door                    rev     rev     yes     no


Kinda Silly (extraneous to real programming):
km      monkey                  rev     rev     yes     yes
wl      weasel                  rev     rev     yes     yes
H       mulberry bush           rev     rev     yes     yes

Q       supergoo                rev     rev     yes     kinda

~       water                   wet     wet     wet     kinda
u       pontoon                 rev     rev     yes     yes (floats)
sz      electric eel            die     die     die     yes

Implementation

rube.c is the reference implementation of the RUBE programming language. In fact, it is far more "reference" than I care for -- if, in this implementation, a dozer (say) falls on another dozer while it is turning around and pushing a crate, and that combination results in only one dozer remaining there (or perhaps creates a new dozer out of nowhere for a total of three dozers), well, hey, that's what the language defines for that configuration.

The reference implementation loads the grid of instructions from an ASCII text file. Coincidentally (because I ripped off the Befunge-93 routines to write it) it's currently restricted to an 80x25 source file. However, that should not be taken as an defining limitation; the language itself imposes no bounds on the size of a RUBE playfield.