Perl (Graphical/ASCII)
The Towers of Hanoi as a Perl script producing ASCII graphics.
#! /usr/bin/perl -w
#
# The Towers Of Hanoi
# ASCII Graphics (Perl)
# Copyright (C) 2001 Amit Singh. All Rights Reserved.
# http://hanoi.kernelthread.com
#
# For 80x25 ASCII Terminal
my $MAXDISKS = 7;
my %TOWERS = (
'1' => [],
'2' => [],
'3' => [],
);
if ($#ARGV != 0) {
die "usage: $0 <number of disks>\n";
}
my $ndisks = int($ARGV[0]);
if (($ndisks < 0) || ($ndisks > $MAXDISKS)) {
die "hanoi: number of disks must be between 1 and $MAXDISKS (inclusive).\n";
}
populate_towers();
do_hanoi($ndisks, "1", "3", "2");
sub populate_towers
{
for (my $i = $ndisks; $i >= 1; $i--) {
my $aref = $TOWERS{'1'};
my $disk = 2 * $i + 1;
push @{$aref}, $disk;
}
}
sub do_hanoi
{
my $n = shift;
my $f = shift;
my $t = shift;
my $u = shift;
if ($n <= 1) {
show_snapshot($f, $t, $u);
} else {
do_hanoi($n - 1, $f, $u, $t);
show_snapshot($f, $t, $u);
do_hanoi($n - 1, $u, $t, $f);
}
}
sub show_snapshot
{
my $f = shift;
my $t = shift;
my $u = shift;
my $f_aref = $TOWERS{$f};
my $t_aref = $TOWERS{$t};
my $u_aref = $TOWERS{$u};
my $disk = pop @{$f_aref};
push @{$t_aref}, $disk;
my @F_a = @{$TOWERS{'1'}};
my @U_a = @{$TOWERS{'2'}};
my @T_a = @{$TOWERS{'3'}};
my $j = 0;
for ($j = $ndisks - 1; $j >= 0; $j--) {
if ($F_a[$j]) {
my $font = ($F_a[$j] - 1) / 2;
my $rem = (25 - $F_a[$j]) / 2;
print " " . " " x $rem . "$font" x $F_a[$j] . " " x $rem . " ";
} else {
print " " x 13 . "|" . " " x 13;
}
if ($U_a[$j]) {
my $font = ($U_a[$j] - 1) / 2;
my $rem = (25 - $U_a[$j]) / 2;
print " " x $rem . "$font" x $U_a[$j] . " " x $rem . " ";
} else {
print " " x 12 . "|" . " " x 13;
}
if ($T_a[$j]) {
my $font = ($T_a[$j] - 1) / 2;
my $rem = (25 - $T_a[$j]) / 2;
print " " x $rem . "$font" x $T_a[$j];
} else {
print " " x 12 . "|";
}
print "\n";
}
print " " . "=" x 25 . " " . "=" x 25 . " " . "=" x 25 . "\n";
}
1;
__END__
