forked from trizen/perl-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
langton_s_ant_gd.pl
executable file
·79 lines (57 loc) · 1.93 KB
/
langton_s_ant_gd.pl
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
#!/usr/bin/perl
# Author: Trizen
# License: GPLv3
# Date: 15 December 2013
# Website: https://trizenx.blgospot.com
# Variation of: https://rosettacode.org/wiki/Langton%27s_ant#Perl
# More info about Langton's ant: https://en.wikipedia.org/wiki/Langton%27s_ant
use 5.010;
use strict;
use warnings;
use GD::Simple;
my $width = 1920;
my $height = 1080;
my $line = 10; # line length
my $size = 100; # pattern size
my $turn_left_color = 'red';
my $turn_right_color = 'black';
my $img_file = 'langton_s_ant.png';
my $p = GD::Simple->new($width, $height);
$p->moveTo($width / 2, $height / 2);
# Using screen coordinates - 0,0 in upper-left, +X right, +Y down -
# these directions (right, up, left, down) are counterclockwise
# so advance through the array to turn left, retreat to turn right
my @dirs = ([1, 0], [0, -1], [-1, 0], [0, 1]);
# we treat any false as white and true as black, so undef is fine for initial all-white grid
my @plane;
for (0 .. $size - 1) { $plane[$_] = [] }
# start out in approximate middle
my ($x, $y) = ($size / 2, $size / 2);
# pointing in a random direction
my $dir = int rand @dirs;
# turn in a random direction
$p->turn(90 * $dir);
my $move;
for ($move = 0 ; $x >= 0 && $x < $size && $y >= 0 && $y < $size ; $move++) {
# toggle cell's value (white->black or black->white)
if ($plane[$x][$y] = 1 - ($plane[$x][$y] ||= 0)) {
# if it's now true (black), then it was white, so turn right
$p->fgcolor($turn_right_color);
$p->line($line);
# for more interesting patterns, try multiplying 90 with $dir
$p->turn(90);
$dir = ($dir - 1) % @dirs;
}
else {
# otherwise it was black, so turn left
$p->fgcolor($turn_left_color);
$p->line($line);
$p->turn(-90);
$dir = ($dir + 1) % @dirs;
}
$x += $dirs[$dir][0];
$y += $dirs[$dir][1];
}
open my $fh, '>', $img_file or die "$img_file: $!";
print {$fh} $p->png;
close $fh;