Simple turtle graphics

From Rosetta Code
Task
Simple turtle graphics
You are encouraged to solve this task according to the task description, using any language you may know.

The first turtle graphic discussed in Mindstorms: Children, Computers, and Powerful Ideas by Seymour Papert is a simple drawing of a house. It is a square with a triangle on top for the roof.

For a slightly more advanced audience, a more practical introduction to turtle graphics might be to draw a bar chart.

See image here: https://i.imgur.com/B7YbTbZ.png

Task
  • Create a function (or subroutine) that uses turtle graphics to draw a house of a specified size as described above. Optionally make it lovely by adding details such as, for example, doors and windows.
  • Create a function (or subroutine) that takes a list (array, vector) of non-negative numbers and draws a bar chart from them, scaled to fit exactly in a square of a specified size. The enclosing square need not be drawn.
  • Both functions should return the turtle to the location it was at and facing in the same direction as it was immediately before the function was executed.

Action!

<lang Action!>INCLUDE "D2:TURTLE.ACT" ;from the Action! Tool Kit

PROC Rectangle(INT w,h)

 BYTE i
 FOR i=1 TO 2
 DO
   Forward(h)
   Left(90)
   Forward(w)
   Left(90)
 OD

RETURN

PROC Square(INT w)

 Rectangle(w,w)

RETURN

PROC Triangle(INT w)

 BYTE i
 FOR i=1 TO 3
 DO
   Forward(w)
   Right(120)
 OD

RETURN

PROC House(INT w)

 Left(90)
 Square(w)
 Triangle(w)
 Right(90)

RETURN

INT FUNC GetMax(INT ARRAY a INT count)

 INT i,max
 max=0
 FOR i=0 TO count-1
 DO
   IF a(i)>max THEN
     max=a(i)
   FI
 OD

RETURN (max)

PROC BarChart(INT ARRAY a INT count,w)

 INT max,st,i
 IF count=0 THEN RETURN FI
 max=GetMax(a,count)
 st=w/count
 Right(90)
 FOR i=0 TO count-1
 DO
   Rectangle(a(i)*w/max,st)
   Forward(st)
 OD
 Left(180)
 Forward(w)

RETURN

PROC Main()

 BYTE CH=$02FC,COLOR1=$02C5,COLOR2=$02C6
 INT ARRAY a=[50 33 200 130 50]
 Graphics(8+16)
 COLOR1=$0C
 COLOR2=$02
 Color=1
 SetTurtle(150,110,90)
 House(75)
 
 Color=0
 Right(90)
 Forward(5)
 Left(90)
 Color=1
 BarChart(a,5,100)
 Right(90)
 Forward(5)
 Right(90)
 DO UNTIL CH#$FF OD
 CH=$FF

RETURN</lang>

Output:

Screenshot from Atari 8-bit computer

Ada

<lang ada> with Ada.Text_IO; use Ada.Text_IO; with Ada.Characters; use Ada.Characters; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Ada.Strings; use Ada.Strings;

