Wator is the "sharks and fish" game defined in Kee Dewdney's book,
The Armchair Universe, W.H. Freeman, 1988. Vants is a rule defined by
Chris Langton in his paper "Studying Artificial Life with Cellular
Automata" in Physica D 22, 1986, and discussed again under the name
Turmite in Kee Dewdney's Computer Recreations column in Scientific
American, September, 1989. The vants, or turmites, are free-ranging
heads of two-dimensional Turing machines.
The Wator which I show here has three species: sharks, fish and shrimp.
As it runs it generates a very loosely coupled zhabotinsky pattern. The
Vant which I show here has three species of Vants.
Below are the necessary codes for implementing these rules in the CA Lab
environment. CA Lab: Rudy Rucker's Cellular Automata Laboratory is a
PC software package availabe from Autodesk, Inc. for $59.95 and can be
ordered by phoning 1-800-525-2763. The program includes four 360K disks
and a 264 page manual. 720K 3 1/2 inch disks are included as well.
In order to run wator as shown, one must first assemble the swap.asm
file using MASM or Turbo Assembler to produce the file swap.exe.
> tasm swap
Then one use the DOS exe2bin utility to convert swap to a .com file
with suffix .cao
> exe2bin swap.asm swap.cao
Next the wator.pas must be compiled to wator.exe by using the Turbo
Pascal compiler. Note that for the compile to work, one must have
the Pascal unit camake.tpu which is supplied with CA Lab.
> tpc wator
Next one runs wator.exe a single time to produce as output the file
> wator
Then one uses a text editor to create a raw ascii file containg the
wator palette se and nes this fle wator.cac. Finally
one uses the CA Lab ca.exe driver. A good pattern to start with
here happens to be the CA Lab billbord.cap file. One can set things
in motion with a single batch-mode command line:
> ca wator billbord -b
Mutata mutandis, the same steps will produce the files turmite.cao,
vant.ca, and vant.cac. What pattern should one run the vants on? As
it turns out the states 66, 128, and 192 correspond to the three
kinds of vants, or turmites. Using the CA Lab screen editor to
put some lines of these guys down is an interesting start. Even
more interesting is to put a square of state 1 down and to put a
vant at the square's edge. The vant will grow lace on the square's
edge.
Those blindly bent on hacking CAs in non CA Lab environments may in any
case find some useful tricks in the code below.
-----------------------------------------------------------
PROGRAM Wator;
{This is a three species version of a "Sharks and Fish" world.
Wator calls a highspeed owncode, swap.cao.
Rudy Rucker, May , 1989.}
USES Camake;
{$F+} { Required for function argument to genrule. }
FUNCTION Carule(NabeAndMe,a,b,c,d,e,f,g,h,i:integer):integer;
CONST
ShrimpBreed = 8; ShrimpSterile = 12 ; ShrimpDie = 15;
FishBreed = 3; FishStarve = 5;
SharkBreed = 2; SharkStarve = 7;
VAR
Me,MeAge,MeHunger,MeShrimpAge,MeType,
Nabe,NabeAge,NabeShrimpAge:integer;
MeShrimp,MeFish,MeShark,NabeShrimp,NabeFish,NabeShark:Boolean;
BEGIN {Function}
Me :=lo(NabeAndMe);
Nabe:=hi(NabeAndMe);
MeShrimp := (Me AND 3)=1;
MeFish:= (Me AND 3)=2;
MeShark:= (Me AND 3)=3;
MeAge:= (Me SHR 2) AND 7;
MeHunger:=Me SHR 5;
MeShrimpAge:= Me SHR 2;
NabeShrimp := (Nabe AND 3)=1;
NabeFish := (Nabe AND 3)=2;
NabeShark := (Nabe AND 3)=3;
NabeAge:= (Nabe SHR 2) AND 7;
NabeShrimpAge:= Nabe SHR 2;
MeType:= Me AND 3;
CASE MeType OF
0: BEGIN
CaRule:=0;
IF NabeShrimp AND (ShrimpBreed<NabeShrimpAge) AND
(NabeShrimpAge<ShrimpSterile) THEN CaRule:=1;
IF NabeFish AND (NabeAge=FishBreed) THEN CaRule:=2;
IF NabeShark AND (NabeAge=SharkBreed) THEN CaRule:=3;
END;
1: BEGIN
IF NabeFish THEN CaRule:=0 ELSE
BEGIN
MeShrimpAge:=(MeShrimpAge+1);
IF MeAge=ShrimpDie THEN CaRule:=0 ELSE
CaRule:=((MeShrimpAge SHL 2)OR 1)AND 255;
END;
END;
2: BEGIN
IF NabeShark THEN CaRule:=0 ELSE
BEGIN
IF NabeShrimp THEN MeHunger:=0;
IF MeHunger>=FishStarve THEN CaRule:=0 ELSE
BEGIN
MeHunger:=MeHunger+1;
MeAge:=(MeAge+1)MOD (FishBreed+1);
CaRule:=((MeHunger SHL 5)OR(MeAge SHL 2)OR 2)AND 255;
END;
END;
END;
3: BEGIN
IF NabeFish THEN MeHunger:=0;
IF MeHunger>=SharkStarve THEN CaRule:=0 ELSE
BEGIN
MeHunger:=MeHunger+1;
MeAge:=(MeAge+1)MOD (SharkBreed+1);
CaRule:=((MeHunger SHL 5)OR(MeAge SHL 2)OR 3)AND 255;
END;
END;
END;
END; {Function}
BEGIN {Main}
WorldType := 13; {is wrap on. 12 is wrap off}
OCodeReq := 'swap';
PalReq := 'wator';
GenRule(CaRule)
END. {Main}
------------------------------------------------------------
;swap.asm
;First put EveryCell's eight bits in bl and put the eight
;bits of a single randomly selected neighbor into bh and use
;bx is offset into a lookup table in the .CA file generated by the
;program which calls gas.cao. This will be new EveryCell.
;Then exchange bh and bl and use this as lookup into same .CA to
;find new nabe.
;Second, after EveryCell's and nabes new cells value are computed,
;Gas swaps these two cell values.
;The rule runs its own randomizer, using Wolfram code 30.
codes segment byte
assume cs:codes
org 100h
naber proc far
mov dx,320 ;load row length counter
push si
mov si,cs:shiftregister ; reseed shiftregister at
xor si,[bp+160] ; start of row.
xor si,[bp]
or si,cs:counter
mov cs:shiftregister,si
inc cs:counter
lbyte:
mov si,cs:shiftregister ; shiftregister is a sixteen
mov ax,si ; bit 1-D CA running Wolfram
mov cx,si ; code 30. si holds C
ror ax,1 ; ax holds L, cx holds R.
rol cx,1 ; NewC = L XOR (C OR R)
or si,cx
xor si,ax ; each time we read shiftregister
mov cs:shiftregister,si ; we update it.
and si,000Eh ; even number 2 to 14
mov si,cs:nabetable[si] ; offset to NW,N,NE,W,E,SW,S,or SE
mov bh,[bp+si] ; load nabe in bh
rol bh,1 ; adjust map state
mov bl,[bp] ; get self
rol bl,1 ; adjust map state
mov ah,[bx] ; look up new EveryCell state
xchg bl,bh ; now view nabe as center
mov al,[bx] ; and look up new val for nabe
mov [bp+si],ah ; copy new to nabe in oldbuff
mov bx,di ; offset of EveryCell
mov es:[bx+si],ah ; copy new to nabe in newbuff
mov [bp],al ; copy nabe to self in oldbuff
stosb ; copy nabe to self in newbuff
inc bp ; advance along row
dec dx ; more to update?
jnz lbyte ; if yes, keep on going
pop si
ret
naber endp
nabetable dw -323,-322,-321,-1,1,321,322,323
shiftregister dw 17h
counter dw 1
codes ends
end naber
-----------------------------------------------------------
PROGRAM Vant;
{This program creates a table to be used by Turmite.CAO. We run
three kinds of virtual ants, or "vants," as Langton calls them. The
term "turmite" is from Dewdney's Sci Am column of November, 1989.
Turmite's Bit Usage:
7,6 turmite bits.
5 reserved for speed bit.
4,3,2 direction bits.
1,0 tile bits.
Turmite Nomencalture:
Cell is the cell I update, Source is its state, Target is a cell
near Cell, Sink is Target's state, Mite & Tile are new cell values
turce in bl.So against Turmite bits. If zero,
copy Source to Cell in New uffer and exit.
(1) If Sourceas nonzero Turmite bits, use diection bits to select g and load Sink in bh.
(2) Use .CA table to determine Mite state.
(3) Put Mite in Target position in New Buffer.
(4) Mask Source to get Tile and put Tile in Cell in New Buffer.
Here we have three kinds of vants.}
USES Camake;
{$F+}
FUNCTION Carule(TState,a,b,c,d,e,f,g,h,i:integer):integer;
VAR
Source,TurType,Sink,TargTile,NewTargTile,Dir,NewDir,Mite:integer;
BEGIN {Function}
Source:=TState AND $FF;
Dir:=(Source SHR 2) AND 7;
TurType:=Source SHR 6;
Sink:=TState SHR 8;
TargTile:=Sink AND 1;
Mite:=0;
CASE TurType OF
1:
BEGIN
CASE TargTile OF
0: BEGIN
NewDir:=(Dir+2)MOD 8;
NewTargTile:=1;
END;
1: BEGIN
NewDir:=(Dir+6)MOD 8;
NewTargTile:=0;
END;
END;
Mite:=(TurType SHL 6)OR(NewDir SHL 2)OR NewTargTile;
END;
2:
BEGIN
CASE TargTile OF
0: BEGIN
NewDir:=(Dir+6)MOD 8;
NewTargTile:=1;
END;
1: BEGIN
NewDir:=(Dir+2)MOD 8;
NewTargTile:=0;
END;
END;
Mite:=(TurType SHL 6)OR(NewDir SHL 2)OR NewTargTile;
END;
3:
BEGIN
CASE TargTile OF
0: BEGIN
NewDir:=(Dir+1)MOD 8;
NewTargTile:=1;
END;
1: BEGIN
NewDir:=(Dir+7)MOD 8;
NewTargTile:=0;
END;
END;
Mite:=(TurType SHL 6)OR(NewDir SHL 2)OR NewTargTile;
END;
END;
CaRule:=Mite;
END; {Function}
BEGIN {Main}
WorldType := 13; {12 is wrap off. 13 is wrap on}
OCodeReq := 'turmite';
PalReq := 'vant';
GenRule(CaRule)
END. {Main}
----------------------------------------------------------------
;turmite.asm
;Bit Usage. 7,6 Turmite bits. 4,3,2 direction. 1,0 tile type.
;(Later I will use bit 5 for speed: 0 is normal speed, 1 is double.)
;As all non-turmite cells will have zero velocity, the state 4
;will never arise. I use this state as a "don't update" flag state.
; Cell is the cell I update, Source is its state, Target is a cell
; near Cell, Sink is Target's state, Mite & Tile are new cell values I ; compute.
;(1) Put Source in bl. If Source is 4, don't change newbuffer Cell. Exit.
;(2) Else test Source against Turmite bits. If these bits are zero,
; copy Source to Cell in new Buffer and exit.
;(3) Else Source has nonzero Turmite bits. Use direction bits to select
; Target and load Sink in bh.
;(4) If Sink is a Turmite in oldbuff or in newbuff, reverse direction of
; Source and put it in Cell.
;(5) Else use Source r ate
Moget Tile and put Tile in Cell i Old and New Buffers.
codes segment byte
assume cs:codes
org 100h
turmite proc far
mov dx,320 ;load row length counter
push si
lbyte:
xor bh,bh
mov bl,[bp] ; get right rotated Source
cmp bl,2 ; is rt rot of don't-update-state?
jne updatecell ; no, do update.
inc di ; yes,adjust for skipped stosb
jmp noupdate ; and skip it.
updatecell:
mov al,bl ; keep rt rot source read
test bl,60h ; any right rotated turmite bits?
jz loadnewcell ; no. copy Source direct.
xor al,8 ; reverse rt rot Source's direction
mov si,bx ; rt rotated Source has 432 in 321
and si,000Eh ; 2*direction in si
mov si,cs:nabetable[si] ; offset to NW,N,NE,E,SE,S,SW,or W
mov bh,[bp+si] ; right rotated Sink
test bh,60h ; is Target a turmite in oldbuff?
jnz loadnewcell ; yes, don't go there.
rol bh,1 ; unrotate Sink
rol bl,1 ; unrotate Source
mov ah,[bx] ; look up Mite
mov bx,di ; offset of Cell in newbuff
test byte ptr es:[bx+si],60h ; is Target a turmite in newbuff?
jnz loadnewcell ; yes. reversed Source to new Cell
mov es:[bx+si],ah ; put Mite in Target in newbuff
mov byte ptr [bp+si],2 ;dnt-updte-st to Target in oldbuff
and al,81h ; mask rt rotated Source to Tile
mov [bp],al ; Tile in oldbuff Cell
loadnewcell:
stosb ; Source or Tile in newbuff Cell
noupdate:
inc bp ; advance along row
dec dx ; more to update?
jnz lbyte ; if yes, keep on going
pop si
ret
turmite endp
nabetable dw -323,-322,-321,1,323,322,321,-1
;nw,n,ne,e,se,s,sw,w
;I use this order so nabetable[v XOR 8] is opposite to nabetable[v]
codes ends
end turmite
---------------------------------------------------------
Supplied below are two 256 color palettes; human readers will
probably want to quit out of the document here.
--------------------------------------------------------
;This is the 256 color wator.cap palette for showing the wator rule.
; the first three numbers in each row are the Red, Green, Blue
; intensities to use with VBA Mode 13; the fourth number is a number
; to use if all you have is CGA
3;R G B CGA
0 0 0 0 ; 0
63 0 0 1 ; 1
50 63 50 2 ; 2
50 50 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 19 2 ; 2
18 31 63 3 ; 3
0 0 0 0 ; 0
25 5 0 1 ; 1
15 63 1
---------
thats all folks
Thanks for posting Wa-tor and the Vants. By the way, last summer I
wrote a 2-species vants that is reversible (I find reversible rules
particularly interesting). It is written for both CAM and Cellsim.
It comes with Cellsim, and will be part of the new CAM's distribution
software, but if anyone on this list doesn't have a copy and would
like one, let me know.
Like most reversible rules, if you start with anything non-trivial,
entropy has its way and the CA array eventually gets very noisy, but
there is a great deal of fascinating behavior before that happens --
multiple types of gliders that move in different directions and
speeds, and even "wires" of sorts which the vants can construct and
then propagate along. I have some ideas about enhancing the rule
slightly to give more complex behavior (a simple chemistry of sorts)
and I started fiddling with it on CAM last year, but I've been too
busy to do much with it yet. I'll say something more about it when I
get time to develop it further.
> Those blindly bent on hacking CAs in non CA Lab environments may in any
> case find some useful tricks in the code below.
Well, there's no need to insult people who don't use CA Lab.
I do cellular automata work for Los Alamos Lab, and also for
Automatrix, a company that specializes in cellular automata products.
Which CA simulator I use depends on just what I'm doing. When I need
80 bits/cell (if you still want to call that a CA), I use the
Connection Machine and Cellsim. When I don't need that many bits, but
am doing a long experiment where I need to run several thousand steps
per minute while doing real-time data analysis, I use CAM. If I
needed to do lots of symbolic analysis on the CA, I'd use Mathematica.
Then there's Howard McIntosh's software, which lets you do mean field
theory and local structure theory analysis.
I hope that doesn't make me "blind" because I don't use CA Lab. I
do admit that the "owncode" feature of CA Lab is very handy, although
it's unfortunate that it has to be done in assembly language.
Disclaimer: These are my own opinions, my employers may or may not agree.
--
Dave Hiebeler Internet: hieb...@heretic.lanl.gov
Theoretical Division hieb...@turing.cs.rpi.edu
T-13 MS B213 Bitnet: userF3JL@rpitsmts
Los Alamos National Laboratory / Los Alamos, NM 87545 USA