HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Simple terminal graphics line drawing

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simpleterminallinegraphicsdrawing

Problem

The program starts at the center of the screen and starts drawing a line in 50ms steps. When the line hits the edge of the terminal it will be reflected and continue drawing. steps takes the number of drawing steps to perform before finishing while until-key finishes on a key press.

Apart from the lack of comments, what would I need to do to make this "good" Forth and how would I change it to fit in one screen (16 lines of 64 chars)?

variable h
variable w
: height h @ ;
: width  w @ ;

variable point-var
cell allot
: point ( offset -- addr ) cells point-var + ;

variable direction-var
cell allot
: dir ( offset -- addr ) cells direction-var + ;

: init ( -- )
    rows h !
    cols w !
    width  2 / 0 point !
    height 2 / 1 point !
    1 0 dir !
    1 1 dir ! ;

: reflect-top ( -- t/f )
    1 point @ 0= dup if 1 1 dir ! then invert ;
: reflect-bot ( -- t/f )
    1 point @ height 1 - = if -1 1 dir ! then ;
: reflect-left ( -- t/f )
    0 point @ width 1 - = if -1 0 dir ! then ;
: reflect-right ( -- t/f )
    0 point @ 0= dup if 1 0 dir ! then invert ;
: reflect ( -- )
    reflect-top if reflect-bot then
    reflect-right if reflect-left then ;

: draw-point ( -- ) [char] # emit ;

: move-x ( -- n ) 0 point @ 0 dir @ + dup 0 point ! ;
: move-y ( -- n ) 1 point @ 1 dir @ + dup 1 point ! ;
: move-xy ( -- ) move-x move-y at-xy ;

: try ;

: step ( -- )
    try reflect
    move-xy draw-point ;

: steps ( n -- )
    init
    page
    0 do step 50 ms loop ;

: until-key ( n -- )
    init
    page
    begin step 50 ms key? until ;

Solution

-
Magic numbers

0 constant X
    1 constant Y


looks more attractive than naked 0 and 1. I suppose (sorry can't test it right now) it may let you unify move-x with move-y, as well as reflects.

-
Height and width

: height= h @ 1 - = ;
    : width=  w @ 1 - = ;


allow more symmetric definition of reflects:

: reflect-top Y point @ 0=      dup  if  1 1 dir ! then invert ;
    : reflect-bot Y point @ height=      if -1 1 dir ! then ;


Now it looks like they have different stack effects, which is strange. Are you sure reflect-bot doesn't miss dup?

-
move-*

I'd rearrange pushes, e.g.

: move-x 0 0 0 point @ dir @ + dup point ! ;
    : move-y 1 1 1 point @ dir @ + dup point ! ;


which really prompts for a point @ dir @ + dup point ! word. move-in-dir perhaps?

-
One screen

Do modern Forthers still care about screens?

Code Snippets

0 constant X
    1 constant Y
: height= h @ 1 - = ;
    : width=  w @ 1 - = ;
: reflect-top Y point @ 0=      dup  if  1 1 dir ! then invert ;
    : reflect-bot Y point @ height=      if -1 1 dir ! then ;
: move-x 0 0 0 point @ dir @ + dup point ! ;
    : move-y 1 1 1 point @ dir @ + dup point ! ;

Context

StackExchange Code Review Q#124788, answer score: 3

Revisions (0)

No revisions yet.