-- procedure main - begins program execution procedure main is

   type Sketch_Pad is array(1 .. 50, 1 .. 50) of Character;
   thePen : Boolean := True; -- pen raised by default
   sketch : Sketch_Pad;
   ycorr, xcorr : Integer := 25;
   -- specifications
   function penPosition(thePen : in out Boolean) return String;
   procedure initGrid(sketch : in out Sketch_Pad);
   procedure commandMenu(thePen : in out Boolean; xcorr : in out Integer;
                         ycorr : in out Integer);
   procedure showMenu(xcorr : in out Integer; ycorr : in out Integer;
                      thePen : in out Boolean; sketch : in Sketch_Pad);
   procedure moveCursor(thePen : in Boolean; sketch : in out Sketch_Pad;
                        xcorr : in out Integer; ycorr : in out Integer;
                        ch : in Integer);
   procedure showGrid(sketch : in Sketch_Pad);
   -- procedure initGrid - creates the sketchpad and initializes elements
   procedure initGrid(sketch : in out Sketch_Pad) is
   begin
       sketch := (others => (others => ' '));
   end initGrid;
   -- procedure showMenu - displays the menu for the application
   procedure showMenu(xcorr : in out Integer; ycorr : in out Integer;
                      thePen : in out Boolean; sketch : in Sketch_Pad) is
       choice : Integer := 0;
   begin
       while choice /= 4 loop
           Set_Col(15);
           Put("TURTLE GRAPHICS APPLICATION");
           Set_Col(15);
           Put("===========================");
           New_Line(2);
           Put_Line("Enter 1 to print the grid map");
           Put_Line("Enter 2 for command menu");
           Put_Line("Enter 3 to raise pen up / down");
           Put_Line("Enter 4 to exit the application");
           choice := integer'value(Get_Line);
           exit when choice = 4;
           case choice is
               when 1 => showGrid(sketch);
               when 2 => commandMenu(thePen, xcorr, ycorr);
               when 3 => Put_Line("Pen is "
                             & penPosition(thePen));
               when others => Put_Line("Invalid input");
           end case;
       end loop;
   end showMenu;
   -- function penPosition - checks changes the state of whether the pen is
   -- raised up or down. If value is True, pen is rasied up
   function penPosition(thePen : in out Boolean) return String is
       str1 : constant String := "raised UP";
       str2 : constant String := "raised DOWN";
   begin
       if thePen = True then
           thePen := False;
           return str2;
       else
           thePen := True;
       end if;
       return str1;
   end penPosition;
   -- procedure command menu - provides a list of directions for the turtle
   -- to move along the grid
   procedure commandMenu(thePen : in out Boolean; xcorr : in out Integer;
                         ycorr : in  out Integer) is
       choice : Integer := 0;
   begin
       while choice <= 0 or choice > 5 loop
           Set_Col(15);
           Put("Command Menu");
           Set_Col(15);
           Put("============");
           New_Line(2);
           Put_Line("To move North enter 1");
           Put_Line("To move South enter 2");
           Put_Line("To move East enter 3");
           Put_Line("To move West enter 4");
           Put_Line("To return to previous menu enter 5");
           choice := integer'value(Get_Line);
           case choice is
               when 1 => moveCursor(thePen, sketch, xcorr, ycorr, choice);
               when 2 => moveCursor(thePen, sketch, xcorr, ycorr, choice);
               when 3 => moveCursor(thePen, sketch, xcorr, ycorr, choice);
               when 4 => moveCursor(thePen, sketch, xcorr, ycorr, choice);
               when 5 => showMenu(xcorr, ycorr, thePen, sketch);
               when others => Put_Line("Invalid choice");
           end case;
       end loop;
   end commandMenu;


   -- procedure moveCursor - moves the cursor around the board by taking the
   -- x and y coordinates from the user. If the pen is down, a character is
   -- printed at that location. If the pen is up, nothing is printed but the
   -- cursor still moves to that position
   procedure moveCursor(thePen : in Boolean; sketch : in out Sketch_Pad;
                        xcorr : in out Integer; ycorr : in out Integer;
                        ch : in Integer) is
   begin
       if thePen = True then -- pen up so move cursor but do not draw
           case ch is
               when 1 => xcorr := xcorr - 1; ycorr := ycorr;
                   sketch(xcorr, ycorr) := ' ';
               when 2 => xcorr := xcorr + 1; ycorr := ycorr;
                   sketch(xcorr, ycorr) := ' ';
               when 3 => xcorr := xcorr; ycorr := ycorr + 1;
                   sketch(xcorr, ycorr) := ' ';
               when 4 => xcorr := xcorr; ycorr := ycorr - 1;
                   sketch(xcorr, ycorr) := ' ';
               when others => Put("Unreachable Code");
           end case;
       else -- pen is down so move cursor and draw
           case ch is
               when 1 => xcorr := xcorr - 1; ycorr := ycorr;
                   sketch(xcorr, ycorr) := '#';
               when 2 => xcorr := xcorr + 1; ycorr := ycorr;
                   sketch(xcorr, ycorr) := '#';
               when 3 => xcorr := xcorr; ycorr := ycorr + 1;
                   sketch(xcorr, ycorr) := '#';
               when 4 => xcorr := xcorr; ycorr := ycorr - 1;
                   sketch(xcorr, ycorr) := '#';
               when others => Put("Unreachable Code");
           end case;
       end if;
   end moveCursor;
   -- procedure showGrid - prints the sketchpad showing the plotted moves
   procedure showGrid(sketch : in Sketch_Pad) is
   begin
       New_Line;
       for I in sketch'Range(1) loop
           for J in sketch'Range(2) loop
               Put(character'image(sketch(I,J)));
           end loop;
           New_Line;
       end loop;
       New_Line;
   end showGrid;

begin

   New_Line;
   initGrid(sketch);
   showMenu(xcorr, ycorr, thePen, sketch);
  New_Line;

end main; </lang>

J

Translation of: Logo

Prerequisites (requires a network connection or, for a non-networked system, significant technical savvy), and assumes user is running the a recent version of J's (perhaps J 9.3) qtide: <lang J> ;install each cut 'gl2 gles github:zerowords/tgsjo'</lang>

Implementation:

<lang J>load'zerowords/tgsjo' R_tgsjo_=: 0 0 _90 EYE_tgsjo_=: 0 0 30 clearscreen createTurtle 0 0 0

rectangle=: {{

   2 repeats {{ 'width height'=. y
       forward height
       left 90
       forward width 
       left 90 }} y

}}

square=: {{size=. y

    rectangle size,size

}}

triangle=:{{

 3 repeats {{size=. y
       forward size 
       right 120}} y

}}

house=:{{size=. y

   left 90
   square size
   triangle size
   right 90

}}

barchart=: {{'lst size'=. y

   if.#lst do.
       scale=. size%>./lst
       width=. size%#lst
       right 90
       for_j. lst do.
           rectangle (j * scale),width
           forward width
       end.
       back size
       left 90
   end.

}}

penColor Red house 150 pen 0 right 90 forward 10 left 90 pen 1 [ penColor Blue barchart 0.5 0.3333 2 1.3 0.5; 200 pen 0 left 90 back 10 right 90 turtleScale 0</lang>

Opens a window with the indicated content. House is red, barchart is blue.

Julia

Translation of: Wren

Outputs a PNG file. <lang julia>using Luxor, Colors

function house(🐒, x, y, siz)

   oldorientation = 🐒.orientation
   xpos, ypos = 🐒.xpos, 🐒.ypos
   # house wall
   Reposition(🐒, x, y)
   Rectangle(🐒, siz, siz)
   # roof
   Reposition(🐒, x - siz / 2, y -  siz / 2)
   Turn(🐒, -60)
   Forward(🐒, siz)
   Turn(🐒, 120)
   Forward(🐒, siz)
   # turtle_demo
   doorheight, doorwidth = siz / 2, siz / 4
   Pencolor(🐒, 0, 0, 0)
   Reposition(🐒, x, y + doorheight / 2)
   Rectangle(🐒, doorwidth, doorheight)
   # window
   windowheight, windowwidth = siz /3, siz / 4
   Reposition(🐒, x + siz / 4, y - siz / 4)
   Rectangle(🐒, windowwidth, windowheight)
   Reposition(🐒, x - siz / 4, y - siz / 4)
   Rectangle(🐒, windowwidth, windowheight)
   Orientation(🐒, oldorientation)
   Reposition(🐒, xpos, ypos)

end

function barchart(🐒, data, x, y, siz)

   oldorientation = 🐒.orientation
   xpos, ypos = 🐒.xpos, 🐒.ypos
   maxdata = maximum(data)
   # scale to fit within a square with sides `siz` and draw bars of chart
   barwidth = siz / length(data)
   Pencolor(🐒, 1.0, 0.0, 0.5)
   Reposition(🐒, x, y)
   for n in data  # draw each bar in chart
       barheight = n * siz / maxdata
       Reposition(🐒, x, y - barheight / 2)
       Rectangle(🐒, barwidth, barheight)
       x += barwidth
   end
   Orientation(🐒, oldorientation)
   Reposition(🐒, xpos, ypos)

end

function testturtle(width = 400, height = 600)

   dra = Drawing(600, 400, "turtle_demo.png")
   origin()
   background("midnightblue")
   🐒 = Turtle()
   Pencolor(🐒, "cyan")
   Penwidth(🐒, 1.5)
   house(🐒, -width / 3, height / 7, width / 2)
   barchart(🐒, [15, 10, 50, 35, 20], width / 8, height / 8, width / 2)
   finish()

end

testturtle() </lang>

Translation of: Quackery

<lang Logo>to rectangle :width :height

   repeat 2 [
       forward :height
       left 90
       forward :width 
       left 90 ]
   end

to square :size

   rectangle size size
   end

to triangle :size

   repeat 3 [ 
       forward size 
       right 120 ] 
    end

to house :size

   left 90
   square size
   triangle size
   right 90
   end

to max :lst

  if equalp count lst 1 [ output first lst ]
  make "x max butfirst lst 
  if x > first lst [ output x ] 
  output first lst   
  end

to barchart :lst :size

   right 90
   if emptyp lst [ stop ]
   make "scale size / (max lst)
   make "width size / count lst
   foreach lst [ 
       rectangle ? * scale width 
       forward width ]
   back size
   left 90
   end

clearscreen hideturtle house 150 penup right 90 forward 10 left 90 pendown barchart [ 0.5 0.33333 2 1.3 0.5 ] 200 left 90 back 10 right 90</lang>

Output:

https://imgur.com/4V1UrcN

Perl

Added octangle window to house attic. <lang perl>#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Simple_turtle_graphics use warnings; use Tk; use List::Util qw( max );

my $c; # the canvas

  1. turtle routines

my $pen = 1; # true for pendown, false for penup my @location = (0, 0); # upper left corner my $direction = 0; # 0 for East, increasing clockwise 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 ) }

  1. make window

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 );
 }</lang>

