@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
