|
|
|
@ -1,20 +1,23 @@
|
|
|
|
|
#lang debug racket/base
|
|
|
|
|
(require racket/contract racket/function rackunit)
|
|
|
|
|
|
|
|
|
|
(struct $posn (x y) #:transparent)
|
|
|
|
|
(struct $point (x y) #:transparent #:mutable)
|
|
|
|
|
(struct $size (width height) #:transparent #:mutable)
|
|
|
|
|
(struct $rect (origin size) #:transparent #:mutable)
|
|
|
|
|
|
|
|
|
|
(struct $quad (posn char) #:transparent #:mutable)
|
|
|
|
|
|
|
|
|
|
(define/contract (posn-add p0 p1)
|
|
|
|
|
($posn? $posn? . -> . $posn?)
|
|
|
|
|
($posn (+ ($posn-x p0) ($posn-x p1)) (+ ($posn-y p0) ($posn-y p1))))
|
|
|
|
|
($point? $size? . -> . $point?)
|
|
|
|
|
($point (+ ($point-x p0) ($size-width p1)) (+ ($point-y p0) ($size-height p1))))
|
|
|
|
|
|
|
|
|
|
(define/contract (size char)
|
|
|
|
|
($quad? . -> . $posn?)
|
|
|
|
|
($posn 1 1))
|
|
|
|
|
($quad? . -> . $size?)
|
|
|
|
|
($size 1 1))
|
|
|
|
|
|
|
|
|
|
(define/contract (advance char)
|
|
|
|
|
($quad? . -> . $posn?)
|
|
|
|
|
($posn 1 0))
|
|
|
|
|
($quad? . -> . $size?)
|
|
|
|
|
($size 1 0))
|
|
|
|
|
|
|
|
|
|
(define pass/c ((listof $quad?) . -> . (listof $quad?)))
|
|
|
|
|
|
|
|
|
@ -41,38 +44,36 @@
|
|
|
|
|
(error 'postcondition-failed))
|
|
|
|
|
res))
|
|
|
|
|
|
|
|
|
|
(struct $rect (x y width height) #:transparent #:mutable)
|
|
|
|
|
|
|
|
|
|
(define (min-x rect) ($rect-x rect))
|
|
|
|
|
(define (max-x rect) (+ (min-x rect) ($rect-width rect)))
|
|
|
|
|
(define (min-y rect) ($rect-y rect))
|
|
|
|
|
(define (max-y rect) (+ (min-y rect) ($rect-height rect)))
|
|
|
|
|
(define (min-x rect) ($point-x ($rect-origin rect)))
|
|
|
|
|
(define (width rect) ($size-width ($rect-size rect)))
|
|
|
|
|
(define (max-x rect) (+ (min-x rect) (width rect)))
|
|
|
|
|
(define (min-y rect) ($point-y ($rect-origin rect)))
|
|
|
|
|
(define (height rect) ($size-height ($rect-size rect)))
|
|
|
|
|
(define (max-y rect) (+ (min-y rect) (height rect)))
|
|
|
|
|
|
|
|
|
|
(define/contract (rect-contains-posn? rect posn)
|
|
|
|
|
($rect? $posn? . -> . boolean?)
|
|
|
|
|
(and (<= (min-x rect) ($posn-x posn) (max-x rect))
|
|
|
|
|
(<= (min-y rect) ($posn-y posn) (max-y rect))))
|
|
|
|
|
(define/contract (rect-contains-point? rect pt)
|
|
|
|
|
($rect? $point? . -> . boolean?)
|
|
|
|
|
(and (<= (min-x rect) ($point-x pt) (max-x rect))
|
|
|
|
|
(<= (min-y rect) ($point-y pt) (max-y rect))))
|
|
|
|
|
|
|
|
|
|
(define/contract (rect-contains-rect? outer inner)
|
|
|
|
|
($rect? $rect? . -> . boolean?)
|
|
|
|
|
(and (rect-contains-posn? outer ($posn (min-x inner) (min-y inner)))
|
|
|
|
|
(rect-contains-posn? outer ($posn (max-x inner) (max-y inner)))))
|
|
|
|
|
(and (rect-contains-point? outer ($rect-origin inner))
|
|
|
|
|
(rect-contains-point? outer ($point (max-x inner) (max-y inner)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (has-position? q) (not (eq? ($quad-posn q) #false)))
|
|
|
|
|
(define-pass (layout qs)
|
|
|
|
|
#:precondition (λ (qs) (andmap (λ (q) (not (has-position? q))) qs))
|
|
|
|
|
#:postcondition (λ (qs) (andmap has-position? qs))
|
|
|
|
|
(define frame ($rect 0 0 5 30))
|
|
|
|
|
(define frame ($rect ($point 0 0) ($size 5 30)))
|
|
|
|
|
(define (quad-fits? q posn)
|
|
|
|
|
(define q-size (size q))
|
|
|
|
|
(define quad-rect ($rect ($posn-x posn) ($posn-y posn)
|
|
|
|
|
($posn-x q-size) ($posn-y q-size)))
|
|
|
|
|
(define quad-rect ($rect posn q-size))
|
|
|
|
|
(and (rect-contains-rect? frame quad-rect) posn))
|
|
|
|
|
(for/fold ([posn ($posn 0 0)]
|
|
|
|
|
(for/fold ([posn ($point 0 0)]
|
|
|
|
|
#:result qs)
|
|
|
|
|
([q (in-list qs)])
|
|
|
|
|
(define first-posn-on-next-line ($posn 0 (add1 ($posn-y posn))))
|
|
|
|
|
(define first-posn-on-next-line ($point 0 (add1 ($point-y posn))))
|
|
|
|
|
(define winning-posn (or (ormap (λ (posn) (quad-fits? q posn)) (list posn first-posn-on-next-line)) (error 'no-posn-that-fits)))
|
|
|
|
|
(set-$quad-posn! q winning-posn)
|
|
|
|
|
(posn-add winning-posn (advance q))))
|
|
|
|
@ -80,14 +81,14 @@
|
|
|
|
|
(define compile (make-compiler layout))
|
|
|
|
|
(check-equal? (compile "Hello world")
|
|
|
|
|
(list
|
|
|
|
|
($quad ($posn 0 0) #\H)
|
|
|
|
|
($quad ($posn 1 0) #\e)
|
|
|
|
|
($quad ($posn 2 0) #\l)
|
|
|
|
|
($quad ($posn 3 0) #\l)
|
|
|
|
|
($quad ($posn 4 0) #\o)
|
|
|
|
|
($quad ($posn 0 1) #\space)
|
|
|
|
|
($quad ($posn 1 1) #\w)
|
|
|
|
|
($quad ($posn 2 1) #\o)
|
|
|
|
|
($quad ($posn 3 1) #\r)
|
|
|
|
|
($quad ($posn 4 1) #\l)
|
|
|
|
|
($quad ($posn 0 2) #\d)))
|
|
|
|
|
($quad ($point 0 0) #\H)
|
|
|
|
|
($quad ($point 1 0) #\e)
|
|
|
|
|
($quad ($point 2 0) #\l)
|
|
|
|
|
($quad ($point 3 0) #\l)
|
|
|
|
|
($quad ($point 4 0) #\o)
|
|
|
|
|
($quad ($point 0 1) #\space)
|
|
|
|
|
($quad ($point 1 1) #\w)
|
|
|
|
|
($quad ($point 2 1) #\o)
|
|
|
|
|
($quad ($point 3 1) #\r)
|
|
|
|
|
($quad ($point 4 1) #\l)
|
|
|
|
|
($quad ($point 0 2) #\d)))
|