Phix

Library: Phix/pGUI
Library: Phix/online

You can run this online here.

--
-- demo\rosetta\Simple_turtle_graphics.exw
-- =======================================
--
with javascript_semantics
include pGUI.e
Ihandle canvas, dlg
cdCanvas cdcanvas

atom x = 0,
     y = 0,
     direction = 0
bool pen_down = true

procedure walk(atom distance)
    //
    // Move forward by distance pixels.
    //
    atom start_x = x,
         start_y = y,
         angle = direction*PI/180
    x += distance*sin(angle)
    y += distance*cos(angle)
    if pen_down then
        cdCanvasLine(cdcanvas,start_x,start_y,x,y)
    end if
end procedure

procedure right(atom angle)
    direction = remainder(direction+angle,360)
end procedure

procedure left(atom angle)
    right(360-angle)
end procedure

procedure penup()
    pen_down = false
end procedure

procedure pendown(atom colour=CD_BLACK)
    pen_down = true
    cdCanvasSetForeground(cdcanvas, colour) 
end procedure

procedure move(sequence s)
    -- s is a list of angles (odd elements)
    --        and distances (even elements)
    for i=1 to length(s) do
        if odd(i) then
            right(s[i])
        else
            walk(s[i])
        end if
    end for
end procedure

procedure rectangle(atom width, height)
    move({0,height,90,width,90,height,90,width,90})
