Commits

catseye  committed cf56674

Initial import of REDGREEN version 1.0 revision 2007.0503 sources.

  • Participants
  • Tags rel_1_0_2007_0503

Comments (0)

Files changed (9)

File doc/redgreen.html

+<html><head>
+    <meta http-equiv="Content-Type" content="text/html;CHARSET=iso-8859-1">
+    <meta name="Description" content="Cat's Eye Technologies: The REDGREEN Cellular Automaton">
+    <title>Cat's Eye Technologies: The REDGREEN Cellular Automaton</title>
+</head>
+<body>
+<h1>REDGREEN</h1>
+
+<h2>Cellular Automaton</h2>
+
+<p>REDGREEN is a successor to <a href="/projects/rube/">RUBE</a>.
+REDGREEN is a true cellular automaton (CA) and written in a much clearer language
+in which to express CA's, <a href="/projects/alpaca/">ALPACA</a>.
+REDGREEN is an extremely complex automaton, making full use of
+ALPACA's "class of states" feature.</p>
+
+<h2>Implementation</h2>
+
+<p>You can download the ALPACA v0.90
+distribution from this web server.
+It contains the ALPACA compiler, of which REDGREEN is one of the
+example CA descriptions.</p>
+
+<h2>The REDGREEN Universe</h2>
+
+<table>
+<tr><td>Air</td><td>		 	&nbsp;</td><td>
+  Heavy things like water and pebbles fall through air.
+  Light things like smoke and steam rise in air.
+  Air is required for a fire to keep burning.
+</td></tr>
+
+<tr><td>Water</td><td>		<b><tt>~</tt></b></td><td>
+  Heavy solid things like pebbles fall into water.
+  Light things like steam or smoke make rising bubbles in water.
+  Boils to steam when heated, but also puts out open fires.
+  Fish can live a John Conway's Life in water.
+</td></tr>
+
+<tr><td>Fire</td><td>		<b><tt>%</tt></b></td><td>
+  Heavy things like pebbles fall through fire; water puts it out.
+  Requires flammable fuel and air to keep burning, otherwise
+  goes up in smoke.  Spreads to adjacent flammables like twigs
+  and heats up adjacent inflammables like rock.
+</td></tr>
+
+<tr><td>Earth</td><td>		<b><tt>#</tt></b></td><td>
+  Stops things which would otherwise fall from falling.  Can be
+  heated up to magma by adjacent fire.
+</td></tr>
+
+
+<tr><td>Magma</td><td>		<b><tt>&</tt></b></td><td>
+  Heated-up earth, will cool down to earth if no adjacent fire or
+  magma is present.  Can boil water.
+</td></tr>
+
+<tr><td>Steam</td><td>		<b><tt>s</tt></b></td><td>
+  From boiling water, rises in air.
+</td></tr>
+
+<tr><td>Smoke</td><td>		<b><tt>@</tt></b></td><td>
+  From fire, rises in air.
+</td></tr>
+
+<tr><td>Bubble</td><td>		<b><tt>o</tt></b></td><td>
+  From air or steam or smoke, rises in water.
+</td></tr>
+
+<tr><td>Fish</td><td>		<b><tt>f</tt></b></td><td>
+  Lives a <A HREF="/projects/alpaca/eg/life/">John Conway's Life</a> in water.
+</td></tr>
+
+<tr><td>Pebble</td><td>		<b><tt>.</tt></b></td><td>
+  Falls through air.
+</td></tr>
+
+<tr><td>Two Pebbles</td><td>		<b><tt>:</tt></b></td><td>
+  Two pebbles stacked together, also falls through air.
+</td></tr>
+
+<tr><td>Spark</td><td>		<b><tt>*</tt></b></td><td>
+  An electrical phenomenon living a <A HREF="/projects/alpaca/eg/wireworld/">WireWorld</a> existance.
+</td></tr>
+
+<tr><td>Tail</td><td>		<b><tt>-</tt></b></td><td>
+  The trail of a spark.
+</td></tr>
+
+<tr><td>Wire</td><td>		<b><tt>=</tt></b></td><td>
+  Conducts electricity (sparks).
+</td></tr>
+
+<tr><td>Zappy</td><td>		<b><tt>z</tt></b></td><td>
+  Shot off by sparks.  Can set flammables on fire.
+</td></tr>
+
+<tr><td>Big Zappy</td><td>		<b><tt>Z</tt></b></td><td>
+  Also shot off by sparks.  Can also set flammables on fire.
+</td></tr>
+
+<tr><td>Duct Tape</td><td>		<b><tt>D</tt></b></td><td>
+  Flammable.  Things can stick to it.  It can unravel.
+</td></tr>
+
+<tr><td>"Oh No" Tape</td><td>		<b><tt>O</tt></b></td><td>
+  Flammable.  Duct tape that's unravelling.
+</td></tr>
+
+<tr><td>Twig</td><td>		<b><tt>l</tt></b></td><td>
+  Flammable.
+</td></tr>
+
+<tr><td>Conveyor Left</td><td>		<b><tt>&lt;</tt></b></td><td>
+  Moves twigs, pebbles etc. on top of it to the left.
+</td></tr>
+
+<tr><td>Conveyor Right</td><td>		<b><tt>&gt;</tt></b></td><td>
+  Moves twigs, pebbles etc. on top of it to the right.
+</td></tr>
+
+<tr><td>Randomizer</td><td>		<b><tt>?</tt></b></td><td>
+  Randomly flips the direction of the Conveyor adjacent
+  above it.
+</td></tr>
+
+<tr><td>Torch</td><td>		<b><tt>T</tt></b></td><td>
+  Provides endless fuel for a fire.
+</td></tr>
+
+</table>
+
+</body></html>

