spacebar invaders (without aliens...) added by saeftl on Tue Apr 22 16:09:24 2014

(use posix posix-extras ncurses srfi-25 srfi-1)

(define cols #f)

(define lines #f)

(define (drawline xx yy z . char)
  (map (lambda (c)
         (mvaddch
           (+ xx c)
           yy
           (if (null? char) (integer->char (+ 65 (list-ref z c))) (car char))))
       (iota (length z))))

(define (blankline xx yy z) (drawline xx yy z (integer->char 32)))

(define (drawshape shape x y oldx oldy)
  (when (>= oldx 0)
        (begin
          (map (lambda (e) (blankline oldx (+ oldy (car e)) (cadr e)))
               (zip (iota (length shape)) shape))
          (refresh)))
  (map (lambda (e) (drawline x (+ y (car e)) (cadr e)))
       (zip (iota (length shape)) shape))
  (refresh)
  (list x y))

(set! shooter (list (list -33 1 2) (list 2 2 2) (list -33 0 2)))

(define (spaceship x y oldx oldy)
  (let ((ss shooter)) (drawshape ss x y oldx oldy)))

(define (b-update bullets)
  (remove
    null?
    (map (lambda (b)
           (let ((x (car b)) (y (- (cadr b) 1)))
             (if (< y 1)
               (begin (mvaddch (+ y 1) x #\space) '())
               (begin
                 (mvaddch (+ y 1) x #\space)
                 (mvaddch y x #\|)
                 (list x y)))))
         bullets)))

(define (main)
  (initscr)
  (cbreak)
  (noecho)
  (nodelay (stdscr) #t)
  (keypad (stdscr) #t)
  (curs_set 0)
  (set! cols (- (COLS) 20))
  (set! lines (LINES))
  (set! ENDX (sub1 cols))
  (set! ENDY (sub1 lines))
  (set! oxy (list -1 -1))
  (set! y 30)
  (set! last (current-milliseconds))
  (set! bullets (list (list 20 20)))
  (set! bullets '())
  (wrefresh (stdscr))
  (mvaddstr
    35
    11
    "PRESS q TO QUIT      h TO MOVE LEFT      l TO MOVE RIGHT    SPACE TO FIRE")
  (spaceship y 20 -1 -1)
  (do ((nx 20) (c (getch) (getch)))
      ((eq? c #\q) '())
    (begin
      (set! ox nx)
      (if (eq? c ERR) (sleep 0.01))
      (if (and (eq? c #\h) (> ox 1)) (set! nx (- ox 1)))
      (if (and (eq? c #\l) (< ox cols)) (set! nx (+ ox 1)))
      (if (eq? c #\space)
        (set! bullets
          (append
            (list (list (+ -1
                           ox
                           (inexact->exact (round (/ (length shooter) 2))))
                        (+ y (- (length (car shooter)) 4))))
            bullets)))
      (if (not (= nx ox)) (spaceship y nx y ox))
      (if (and (> (- (current-milliseconds) last) 1) (not (null? bullets)))
        (set! bullets (b-update bullets)))
      (set! last (current-milliseconds))))
  (wrefresh (stdscr))
  (endwin))

(main)