end procedure

procedure draw_house(atom width, height)
    //
    // Draw a house at the current x,y
    // direction must be 0 for house to be upright
    //
    // house walls
    rectangle(width, height)
    // door (maybe some windows too would be nice...)
    penup()
    move({90,width/7,-90})
    pendown(CD_BLUE)
    rectangle(width/8,height/2.5)
    penup()
    move({-90,width/7,90})
    // roof
    walk(height)
    pendown(CD_RED)
    atom a = arctan(width/height)*CD_RAD2DEG,
         d = sqrt(width*width+height*height)/2
    move({a,d,180-a*2,d})
    penup()
    // return to origin({qw,qh}) and direction 0:
    move({90+a,width,-90,height,180})
end procedure

procedure draw_barchart(sequence nums, atom w, h)
    // draw a barchart occupying the middle 60% of w,h
    // nums can contain +ve and/or -ve values.
    integer n = length(nums)
    atom mx = max(max(nums),0),
         mn = min(min(nums),0),
         r = mx-mn,                 -- range
         zl = abs(mn)/r*h*0.6+h/5,  -- zero line
         bw = w*0.6/n               -- bar width
    move({90,w/5,-90,zl})
    pendown()
    for i=1 to n do
        atom ni = nums[i]/r*h*0.6
        if ni>0 then
            rectangle(bw,ni)
        else
            pendown(CD_RED)
            right(90)
            rectangle(-ni,bw)
            left(90)
            pendown(CD_BLACK)
        end if
        move({90,bw,-90})
    end for
    penup()
    // return to origin({w/2,0}) and direction 0:
    move({180,zl,90,w/5+bw*n,90})
