use strict; 
use warnings;
use Tk;
use List::Util qw( max );

my $c; 



my $pen = 1; 
my @location = (0, 0); 
my $direction = 0; 
my @stack;
my $radian = 180 / atan2 0, -1;
sub dsin { sin $_[0] / $radian }
sub dcos { cos $_[0] / $radian }
sub save { push @stack, [ $direction, @location ] }
sub restore { ($direction, @location) = @{ pop @stack } }
sub turn { $direction += shift }
sub right { turn shift }
sub left { turn -shift }
sub forward
  {
  my $x = $location[0] + $_[0] * dcos $direction;
  my $y = $location[1] + $_[0] * dsin $direction;
  $pen and $c->createLine( @location, $x, $y, -width => 3 );
  @location = ($x, $y);
  }
sub back { turn 180; forward shift; turn 180 }
sub penup { $pen = 0 }
sub pendown { $pen = 1 }
sub text { $c->createText( @location, -text => shift ) }



my $mw = MainWindow->new;
$c = $mw->Canvas(
  -width => 900, -height => 900,
  )->pack;
$mw->Button(-text => 'Exit', -command => sub {$mw->destroy},
  )->pack(-fill => 'x');
$mw->after(0, \&run);
MainLoop;
-M $0 < 0 and exec $0;

sub box
  {
  my ($w, $h) = @_;
  for (1 .. 2)
    {
    forward $w;
    left 90;
    forward $h;
    left 90;
    }
  }

sub house
  {
  my $size = shift;
  box $size, $size;
  right 90;
  for ( 1 .. 3 )
    {
    right 120;
    forward $size;
    }
  penup;
  left 90;
  forward $size;
  left 90;
  save;
  forward $size * 1 / 4;
  pendown;
  box $size / 4, $size / 2;
  penup;
  forward $size * 3 / 8;
  left 90;
  forward $size / 4;
  right 90;
  pendown;
  box $size / 4, $size / 4;
  penup;
  restore;
  save;
  forward $size / 2;
  left 90;
  forward $size + 40;
  right 90;
  pendown;
  for (1 .. 8)
    {
    forward 15;
    left 45;
    forward 15;
    }
  restore;
  penup;
  }

sub graph
  {
  save;
  my $size = shift;
  my $width = $size / @_;
  my $hscale = $size / max @_;
  for ( @_ )
    {
    box $width, $hscale * $_;
    save;
    penup;
    forward $width / 2;
    left 90;
    forward 10;
    text $_;
    pendown;
    restore;
    forward $width;
    }
  restore;
  }

sub run
  {
  penup;
  forward 50;
  right 90;
  forward 400;
  pendown;
  house(300);
  penup;
  forward 400;
  pendown;
  graph( 400, 2,7,4,5,1,8,6 );
  }