@Echo Off SetLocal EnableExtensions EnableDelayedExpansion Rem width of the area Set width=81 Rem height of the area Set height=40 Rem what to do at the edges. Rem Zero = outside the area are only zeros Rem One = outside the area are only ones Rem Copy = the first/last cell is repeated to the outside of the area Rem Wrap = the field is a cylinder and the 0th cell is the last one and vice versa Set edge_mode=Copy Rem Copy should be a sensible default here. The edge seems to be the place where things Rem go weird anyway. Rem rule can be given via commandline, if not, just ask for it Set rule=%1 If "%1" Neq "" GoTo dont_ask_rule :ask_rule Set /p rule=Rule? :dont_ask_rule If %rule% Lss 0 GoTo ask_rule If %rule% Gtr 255 GoTo ask_rule Call :dissect_rule Call :init_field Call :show_field_row 1 For /l %%x In (2,1,%height%) Do Call :compute_row %%x EndLocal GoTo :EOF :dissect_rule For /l %%i In (0,1,7) Do Set /a wolfram_%%i=^(%rule% ^>^> %%i^) ^& 1 GoTo :EOF :show_rule For /l %%i In (0,1,7) Do Set blah=!wolfram_%%i!!blah! Echo Rule: %blah% GoTo :EOF :init_field For /l %%r In (1,1,%height%) Do ( For /l %%c In (1,1,%width%) Do Set field_%%r_%%c=0 ) If %edge_mode%==Zero ( Rem outside the display area are only zeros Set /a augm_width=width+1 For /l %%r In (1,1,%height%) Do ( Set field_%%r_0=0 Set field_%%r_!augm_width!=0 ) ) If %edge_mode%==One ( Rem outside the display area are only ones Set /a augm_width=width+1 For /l %%r In (1,1,%height%) Do ( Set field_%%r_0=1 Set field_%%r_!augm_width!=1 ) ) If %edge_mode%==Wrap ( Set field_1_0=!field_1_%width%! Set /a augm_width=width+1 Set field_1_!augm_width!=!field_1_1! ) If %edge_mode%==Copy ( Set field_1_0=!field_1_1! Set /a augm_width=width+1 Set field_1_!augm_width!=!field_1_%width%! ) Set /a halfwidth=width/2 Set field_1_%halfwidth%=1 GoTo :EOF :show_field For /l %%r In (1,1,%height%) Do Call :show_field_row %%r Goto :EOF :show_field_row Set line= For /l %%c In (1,1,%width%) Do If !field_%1_%%c!==1 (Set line=!line!X) Else (Set line=!line! ) Echo.!line! GoTo :EOF :compute_row Rem %1 is the current row For /l %%c In (1,1,%width%) Do Call :compute_row_field %%c %1 Call :show_field_row %1 If %edge_mode%==Wrap ( Set field_%1_0=!field_%1_%width%! Set /a augm_width=width+1 Set field_%1_!augm_width!=!field_%1_1! ) If %edge_mode%==Copy ( Set field_%1_0=!field_%1_1! Set /a augm_width=width+1 Set field_%1_!augm_width!=!field_%1_%width%! ) GoTo :EOF :compute_row_field Rem %1 is the field, %2 the current row Set /a oldrow=%2 - 1 Call :get_case %oldrow% %1 Set field_%2_%1=!wolfram_%case%! GoTo :EOF :get_case Rem %1 is the row above the one currently calculated, %2 is the current field Rem left and right neighbours Set /a l=%2 - 1 Set /a r=%2 + 1 Set /a case=^(!field_%1_%l%! ^<^< 2^) + ^(!field_%1_%2! ^<^< 1^) + ^(!field_%1_%r%!^) GoTo :EOF