end procedure

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")
    cdCanvasActivate(cdcanvas)
    cdCanvasClear(cdcanvas)
    atom qw = width/4,
         qh = height/4
    penup()
    move({0,qh,90,qw,-90})
    pendown()

    draw_house(qw,qh)       -- (at current x,y)

    penup()
    move({180,qh,90,qw,90}) -- return to {0,0}

    move({90,width/2,-90})  -- barchart in the right half

    draw_barchart({0.5, -4/3, 2, 1.3, 0.5},width/2,height)

    move({-90,width/2,90})  -- return to {0,0}

    -- sanity checks
    if round(x)!=0 then ?9/0 end if
    if round(y)!=0 then ?9/0 end if
    if round(direction)!=0 then ?9/0 end if

    cdCanvasFlush(cdcanvas)
    return IUP_DEFAULT
end function
IupOpen()
canvas = IupCanvas(Icallback("redraw_cb"),"RASTERSIZE=600x400")
dlg = IupDialog(canvas,`TITLE="Simple turtle graphics"`)
IupMap(dlg)
cdcanvas = cdCreateCanvas(CD_IUP, canvas)
IupShow(dlg)
IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
if platform()!=JS then
    IupMainLoop()
    IupClose()
end if

Python

Translation of: Quackery

<lang Python>from turtle import *

def rectangle(width, height):

   for _ in range(2):
       forward(height)
       left(90)
       forward(width)
       left(90)

def square(size):

   rectangle(size, size)

def triangle(size):

   for _ in range(3):
       forward(size)
       right(120)
   

def house(size):

   right(180)
   square(size)
   triangle(size)
   right(180)
   

def barchart(lst, size):

   scale = size/max(lst)
   width = size/len(lst)
   for i in lst:
       rectangle(i*scale, width)
       penup()
       forward(width)
       pendown()
   penup()
   back(size)
   pendown()
   

clearscreen() hideturtle() house(150) penup() forward(10) pendown() barchart([0.5, (1/3), 2, 1.3, 0.5], 200) penup() back(10) pendown()</lang>

Output:

https://imgur.com/oBXTDem

Quackery

