Conway’s Game of Life has fascinated computer scientists for decades. Even though its rules are ridiculously simple, Conway’s universe gives rise to a variety of gliders, spaceships, oscillators, glider guns, and other forms of “life”. Self-printing programs are similarly curious, and – rather surprisingly – have an important place in the theory of computation.

What happens when you combine the two? You are about to find out, but one thing is for sure: the geekiness factor should be pretty high.

I wrote a little C# program that contains a Game-of-Life grid. The program advances the game grid to the next generation and prints out a copy of itself, with the grid updated. You can take the output, compile it with a C# compiler, run it, and you’ll get the next generation of the game. You can iterate the process, or change the initial grid state manually.

Here is the source code:

using System;class G  /* GAME OF LIFE by Igor Ostrovsky */  {static string[]S={
"############################################################################",
"#                                                               * *        #",
"#  ***                                                         *           #",
"#                                       *                      *           #",
"#                                     * *                      *  *        #",
"#                           **      **            **           ***         #",
"#                          *   *    **            **                       #",
"#               **        *     *   **                                     #",
"#               **        *   * **    * *                                  #",
"#                         *     *       *                                  #",
"#                          *   *                                           #",
"#                           **                                             #",
"#   **     **                                                              #",
"#    **   **                                        *  *                   #",
"# *  * * * *  *                                         *                  #",
"# *** ** ** ***                                     *   *                  #",
"#  * * * * * *                                       ****                  #",
"#   ***   ***                                                              #",
"#                                                                          #",
"#   ***   ***                                                              #",
"#  * * * * * *            *                                                #",
"# *** ** ** ***           *           *  *                             *** #",
"# *  * * * *  *                           *                           *  * #",
"#    **   **             ***          *   *                **            * #",
"#   **     **                          ****                              * #",
"#                                                                     * *  #",
"############################################################################",    
};static void Main(){string T="\",r=\"using System;class G  /* GAME OF LIFE b"+
"y Igor Ostrovsky \"+\"*/  {static string[]S={\\n\";int p=31,i,j,b,d;for(i=0;"+
"i<27;i++){r+='\"'; for(j=0;j<76;j++){if(S[i][j]!='#'){b=0;for(d=0;d<9;d++)if"+
"(S[i-1+d/3][j-1+d%3]=='*')b++;r+=b==3 ||(S[i][j]=='*'&&b==4)?'*':' ';} else "+
"r+='#';}r+=\"\\\",\\n\";}r+=\"};static\"+\" void Main(){string T=\\\"\";fore"+
"ach(var c in T){if(c=='\\\\'||c=='\"'){r+='\\\\';p++;} r+=c; if(++p>=77){r+="+
"\"\\\"+\\n\\\"\";p=1;}} foreach(var c in T){r+=c;if(++p%79==0)r+='\\n';}Cons"+
"ole.Write(r);}}",r="using System;class G  /* GAME OF LIFE by Igor Ostrovsky "+
"*/  {static string[]S={\n";int p=31,i,j,b,d;for(i=0;i<27;i++){r+='"'; for(j=0;
j<76;j++){if(S[i][j]!='#'){b=0;for(d=0;d<9;d++)if(S[i-1+d/3][j-1+d%3]=='*')b++;
r+=b==3 ||(S[i][j]=='*'&&b==4)?'*':' ';} else r+='#';}r+="\",\n";}r+="};static"
+" void Main(){string T=\"";foreach(var c in T){if(c=='\\'||c=='"'){r+='\\';p++
;} r+=c; if(++p>=77){r+="\"+\n\"";p=1;}} foreach(var c in T){r+=c;if(++p%79==0)
r+='\n';}Console.Write(r);}}

 

And is here the output the program prints. The output is the same as the source code, except that the game has advanced to the next generation:

using System;class G  /* GAME OF LIFE by Igor Ostrovsky */  {static string[]S={
"############################################################################",
"#   *                                                                      #",
"#   *                                                          **          #",
"#   *                                  *                      ***          #",
"#                                    * *                      ** *         #",
"#                           *       * *           **           ***         #",
"#                          **      *  *           **            *          #",
"#               **        **    **  * *                                    #",
"#               **       ***    **   * *                                   #",
"#                         **    **     *                                   #",
"#                          **                                              #",
"#                           *                                              #",
"#   ***   ***                                                              #",
"#                                                                          #",
"# *    * *    *                                        **                  #",
"# *    * *    *                                      ** **                 #",
"# *    * *    *                                      ****                  #",
"#   ***   ***                                         **                   #",
"#                                                                          #",
"#   ***   ***                                                              #",
"# *    * *    *                                                         *  #",
"# *    * *    *                                                        *** #",
"# *    * *    *          * *             **                            * **#",
"#                         *            ** **                            ***#",
"#   ***   ***             *            ****                             ** #",
"#                                       **                                 #",
"############################################################################",
};static void Main(){string T="\",r=\"using System;class G  /* GAME OF LIFE b"+
"y Igor Ostrovsky \"+\"*/  {static string[]S={\\n\";int p=31,i,j,b,d;for(i=0;"+
"i<27;i++){r+='\"'; for(j=0;j<76;j++){if(S[i][j]!='#'){b=0;for(d=0;d<9;d++)if"+
"(S[i-1+d/3][j-1+d%3]=='*')b++;r+=b==3 ||(S[i][j]=='*'&&b==4)?'*':' ';} else "+
"r+='#';}r+=\"\\\",\\n\";}r+=\"};static\"+\" void Main(){string T=\\\"\";fore"+
"ach(var c in T){if(c=='\\\\'||c=='\"'){r+='\\\\';p++;} r+=c; if(++p>=77){r+="+
"\"\\\"+\\n\\\"\";p=1;}} foreach(var c in T){r+=c;if(++p%79==0)r+='\\n';}Cons"+
"ole.Write(r);}}",r="using System;class G  /* GAME OF LIFE by Igor Ostrovsky "+
"*/  {static string[]S={\n";int p=31,i,j,b,d;for(i=0;i<27;i++){r+='"'; for(j=0;
j<76;j++){if(S[i][j]!='#'){b=0;for(d=0;d<9;d++)if(S[i-1+d/3][j-1+d%3]=='*')b++;
r+=b==3 ||(S[i][j]=='*'&&b==4)?'*':' ';} else r+='#';}r+="\",\n";}r+="};static"
+" void Main(){string T=\"";foreach(var c in T){if(c=='\\'||c=='"'){r+='\\';p++
;} r+=c; if(++p>=77){r+="\"+\n\"";p=1;}} foreach(var c in T){r+=c;if(++p%79==0)
r+='\n';}Console.Write(r);}}

 

If you want to see the program iterate, save the source code into a file named life.cs, and run this command repeatedly from a Visual Studio console:

csc.exe life.cs && (life > life.cs) && life

Cool, isn’t it? I have a follow-up article nearly ready that explains how to write programs like this one… just in case you ever wanted to. ;-)

[Update] The follow-up How to write a self-printing program is up.

More articles:

Numbers that cannot be computed

Skip list are fascinating!

Quicksort killer

Tags:

18 Comments to “Self-printing Game of Life in C#”

  1. John Woods says:

    Wow that looks like something I did on my Commodore 64 back in the day.

    Jiff
    http://www.online-anonymity.kr.tc

  2. Anonymous says:

    You sir, are one evil motherfucker.

    I look forward to your follow-up article that explains how to be an evil motherfucker just like you.

    :-)

  3. […] Igor writes- Conw&#97y’s G&#97me of Life h&#97s f&#97scin&#97ted comp&#117ter scientists for dec&#97des. Even tho&#117gh its r&#117les &#97re ridic&#117lo&#117sly simple, Conw&#97y’s &#117niverse gives rise to &#97 v&#97riety of gliders, sp&#97ceships, oscill&#97tors, glider g&#117ns, &#97nd other forms of “life”. Self-printing progr&#97ms &#97re simil&#97rly c&#117rio&#117s, &#97nd – r&#97ther s&#117rprisingly – h&#97ve &#97n import&#97nt pl&#97ce in the theory of comp&#117t&#97tion. […]

  4. d says:

    Today, the Game of Life. Tomorrow, Skynet.

  5. tan says:

    My head just exploded.

  6. Dustin says:

    Hey Igor,

    Didn’t know that you regularily blog programming/theory tidbits like this one. Cool.

  7. Rohit says:

    Coolest quine ever!

  8. rb says:

    it doesnt compile in Mono on Linux.

  9. @rb: The code uses implicitly-typed variables (the ‘var’ keyword). Perhaps Mono does not support that feature yet?

  10. […] [upmod] [downmod] Self-printing Game of Life in C# | Igor Ostrovsky Blogging (igoro.com) 1 points posted 6 months, 2 weeks ago by jeethu tags game programming quine life […]

  11. […] the RSS feed to receive my future posts.Powered by WP Greet BoxAs promised at the end of my recent post, I am going to explain how to implement a program that prints itself, in addition to doing other […]

  12. […] Self-printing Game of Life in C# […]

  13. z0r says:

    You could also feed it to the build-in C# compiler.
    http://support.microsoft.com/kb/304655

  14. Danukeru says:

    Now THAT’S what I call hardcore metaprogramming…

    Von Neumann would be proud. XD

  15. […] a quine to print out the source code of the program together with a comment containing the next frame in Conway’s Game of Life. So we have programs that can age themselves, as well as programs that double as pictures. The […]

  16. Rsh says:

    Works for Mono quite all right:

    while [ 1 ];do gmcs GameOfLife.cs && mono GameOfLife.exe > GameOfLife.cs && clear && cat GameOfLife.cs|grep "\"#";done

  17. Bjartur Thorlacius says:

    Note the gmcs part. The mcs executable packaged in Mono implements only a subset of the language, or equally, an old version of the language. The Mono compiler for C# 2 and C#1 is mcs, and the Mono compiler for C# 3 and later is gmcs.

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>