File eg/convey.red

+
+
+                                                         l l : . l
+
+
+
+
+<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~f~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~f~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~f~~~f~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ffff~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~ff~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~f~f~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~f~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
+  ####################################################
+

File eg/pyramid.red

+             .
+                    
+                    
+                    
+             >      
+             ?      
+                    
+            > >     
+            ? ?     
+                    
+           > > >    
+           ? ? ?    
+                    
+          > > > >   
+          ? ? ? ?   
+                    
+         > > > > >  
+         ? ? ? ? ?  
+                    
+       # # # # # # #
+       #############

File eg/steam.red

+
+                                   # #
+                 ......            # #
+                                   #  ~                      #
+                                   #######################   #
+                                  %#                         #
+                       . . .      T #####                    #
+                                  ###   #  :                 #
+                                        #                    #
+                                        #  .                 #
+                                        #                    #
+                                        #                    #
+                                        #  .                 #
+                                        #                    #
+                                        #                    #
+>>>>>>>>>>>>>>>##<<<<<<<<<<<<<<<<<############################
+                                                %
+                                                T
+
+
+
+    ====*-=====================*======
+    =                                =
+    ===-*======================*======
+    =                                                 llll
+    =        ===                                     lllll
+    =       =   =                                     llll
+     =      =  = <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+      =     = =
+       =     =
+        =====
+

File script/redgreen.bat

+@echo off
+perl src\redgreen.pl src\%1.red

File script/redgreen.pl