<lang Quackery> [ $ "turtleduck.qky" loadfile ] now!

 [ behead do
   rot witheach
     [ do 2over 2over
       v< if 2swap 
       2drop ] ]                 is largest   (       [ --> n/d )
 [ 2 times 
   [ 2dup walk
     -1 4 turn
     2over walk 
     -1 4 turn ] 
   2drop 2drop ]                 is rectangle ( n/d n/d -->     ) 
 [ 2dup rectangle ]              is square    (     n/d -->     )
 [ 3 times 
    [ 2dup walk 
      1 3 turn ] 
   2drop ]                       is triangle  (    n/d  -->     )
 [ 1 2 turn 
   2dup square triangle 
   1 2 turn ]                    is house     (     n/d -->     )
 [ stack ]                       is bar.width (         --> s   )
 [ stack ]                       is bar.scale (         --> s   )
 [ join temp put
   dup size n->v 
   temp share do v/ 1/v
   join bar.width put
   dup largest
   temp share do v/
   join bar.scale put    
   witheach 
     [ do 
       bar.scale share do v/
       bar.width share do
       rectangle
       bar.width share do fly ]
   temp take do -v fly
   bar.width release
   bar.scale release ]          is barchart  (   [ n/d -->     )
  turtle
  150 1 house
  10 1 fly
  ' [ [ 1 2 ] [ 1 3 ] [ 2 1 ] [ 13 10 ] [ 1 2 ] ] 200 1 barchart
  -10 1 fly</lang>
Output:

https://imgur.com/B7YbTbZ

Wren

Library: DOME
Library: Wren-turtle

<lang ecmascript>import "dome" for Window import "graphics" for Canvas, Color import "./turtle" for Turtle

class Main {

   construct new(width, height) {
       Window.resize(width, height)
       Canvas.resize(width, height)
       Window.title = "Simple turtle graphics"
       _w = width
       _h = height
   }
   init() {
       Canvas.cls(Color.white)
       _t = Turtle.new()
       drawHouse(_w/4)
       barChart([15, 10, 50, 35, 20], _w/3)
   }
   drawHouse(size) {
       // save initial turtle position and direction
       var saveX = _t.x
       var saveY = _t.y
       var saveD = _t.dir

       _t.pen.width = 2
       // draw house
       _t.drawRect(_w/4, _h/2, size, size)
       // draw roof
       _t.right(30)
       _t.walk(size)
       _t.right(120)
       _t.walk(size)
       // draw door
       var doorWidth  = (size/4).floor
       var doorHeight = (size/2).floor
       _t.drawRect(_w/4 + doorWidth/2, _h/2 + doorHeight, doorWidth, doorHeight)
       // draw window
       var windWidth  = (size/3).floor
       var windHeight = (size/4).floor
       _t.drawRect(_w/4 + size/2, _h/2 + size/2, windWidth, windHeight)
       // restore initial turtle position and direction
       _t.x = saveX
       _t.y = saveY
       _t.dir = saveD
   }
   // nums assumed to be all non-negative
   barChart(nums, size) {
       // save intial turtle position and direction
       var saveX = _t.x
       var saveY = _t.y
       var saveD = _t.dir
       // find maximum
       var max = 0
       for (n in nums) if (n > max) max = n
       // scale to fit within a square with sides 'size' and draw chart
       var barWidth = (size / nums.count).floor
       var startX = _w / 2 + 20
       var startY = _h / 2
       for (i in 0...nums.count) {
           var barHeight = (nums[i] * size / max).round
           _t.drawRect(startX, startY - barHeight, barWidth, barHeight)
           startX = startX + barWidth
       }
       // restore intial turtle position and direction
       _t.x = saveX
       _t.y = saveY
       _t.dir = saveD
   }
   update() {}
   draw(alpha) {}

}

var Game = Main.new(600, 600)</lang>

Output:
Similar to Quackery image except that the house has a door and a single window.

Yabasic

Translation of: Python

<lang Yabasic>// Rosetta Code problem: http://rosettacode.org/wiki/Simple_turtle_graphics // Adapted from Python to Yabasic by Galileo, 01/2022

import turtle

sub rectang(width, height)

   local i
   
   for i = 1 to 2
       move(height)
       turn(-90)
       move(width)
       turn(-90)
   next

end sub

sub square(size)

   rectang(size, size)

end sub

sub triang(size)

   local i
   
   for i = 1 to 3
       move(size)
       turn(120)
   next

end sub

sub house(size)

   turn(180)
   square(size)
   triang(size)
   turn(180)

end sub

sub barchart(lst$, size)

   local t$(1), t(1), n, m, i, scale, width
   
   n = token(lst$, t$())
   redim t(n)
   
   for i = 1 to n
       t(i) = val(t$(i))
       if t(i) > m m = t(i)
   next
   
   scale = size/m
   width = size/n
   for i = 1 to n
       rectang(t(i)*scale, width)
       pen(false)
       move(width)
       pen(true)
   next
   pen(false)
   move(-size)
   pen(true)

end sub

startTurtle() color 255, 255, 255 turn(90) house(150) pen(false) move(10) pen(true) barchart("0.5 0.333 2 1.3 0.5", 200)</lang>