There's more than one way to do things PerlMonks

### Evolutionary Japh

by liverpole (Monsignor)
 on Nov 14, 2006 at 19:05 UTC Need Help??

This was inspired by this obfuscation and this one, which present golfed obfuscations of Conway's Game of Life.  It seemed like a natural extension to write it in Perl/Tk, and then try to golf it down.  (It runs a little slower than it would if it were optimized for speed, which would naturally take more code).

Update 3:  You need to have Perl/Tk installed for this program to work.

```                               s''map{\$j
^=1;map{\$g{\$j}{
\$_}=1}split//}spl
it"/",\$G||="23/3";s
ub#g{\$z=pop;\$r=\\$C[
64*\$x+\$y];\$Q=\$x<0||
\$x>63||\$y<0||\$y>63?
0:\$\$r;if(\$z>=0&&\$
Q!=\$z){\$\$r=\$z;\$
M=512*\$x+

8*\$y;\$I=\$
I[\$M]and\$c->del
ete(\$I);\$I[\$M]=cr
eateOval\$c(3+8*\$x,3
+8*\$y,9+8*\$x,9+8*\$y
,-f=>\$z?"blue":\$N,o
utline=>\$N)}\$Q}use#
Tk;\$m=new#MainWin
dow(title=>\$G);
\$c=\$m->Ca

nvas(w,51                4,he,514)                ->pack;af
ter\$m(1,sub{\$N=          cget\$c(bg);@S=0          ..63;map{\$a=2+8
*\$_;@D=(2,\$a,515,        \$a);map{createLin        e\$c(@D);@D=(\$a,@D
);pop@D}7..8}@S,64;      \$F?do{open(_,\$F);ma      p{\$x=0;map{g(/@/);\$
x++}split//;++\$y;}<      _>}:map{\$x=\$_;map{\$      y=\$_;g(1>rand#4)}@S
}@S;{for\$p(@S){map{      \$q=\$_;\$t=0;for\$v(-1      ..1){map{\$x=\$p+\$_;\$
y=\$v+\$q;\$g=g(-1);\$_      ||\$v#or\$G=\$g;\$t+=\$g      ;}(-1..1)}\$N[64*\$p+
\$q]=\$g{\$G||0}{\$t-        \$G}}@S}for\$x(@S){        map{\$y=\$_;g+\$N[64
*\$x+\$_]}@S}upda          te\$m;redo}});Ma          inLoop';s#\s##g
;s&#& &g;                (\$F,\$G)=@                ARGV;eval

But wait, there's more...  If you give a single filename argument (other than "0", which is ignored), it will read the starting setup from that file, where each line (of up to 64 lines) contains up to 64 characters; '@' = living cell, and anything else is non-living.

And, if you specify a second command-line argument, it changes the rules!  This link describes the more interesting variations of the super-set of John Horton Conway's game (which can be classified as "23/3" life).

A second argument of "23/34", for example, would switch the rules to those of HighLife, whereas "34678/3678" would use the rules of Day & Night.  (You can always give a first argument of "0" to generate a random pattern instead of reading from a file).

Update:  Here's an example of a file (the pattern is called a "Gosper Glider Gun") which, when passed as the first argument to the obfuscation (eg. life.pl gg.txt), causes an never-ending stream of "gliders" to be produced:
```.......................................
.........................@.............
.......................@.@.............
.............@@......@@............@@..
............@...@....@@............@@..
.@@........@.....@...@@................
.@@........@...@.@@....@.@.............
...........@.....@.......@.............
............@...@......................
.............@@........................

And you can try different rules, sometimes with surprising results.

For example, try using the same file, but substitute the "1357/1357 = Replicator" pattern:  life.pl gg.txt 1357/1357.  The results are completely different.

Or try:  life.pl 0 2345/45678 to see the results of "Walled Cities" rule ("2345/45678"), applied to to a random pattern.

Update 2:  I can't resist adding another one that I just now tried for the first time (again, from this page).

This one is called "Diamoeba (5678/35678)", and works best with a pattern that contains many living cells close together; for example:

```................................................
................................................
................................................
................................................
................................................
................................................
................................................
................................................
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.................@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Assuming the above file is called "block.txt", you can see the results with:  life.pl block.txt 5678/35678.

s''(q.S:\$/9=(T1';s;(..)(..);\$..=substr+crypt(\$1,\$2),2,3;eg;print\$..\$/

Replies are listed 'Best First'.
Re: Evolutionary Japh
by sh1tn (Priest) on Nov 15, 2006 at 01:35 UTC
Brilliant as always ++

Re: Evolutionary Japh
by wulvrine (Friar) on Nov 20, 2006 at 14:01 UTC
Wonderfull!!
I could spend a lifetime playing with this game. ++! only because there isn't a +++!
Damn me for a fool, must...shut...down...program...........aww look how cool that looks!

s&&VALKYRIE &&& print \$_^q|!4 =+;' *|
Re: Evolutionary Japh
by NateTut (Deacon) on Nov 27, 2006 at 22:00 UTC
liverpole could you please post a "deobfuscated" version of this code? It reminds me of a little program that my son & I found fascinating: http://www.swimbots.com/. Maybe I can get him to start coding some perl instead of playing gameboy all day.

Here is the same program without the obfuscation:

```#!/usr/bin/perl -w
#
#  A "deobfuscated" version of "Evolutionary Japh"
#
#  061128 liverpole
#

+
# Strict
use strict;
use warnings;

+
# Libraries
use Tk;
use Data::Dumper;
use FileHandle;

+