+#!/usr/bin/perl
+# eg/redgreen/script/redgreen.pl - automatically generated from eg/redgreen/src/redgreen.alp by:
+# alpaca.pl v0.93
+# http://catseye.webhop.net/projects/alpaca/
+######################################################
+
+use Alpaca qw(true false guess
+	      adjacent_state adjacent_class
+	      load_playfield display_playfield process_playfield);
+
+sub FallableClassRules {
+  return 'Air' if ((not SupportClassMember($Playfield->[$x][$y+1])) and (adjacent_state('Air') >= 2) and (not (adjacent_state('DuctTape') >= 1)));
+  return 'Water' if ((not SupportClassMember($Playfield->[$x][$y+1])) and (adjacent_state('Water') >= 4) and (not (adjacent_state('DuctTape') >= 1)));
+  return $Playfield->[$x][$y] if (($Playfield->[$x][$y+1] eq 'ConveyorLeft' and (not PassthruClassMember($Playfield->[$x-1][$y]))) or ($Playfield->[$x][$y+1] eq 'ConveyorRight' and (not PassthruClassMember($Playfield->[$x+1][$y]))));
+  return 0
+ };
+
+sub PassthruClassRules {
+  return $Playfield->[$x][$y-1] if (FallableClassMember($Playfield->[$x][$y-1]));
+  return $Playfield->[$x+1][$y] if (FallableClassMember($Playfield->[$x+1][$y]) and $Playfield->[$x+1][$y+1] eq 'ConveyorLeft');
+  return $Playfield->[$x-1][$y] if (FallableClassMember($Playfield->[$x-1][$y]) and $Playfield->[$x-1][$y+1] eq 'ConveyorRight');
+  return 0
+ };
+
+sub FlammableClassRules {
+  return 'Fire' if ((adjacent_class(\&BurnerClassMember) >= 1));
+  return 0
+ };
+
+sub SteamyClassRules {
+  return 'Water' if ($Playfield->[$x-1][$y] eq 'Water' or $Playfield->[$x+1][$y] eq 'Water' or $Playfield->[$x-1][$y-1] eq 'Water' or $Playfield->[$x+1][$y-1] eq 'Water' or $Playfield->[$x][$y-1] eq 'Water');
+  return 'Air' if (1);
+  return 0
+ };
+
+sub BurnerClassRules {
+  return 0
+ };
+
+sub SupportClassRules {
+  return 0
+ };
+
+sub AirStateRules {
+  return 'Water' if ($Playfield->[$x][$y-1] eq 'Water' or $Playfield->[$x-1][$y-1] eq 'Water' or $Playfield->[$x+1][$y-1] eq 'Water' or ($Playfield->[$x-1][$y] eq 'Water' and SupportClassMember($Playfield->[$x-1][$y+1])) or ($Playfield->[$x-1][$y] eq 'Water' and $Playfield->[$x-1][$y+1] eq 'Water' and $Playfield->[$x][$y+1] eq 'Water') or ($Playfield->[$x+1][$y] eq 'Water' and SupportClassMember($Playfield->[$x+1][$y+1])) or ($Playfield->[$x+1][$y] eq 'Water' and $Playfield->[$x+1][$y+1] eq 'Water' and $Playfield->[$x][$y+1] eq 'Water'));
+  return 'Steam' if ($Playfield->[$x][$y+1] eq 'Steam' or $Playfield->[$x-1][$y+1] eq 'Steam' or $Playfield->[$x+1][$y+1] eq 'Steam');
+  return 'Smoke' if ($Playfield->[$x][$y+1] eq 'Smoke' or $Playfield->[$x-1][$y+1] eq 'Smoke' or $Playfield->[$x+1][$y+1] eq 'Smoke');
+  return 'Zappy' if ((adjacent_state('Spark') >= 1));
+  return PassthruClassRules() || 'Air'
+ };
+
+sub WaterStateRules {
+  return 'Steam' if ((adjacent_state('Fire') >= 1) or (adjacent_state('Magma') >= 1));
+  return 'Bubble' if ($Playfield->[$x][$y+1] eq 'Bubble' or $Playfield->[$x][$y+1] eq 'Smoke' or $Playfield->[$x][$y+1] eq 'Steam');
+  return 'Fish' if ((adjacent_state('Fish') >= 3) and (adjacent_state('Water') >= 5));
+  return PassthruClassRules() || 'Water'
+ };
+
+sub FireStateRules {
+  return 'Smoke' if ((adjacent_state('Water') >= 1) or (not (adjacent_state('Air') >= 1)) or ((not (adjacent_state('Torch') >= 1)) and (not (adjacent_state('DuctTape') >= 1)) and (not (adjacent_state('Twig') >= 1))));
+  return PassthruClassRules() || BurnerClassRules() || 'Fire'
+ };
+
+sub EarthStateRules {
+  return 'Magma' if ((adjacent_state('Fire') >= 1));
+  return SupportClassRules() || 'Earth'
+ };
+
+sub MagmaStateRules {
+  return 'Earth' if ((not (adjacent_state('Fire') >= 1)) and (not (adjacent_state('Magma') >= 2)));
+  return SupportClassRules() || BurnerClassRules() || 'Magma'
+ };
+
+sub SteamStateRules {
+  return PassthruClassRules() || SteamyClassRules() || 'Steam'
+ };
+
+sub SmokeStateRules {
+  return PassthruClassRules() || SteamyClassRules() || 'Smoke'
+ };
+
+sub BubbleStateRules {
+  return PassthruClassRules() || SteamyClassRules() || 'Bubble'
+ };
+
+sub FishStateRules {
+  return 'Air' if ((not (adjacent_state('Water') >= 1)));
+  return 'Water' if ((adjacent_state('Fish') >= 4) or (adjacent_state('Water') >= 7));
+  return 'Fish'
+ };
+
+sub OnePebbleStateRules {
+  return 'TwoPebble' if ($Playfield->[$x][$y-1] eq 'OnePebble' and (SupportClassMember($Playfield->[$x][$y+1])));
+  return FallableClassRules() || 'OnePebble'
+ };
+
+sub TwoPebbleStateRules {
+  return FallableClassRules() || SupportClassRules() || 'TwoPebble'
+ };
+
+sub SparkStateRules {
+  return 'Tail' if (1);
+  return SupportClassRules() || BurnerClassRules() || 'Spark'
+ };
+
+sub TailStateRules {
+  return 'Wire' if (1);
+  return SupportClassRules() || 'Tail'
+ };
+
+sub WireStateRules {
+  return 'Spark' if ((adjacent_state('Spark') >= 1) and (not (adjacent_state('Spark') >= 4)));
+  return SupportClassRules() || 'Wire'
+ };
+
+sub DuctTapeStateRules {
+  return 'UnravelTape' if (((not (adjacent_state('DuctTape') >= 2))) or ((not ((adjacent_state('DuctTape') >= 1) and (adjacent_class(\&SupportClassMember) >= 1)))));
+  return SupportClassRules() || FlammableClassRules() || 'DuctTape'
+ };
+
+sub UnravelTapeStateRules {
+  return FallableClassRules() || FlammableClassRules() || 'UnravelTape'
+ };
+
+sub TwigStateRules {
+  return FallableClassRules() || SupportClassRules() || FlammableClassRules() || 'Twig'
+ };
+
+sub ZappyStateRules {
+  return 'BigZappy' if (1);
+  return PassthruClassRules() || 'Zappy'
+ };
+
+sub BigZappyStateRules {
+  return 'Air' if (1);
+  return PassthruClassRules() || 'BigZappy'
+ };
+
+sub RandomizerStateRules {
+  return SupportClassRules() || 'Randomizer'
+ };
+
+sub ConveyorLeftStateRules {
+  return 'ConveyorRight' if ($Playfield->[$x][$y+1] eq 'Randomizer' and guess());
+  return 'ConveyorLeft'
+ };
+
+sub ConveyorRightStateRules {
+  return 'ConveyorLeft' if ($Playfield->[$x][$y+1] eq 'Randomizer' and guess());
+  return 'ConveyorRight'
+ };
+
+sub TorchStateRules {
+  return 'Torch'
+ };
+
+sub BurnerClassMember {
+  return $_[0] eq 'Fire' ||
+         $_[0] eq 'Magma' ||
+         $_[0] eq 'Spark' ||
+         0
+};
+
+sub FallableClassMember {
+  return $_[0] eq 'OnePebble' ||
+         $_[0] eq 'TwoPebble' ||
+         $_[0] eq 'UnravelTape' ||
+         $_[0] eq 'Twig' ||
+         0
+};
+
+sub FlammableClassMember {
+  return $_[0] eq 'DuctTape' ||
+         $_[0] eq 'UnravelTape' ||
+         $_[0] eq 'Twig' ||
+         0
+};
+
+sub PassthruClassMember {
+  return $_[0] eq 'Air' ||
+         $_[0] eq 'Water' ||
+         $_[0] eq 'Fire' ||
+         $_[0] eq 'Steam' ||
+         $_[0] eq 'Smoke' ||
+         $_[0] eq 'Bubble' ||
+         $_[0] eq 'Zappy' ||
+         $_[0] eq 'BigZappy' ||
+         0
+};
+
+sub SteamyClassMember {
+  return $_[0] eq 'Steam' ||
+         $_[0] eq 'Smoke' ||
+         $_[0] eq 'Bubble' ||
+         0
+};
+
+sub SupportClassMember {
+  return $_[0] eq 'Earth' ||
+         $_[0] eq 'Magma' ||
+         $_[0] eq 'TwoPebble' ||
+         $_[0] eq 'Spark' ||
+         $_[0] eq 'Tail' ||
+         $_[0] eq 'Wire' ||
+         $_[0] eq 'DuctTape' ||
+         $_[0] eq 'Twig' ||
+         $_[0] eq 'Randomizer' ||
+         0
+};
+
+$Appearance = {
+  'Air' => ' ',
+  'BigZappy' => 'Z',
+  'Bubble' => 'o',
+  'ConveyorLeft' => '<',
+  'ConveyorRight' => '>',
+  'DuctTape' => 'D',
+  'Earth' => '#',
+  'Fire' => '%',
+  'Fish' => 'f',
+  'Magma' => '&',
+  'OnePebble' => '.',
+  'Randomizer' => '?',
+  'Smoke' => '@',
+  'Spark' => '*',
+  'Steam' => 's',
+  'Tail' => '-',
+  'Torch' => 'T',
+  'Twig' => 'l',
+  'TwoPebble' => ':',
+  'UnravelTape' => 'O',
+  'Water' => '~',
+  'Wire' => '=',
+  'Zappy' => 'z',
+
+};
+
+$InputCodec = {
+  ' ' => 'Air',
+  'Z' => 'BigZappy',
+  'o' => 'Bubble',
+  '<' => 'ConveyorLeft',
+  '>' => 'ConveyorRight',
+  'D' => 'DuctTape',
+  '#' => 'Earth',
+  '%' => 'Fire',
+  'f' => 'Fish',
+  '&' => 'Magma',
+  '.' => 'OnePebble',
+  '?' => 'Randomizer',
+  '@' => 'Smoke',
+  '*' => 'Spark',
+  's' => 'Steam',
+  '-' => 'Tail',
+  'T' => 'Torch',
+  'l' => 'Twig',
+  ':' => 'TwoPebble',
+  'O' => 'UnravelTape',
+  '~' => 'Water',
+  '=' => 'Wire',
+  'z' => 'Zappy',
+
+};
+
+$StateRule = {
+  'Air' => \&main::AirStateRules,
+  'BigZappy' => \&main::BigZappyStateRules,
+  'Bubble' => \&main::BubbleStateRules,
+  'ConveyorLeft' => \&main::ConveyorLeftStateRules,
+  'ConveyorRight' => \&main::ConveyorRightStateRules,
+  'DuctTape' => \&main::DuctTapeStateRules,
+  'Earth' => \&main::EarthStateRules,
+  'Fire' => \&main::FireStateRules,
+  'Fish' => \&main::FishStateRules,
+  'Magma' => \&main::MagmaStateRules,
+  'OnePebble' => \&main::OnePebbleStateRules,
+  'Randomizer' => \&main::RandomizerStateRules,
+  'Smoke' => \&main::SmokeStateRules,
+  'Spark' => \&main::SparkStateRules,
+  'Steam' => \&main::SteamStateRules,
+  'Tail' => \&main::TailStateRules,
+  'Torch' => \&main::TorchStateRules,
+  'Twig' => \&main::TwigStateRules,
+  'TwoPebble' => \&main::TwoPebbleStateRules,
+  'UnravelTape' => \&main::UnravelTapeStateRules,
+  'Water' => \&main::WaterStateRules,
+  'Wire' => \&main::WireStateRules,
+  'Zappy' => \&main::ZappyStateRules,
+
+};
+
+load_playfield($ARGV[0]);
+
+display_playfield();
+
+while (!$done)
+{
+  process_playfield();
+  display_playfield();
+}
+
+exit(0);
+
+### END ###

