Happy ASCII New Year ;-)

Posted by & filed under Art, CDF, Code, Graphics, Mathematica, Wolfram, Wolfram Language.

I can occasionally appreciate a nice ASCII art design. But the better is the design, the more manual and custom approach it needs – or so it seems. It is actually quite challenging, if you think about it, to transform a known image or shape to a limited medium using finite set of geometries. So the question is: are there some nice programmable cases? I got inspired by a recent challenge Make a scalable Christmas tree on a code-golf site. A Christmas tree is indeed a good shape for scalable design. Here is the result with full code and explanations below. BTW watch tree carefully – it changes too 😉

ASCII Tree

We can start with something very simple, a one-liner, – just picking some nice symbols for snow and tree needles – and then picking them at random:

 
Column[Table[Row[RandomChoice[{"+", ".", "*", "~", "^", "o"}, k]], {k, 1, 35, 2}], Alignment -> Center]

simple ASCII tree

Which already looks nice and in the true spirit ASCII. It is also scalable – just increases the size inside the Table. But now we can even add a bit of dynamics to this. It’d be great to have falling snow. How to make it a bit real? We will make it to fall in a straight-down path rarely shifting it randomly to the left or right. Basically our snow will make a lazy random walk. But then if two different snowflakes meet – how do they overlap or pass through each other? These are just characters in a List, so how to accomplish this? Well we can be a bit inventive to avoid the overlap problem. If we place one and only one snowflake in every row, and then shift down 1 step simultaneously for all of them, then no matter what left-right shifts are – snowflakes will never collide. What else could we do? We could create an illusion that snow sometimes sticks to the branches and then falls. For this we do not need to actually correlate snow and tree. We could just randomly replace symbols in the tree and that will be enough for a good ASCII visual. Snow symbols will be white puffs or snowflakes and tree symbols will be green. Note the controlled Dynamic updates too. Here we go.

 
DynamicModule[{atoms, tree, pos, snow, p = .8, sz = 15},

 atoms = {
   Style["+", White],
   Style["*", White],
   Style["o", White],
   Style[".", Green],
   Style["~", Green],
   Style["^", Green],
   Style["^", Green]
   };

 pos = Flatten[Table[{m, n}, {m, 18}, {n, 2 m - 1}], 1];

 tree = Table[RandomChoice[atoms, k], {k, 1, 35, 2}];

 snow = Table[
   RotateLeft[ArrayPad[{RandomChoice[atoms[[1 ;; 2]]]}, {0, sz}, " "],
     RandomInteger[sz]], {sz + 1}];

 Dynamic[Refresh[

   Overlay[{

     tree[[Sequence @@ RandomChoice[pos]]] = RandomChoice[atoms];
     Column[Row /@ tree, Alignment -> Center, Background -> Black],

     Grid[
      snow = 
       RotateRight[
        RotateLeft[#, 
           RandomChoice[{(1 - p)/2, p, (1 - p)/2} -> {-1, 0, 1}]] & /@
          snow
        , {1, 0}]]

     }, Alignment -> Center]

   , UpdateInterval -> 0, TrackedSymbols -> {}]
  ]
 ]

Leave a Reply

Your email address will not be published. Required fields are marked *