+
# Global variables
my @cells;                  # Current generation of cells
my @nextgen;                # Next generation of cells
my @dimension = (0..63);    # One dimension (X or Y)
my @ids;                    # IDs of each "dot" in the canvas object
my \$off_color;              # Color of a "dead" cell (canvas backgroun
+d)
my \$on_color = "blue";      # Color of a "living" cell
my (\$x, \$y);                # Current coordinates

+

+
# Command-line
my \$filename = shift || 0;       # Pattern filename (default = random
+screen)
my \$rulename = shift || '23/3';  # Which rule? (Conway's 23/3 is defau
+lt)

+

+
# Main program

+
# Initialize the "rules hash".  After this step, using the default rul
+es,
# %rules will be:
#    {
#      '1' => { '3' => 1, '2' => 1 },
#      '0' => { '3' => 1 }
#    };
#
my \$living = 0;
my %rules = ( );    # Initialize the "rules hash"
foreach my \$digits (split('/', \$rulename)) {
# Living first (living = 1), followed by dead (living = 0)
\$living ^= 1;
foreach my \$digit (split(//, \$digits)) {
\$rules{\$living}{\$digit} = 1;
}
}

+

+
# Setup the GUI
my \$mw     = new MainWindow(-title => \$rulename);
my \$canvas = \$mw->Canvas(-width => 514, -height => 514)->pack();
\$off_color = cget \$canvas(-bg);
\$mw->after(1, \&setup_and_evolve_forever);
MainLoop;

+

+
#
#  The main program loop.
#
sub setup_and_evolve_forever {

+
# Draw grid lines on the canvas
foreach my \$value (0..65) {
my \$a = 2 + 8 * \$value;
\$canvas->createLine(2, \$a, 515, \$a);
\$canvas->createLine(\$a, 2, \$a, 515);
}

+
if (\$filename) {
# Use a file for the initial pattern
my \$fh = new FileHandle;
open(\$fh, "<", \$filename);
my \$line;
\$y = 0;
while (\$line = <\$fh>) {
chomp \$line;
my \$x = 0;
foreach my \$char (split(//, \$line)) {
my \$is_living = (\$char eq '@')? 1: 0;
evolve_cell(\$x, \$y, \$is_living);
++\$x;
}
++\$y;
}
} else {
# Create a random initial pattern.
# Chances of a cell being "alive" are 1 in 4.
#
foreach \$x (@dimension) {
foreach \$y (@dimension) {
evolve_cell(\$x, \$y, (1 > rand 4)? 1: 0);
}
}
}

+
# Evolve forever ...
while (1) {

+
# First, plot the next generation of cells
foreach my \$p (@dimension) {
foreach my \$q (@dimension) {
my \$nneighbors = 0;
my \$this_cell = 0;
foreach my \$v (-1..1) {
foreach my \$w (-1..1) {
\$x = \$p + \$v;
\$y = \$q + \$w;
my \$is_living = evolve_cell(\$x, \$y, -1);
if (0 == \$w && 0 == \$v) {
\$this_cell = \$is_living;
}
\$nneighbors += \$is_living;
}
}

+
# Assign cell based on current state and number of nei
+ghbors
\$nneighbors = \$rules{\$this_cell}{\$nneighbors-\$this_cel
+l};
\$nextgen[64 * \$p + \$q] = \$nneighbors;
}
}

+
# Secondly, assign (and display) the next generation
foreach \$x (@dimension) {
foreach \$y (@dimension) {
evolve_cell(\$x, \$y, \$nextgen[64 * \$x+\$y] || 0);
}
}

+
\$mw->update();
}
}

+

+
#  Given (x, y) coordinates (x = \$1, y = \$2) and a state \$3 (which can
#  be 0 (dead), 1 (alive), or -1 (don't modify, just return the state)
+),
#  assigns the new state to the given cell (if the state is not -1), a
+nd
#  returns the state of the cell.
#
sub evolve_cell {
my (\$x, \$y, \$z) = @_;

+
# Get cell's state (0 = dead, 1 = alive)
my \$state = \$cells[64 * \$x + \$y] || 0;
if (\$x < 0 || \$x > 63 || \$y < 0 || \$y > 63) {
# If the coordinates are out-of-bounds, call the cell "dead"
\$state = 0;
}

+
if (\$z >= 0 && \$state != \$z) {
# Only evolve if the state is 0 or 1, and not equal to
# the previous state.
#
\$cells[64 * \$x + \$y] = \$z;      # Insert new value
my \$index = 512 * \$x + 8 * \$y;  # Calculate cell index
my \$id = \$ids[\$index];          # Lookup previous canvas ID, a
+nd
\$id and \$canvas->delete(\$id);   #  if nonzero, delete it.

+
# Setup the dimensions of the dot, and
# put the dot in the canvas.
#
my @dot = (3 + 8 * \$x, 3 + 8 * \$y,9 + 8 * \$x, 9 + 8 * \$y);
push @dot, \$z? (-f => \$on_color): (-f => \$off_color);
push @dot, -outline => \$off_color;
\$ids[\$index] = \$canvas->createOval(@dot);
}

+
return \$state;
}

s''(q.S:\$/9=(T1';s;(..)(..);\$..=substr+crypt(\$1,\$2),2,3;eg;print\$..\$/
Thanks!
Re: Evolutionary Japh
by dk (Chaplain) on Nov 17, 2006 at 09:34 UTC
Doesn't work--
do you have Tk installed? cos it's in an eval block it will fail without warnings - add
```;print \$@ if \$@;
to the end and it should tell you what's wrong. a

Create A New User
Node Status?
node history
Node Type: obfuscated [id://584030]
Front-paged by planetscape
help
Chatterbox?
 1nickt is installing all Perl versions so as to be able to send test reports to CPANTS ...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (11)
As of 2017-09-19 17:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
During the recent solar eclipse, I:

Results (226 votes). Check out past polls.

Notices?