[racket] [BULK] keyboard input from user

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Sun Oct 3 23:21:57 EDT 2010

On Oct 3, 2010, at 9:23 PM, 김태윤 wrote:

> hello
> I'm trying to make program that receive keyboard input
> for making program little bit more fun
> as shown in the book, "how to design world"
> I wrote the code as like below
> it's just key comparing 
> I can't find how to receive keyinput from user in the book
> (define (printkey x)
>   (cond [(key=? x 'up)(print "up")]
>         [(key=? x 'down)(print "down")]
>         [(key=? x 'left)(print "left")]
>         [(key=? x 'right)(print "right")]
>         [(key=? x 'a)(print "a")]
>         [(key=? x 's)(print "s")]
>         [(key=? x 'd)(print "d")]
>         [(key=? x 'f)(print "f")]
>         [(key=? x 'z)(print "z")]
>         [(key=? x 'x)(print "x")]))
> could you let me know how to receive keyboard input from user?
> and how to iterate it?

As others have pointed out, the current version of the universe teachpack uses strings rather than symbols, so you need "up", "down", etc. rather than 'up, 'down, etc.

More fundamentally, the universe teachpack uses an event-driven approach.  You don't "ask for keyboard input from the user" and "iterate it"; instead, you start a "world" and tell it that whenever it gets a key event, it should call such-and-such function of yours (the "key handler").  This function CAN print things with "print" (if you're in the right language), but that's not the way it's typically used: in most cases, it is given a "current model", and it returns a "new model" after the key event.  Meanwhile, you've provided another called the "draw handler", which will be called automatically every time the model changes, and its output is shown on the screen.

For example, if you just want to see the last key that was pressed,

(require 2htdp/image)
(require 2htdp/universe)

; For this animation, the model is a string.

; Draw handler: string -> image
(check-expect (handle-draw "hello") (text "hello" 18 "blue"))
(check-expect (handle-draw "right") (text "right" 18 "blue"))
(define (handle-draw model) (text model 18 "blue"))

; Key handler: string(old-model) string(key) -> string(new-model)
; Our key handler will ignore the old model and simply return the key.
(check-expect (handle-key "hello" "right") "right")
(define (handle-key old-model key) key)

; Now let's run the animation.
(big-bang ""                           ; initial model is empty string
          (check-with string?)         ; model is a string
          (on-draw handle-draw 150 50) ; display text in 150x50 pixel window
          (on-key handle-key))

If you actually wanted to do something interesting depending on the key, your key handler would have a "cond" like what you've written above, but each case would return the appropriate new model (depending on what you wanted to accomplish) rather than printing something on the console.

Stephen Bloch
sbloch at adelphi.edu

Posted on the users mailing list.