File src/redgreen.alp

+/*
+ * REDGREEN.ALP - REDGREEN description in ALPACA
+ * v0.60 Jul 28 1998 Chris Pressey
+ * Added BSD License May 3 2007
+ */
+
+/*
+ * Copyright (c)2007 Chris Pressey, Cat's Eye Technologies.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright
+ *      notices, this list of conditions and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above copyright
+ *      notices, this list of conditions, and the following disclaimer in
+ *      the documentation and/or other materials provided with the
+ *      distribution.
+ *   3. Neither the names of the copyright holders nor the names of their
+ *      contributors may be used to endorse or promote products derived
+ *      from this software without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*** BEGIN ***/
+
+/*** CLASSES ***/
+
+class Fallable
+  to Air when not v is Support and 2 Air and not 1 DuctTape,
+  to Water when not v is Support and 4 Water and not 1 DuctTape,
+  to me when (v ConveyorLeft and not < is Passthru) or (v ConveyorRight and not > is Passthru);
+
+class Passthru
+  to ^ when ^ is Fallable,
+  to > when > is Fallable and v> ConveyorLeft,
+  to < when < is Fallable and v< ConveyorRight;
+
+class Flammable
+  to Fire when 1 is Burner;
+
+class Steamy
+  to Water when < Water or > Water or ^< Water or ^> Water or ^ Water,
+  to Air;
+
+class Burner;
+class Support;
+
+/*** STATES ***/
+
+state Air " "
+ is Passthru
+  to Water when ^ Water or ^< Water or ^> Water
+             or (< Water and v< is Support)
+             or (< Water and v< Water and v Water)
+             or (> Water and v> is Support)
+             or (> Water and v> Water and v Water),
+  to Steam when v Steam or v< Steam or v> Steam,
+  to Smoke when v Smoke or v< Smoke or v> Smoke,
+  to Zappy when 1 Spark;
+
+state Water "~"
+ is Passthru
+  to Steam when 1 Fire or 1 Magma,
+  to Bubble when v Bubble or v Smoke or v Steam,
+  to Fish when 3 Fish and 5 Water;
+
+state Fire "%"
+ is Passthru
+ is Burner
+  to Smoke when 1 Water or not 1 Air or (not 1 Torch and not 1 DuctTape and not 1 Twig);
+
+state Earth "#"
+ is Support
+  to Magma when 1 Fire;
+
+state Magma "&"
+ is Support
+ is Burner
+  to Earth when not 1 Fire and not 2 Magma;
+
+state Steam "s"
+ is Passthru
+ is Steamy;
+
+state Smoke "@"
+ is Passthru
+ is Steamy;
+
+state Bubble "o"
+ is Passthru
+ is Steamy;
+
+state Fish "f"
+  to Air when not 1 Water,
+  to Water when 4 Fish or 7 Water;
+
+state OnePebble "."
+ is Fallable
+  to TwoPebble when ^ OnePebble and (v is Support);
+
+state TwoPebble ":"
+ is Fallable
+ is Support;
+
+state Spark "*"
+ is Support
+ is Burner
+  to Tail;
+
+state Tail "-"
+ is Support
+  to Wire;
+
+state Wire "="
+ is Support
+  to Spark when 1 Spark and not 4 Spark;
+
+state DuctTape "D"
+ is Support
+ is Flammable
+  to UnravelTape when (not 2 DuctTape) or (not (1 DuctTape and 1 is Support));
+
+state UnravelTape "O"
+ is Fallable
+ is Flammable;
+
+state Twig "l"
+ is Fallable
+ is Support
+ is Flammable;
+
+state Zappy "z"
+ is Passthru
+  to BigZappy;
+
+state BigZappy "Z"
+ is Passthru
+  to Air;
+
+state Randomizer "?"
+ is Support;
+
+state ConveyorLeft "<"
+  to ConveyorRight when v Randomizer and guess;
+
+state ConveyorRight ">"
+  to ConveyorLeft when v Randomizer and guess;
+
+state Torch "T".
+
+/*** END ***/