ラングトンのアリの描画
Posted feedbacks - Perl
Perl/Tk でごりごり書いてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | use strict;
use warnings;
use Tk;
use Tk::MsgBox;
use utf8;
my $w = shift || 100;
my $h = shift || $w;
my $pxsize = 4;
my $init_pattern_subs = create_pattern_subs();
my $pattern = shift;
my $pattarn_sub = $pattern && exists $init_pattern_subs->{$pattern}
? $init_pattern_subs->{$pattern}
: sub { 0 };
my $mw = Tk::MainWindow->new(-title => 'ラングトンの蟻');
my $control_frame = $mw->Frame;
$control_frame->pack(
-side => 'bottom',
-anchor => 's',
-fill => 'x',
);
my $drawing_frame = $mw->Frame;
$drawing_frame->pack(
-side => 'top',
-anchor => 'n',
-fill => 'both',
);
my $canvas = $drawing_frame->Canvas(
-width => $w * $pxsize, -height => $h * $pxsize,
-background => 'white',
);
my @field;
for my $x ( 0 .. $w-1 ) {
for my $y ( 0 .. $h-1 ) {
$field[$x][$y] = $canvas->createRectangle(
(map{$_ * $pxsize} $x,$y,$x+1,$y+1),
-fill => 'white'
);
}
}
$canvas->pack(-fill => 'both');
my $start_button = $control_frame->Button(
-text => 'START',
-command => \&start_proc,
-state => 'normal',
);
$start_button->pack(-anchor => 'w', -side => 'left');
my $stop_button = $control_frame->Button(
-text => 'STOP',
-command => \&stop_proc,
-state => 'disabled',
);
$stop_button->pack(-anchor => 'w', -side => 'left', -padx => 20);
my $stat = step_label(0,0,0);
my $stat_label = $control_frame->Label(
-textvariable => \$stat
);
$stat_label->pack(-anchor => 'w', -side => 'left', -padx => 30);
Tk->MainLoop;
sub create_pattern_subs
{
+{
ichimatsu => sub { (($_[0]/2) ^ ($_[1]/2)) & 0x1; },
lines => sub { ($_[0]/12) & ($_[1]/2) & 0x1; },
random => sub { !int rand 3 },
};
}
sub step_label
{
sprintf '%#8d steps (%#3d, %#3d)', @_;
}
{
my ($count,$x,$y,$d,$timer);
sub start_proc
{
$stop_button->configure(-state => 'normal');
$start_button->configure(-state => 'disabled');
$count = 0;
$x = int(rand($w/2) + $w/4);
$y = int(rand($h/2) + $h/4);
$d = int(rand(4));
for my $x_ ( 0 .. $w-1 ) {
for my $y_ ( 0 .. $h-1 ) {
$canvas->itemconfigure($field[$x_][$y_],
-fill => $pattarn_sub->($x_,$y_) ? 'black' : 'white');
}
}
$timer = $mw->repeat(10, \&next_step);
}
sub stop_proc
{
$stop_button->configure(-state => 'disabled');
$start_button->configure(-state => 'normal');
$mw->afterCancel($timer);
}
sub next_step
{
my $bit = $canvas->itemcget($field[$x][$y], '-fill') ne 'white';
$canvas->itemconfigure($field[$x][$y], -fill => ($bit ? 'white' : 'black'));
$d = ($bit ? ++$d : --$d) % 4;
if ( $d == 0 ) { --$x; }
elsif ( $d == 1 ) { ++$y; }
elsif ( $d == 2 ) { ++$x; }
elsif ( $d == 3 ) { --$y; }
if ( $x < 0 || $x >= $w || $y < 0 || $y >= $h ) {
stop_proc;
my $d = $mw->MsgBox(-title => 'END', -message => 'しゅーりょー', -type => 'ok');
$d->Show;
return;
}
$stat = step_label( ++$count, $x, $y);
}
}
|

Songmu #9331() [ JavaScript ] Rating8/10=0.80
- 黒いマスにアリがいた場合、90°右に方向転換し、そのマスの色を反転させ、1マス前進する。
- 白いマスにアリがいた場合、90°左に方向転換し、そのマスの色を反転させ、1マス前進する。
詳しくはWikipedia等で調べるか、参考ページに拙作のデモがありますのでご覧下さい。
see: JavaScriptでラングトンの蟻
Rating8/10=0.80-0+
[ reply ]