| use Term::ReadKey; |
| use Win32::Console; |
| use Time::HiRes 'sleep'; |
| use IO::Handle; |
| STDOUT->autoflush(1); |
| system("mode con lines=40 cols=80"); |
| |
| our $OUT=Win32::Console->new(STD_OUTPUT_HANDLE); |
| $OUT->Cursor(20, 20, 99, 0); |
| |
| my ($i, $j); |
| our ($rows, $cols) = (40, 40); |
| our ($mxrow, $mxcol) = ($rows-1, $cols-1); |
| |
| |
| our @coord; |
| my (@h, @n); |
| my $y = 0; |
| |
| foreach (<DATA>) { |
| s/\r?\n$//; |
| tr/\*\./10/; |
| @{$h[$y++]} = ( split("", $_) ); |
| } |
| |
| foreach $i (0 .. $mxrow) { |
| foreach $j (0 .. $mxcol) { |
| $coord[$i][$j]{'x'} = $j*2; |
| $coord[$i][$j]{'y'} = $i; |
| $h[$i][$j] = 0 unless (defined $h[$i][$j]); |
| $n[$i][$j] = 0; |
| } |
| } |
| |
| &Draw(\@n, \@h); |
| foreach (0..1000) { |
| sleep 0.1; |
| @n = (); |
| &NextBuffer(\@h, \@n); |
| &Draw(\@h, \@n); |
| @h = (@n); |
| &KeyFunc(); |
| } |
| |
| sub NextBuffer { |
| my ($ra, $rb) = (shift, shift); |
| my ($i, $j, $sum, $n); |
| my ($L, $R, $U, $D, $vi, $vj); |
| foreach $i (0 .. $mxrow) { |
| $U = ($i-1) < 0 ? $mxrow : ($i-1); |
| $D = ($i+1) > $mxrow ? 0 : ($i+1); |
| foreach $j (0 .. $mxcol) { |
| $sum = 0; |
| $L = ($j-1) < 0 ? $mxcol : ($j-1); |
| $R = ($j+1) > $mxcol ? 0 : ($j+1); |
| $sum = $ra->[$U][$L] + $ra->[$U][$j] + $ra->[$U][$R] + |
| $ra->[$i][$L] + 0 + $ra->[$i][$R] + |
| $ra->[$D][$L] + $ra->[$D][$j] + $ra->[$D][$R]; |
| |
| if ($sum == 3) { |
| $rb->[$i][$j] = 1; |
| } elsif ($sum == 2) { |
| $rb->[$i][$j] = $ra->[$i][$j]; |
| } else { |
| $rb->[$i][$j] = 0; |
| } |
| } |
| } |
| } |
| |
| sub Draw { |
| my ($ra, $rb) = (shift, shift); |
| foreach $i (0 .. $mxrow) { |
| foreach $j (0 .. $mxcol) { |
| if ($rb->[$i][$j] != $ra->[$i][$j]) { |
| &Point( |
| $coord[$i][$j]{'x'}, |
| $coord[$i][$j]{'y'}, |
| $rb->[$i][$j], |
| ); |
| } |
| } |
| } |
| } |
| |
| sub Point { |
| my ($mx, $my, $light) = (shift, shift, shift); |
| my $color; |
| if ($light == 1) { |
| $color = $FG_WHITE|$BG_GRAY; |
| } else { |
| $color = $FG_WHITE|$BG_BLACK; |
| } |
| $OUT->Cursor($mx, $my); |
| $OUT->FillAttr($color, 2, $mx, $my); |
| } |
| |
| sub KeyFunc { |
| my $key; |
| $key = ReadKey(-1); |
| return if (not defined $key); |
| if ( ord($key) == 27 ) { |
| exit; |
| } |
| } |
| |
| |
| __DATA__ |
| ......................**............... |
| ......................**............... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| .........*..........**...**............ |
| .......*.*............***.............. |
| ......*.*............*...*............. |
| **...*..*.............*.*.............. |
| **....*.*..............*............... |
| .......*.*......*.*.................... |
| .........*......**..................... |
| .................*...*................. |
| .....................**......*......... |
| ....................*.*......*.*....... |
| ...............*..............*.*....** |
| ..............*.*.............*..*...** |
| .............*...*............*.*...... |
| ..............***............*.*....... |
| ............**...**..........*......... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ....................................... |
| ...............**...................... |
| ...............**......................COPY |