[plt-scheme] tetris

From: Matthias Felleisen (matthias at ccs.neu.edu)
Date: Wed Feb 27 08:23:15 EST 2008

That's what we're hoping will happen here. Ever since
we started using the functional animation package, I
see students working on their programs after the
semester is over. Not too many, but a bunch.

-- Matthias




On Feb 27, 2008, at 4:15 AM, Benjamin L. Russell wrote:

> This reminds me of the project "Schemetris" I wrote
> with one classmate as a final project for a Computer
> Science class back at Yale in 1994.  That one was
> written in MIT Scheme, though, and at least some of
> the libraries were pre-provided.
>
> I slept only 3 hours per day for 3 days to get it
> done.  My classmate gave me the function
> specifications, and I wrote the functions.  The
> project was a great success, and motivated me to
> return to studying Scheme over a decade afterward.
>
> Benjamin L. Russell
>
> --- Jon Rafkind <workmin at ccs.neu.edu> wrote:
>
>> I thought the recently uploaded tetris game to
>> planet was fun so I
>> converted it to use the Allegro package instead of
>> htdp. Theres not
>> really much of a point and its not like it runs
>> better or anything, but
>> it was good to compare htdp's functional style with
>> Allegro's mostly
>> imperative style. It probably won't work too well in
>> osx.
>>
>> Tetris on planet:
>>
> http://planet.plt-scheme.org/display.ss? 
> package=tetris.plt;owner=dvanhorn
>>
>> Code attached if you want to try it.
>>> (module tetris2 mzscheme
>>
>> 	(require (planet "util.ss" ("kazzmir"
>> "allegro.plt")))
>> 	(require (prefix keyboard- (planet "keyboard.ss"
>> ("kazzmir" "allegro.plt"))))
>> 	(require (prefix image- (planet "image.ss"
>> ("kazzmir" "allegro.plt"))))
>> 	(require (lib "list.ss"))
>>
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;; Defined constants
>> (define-struct posn (x y))
>>
>> (define block-size   20)  ;; in Pixels
>> (define board-width  10)  ;; in Blocks
>> (define board-height 20)
>>
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;; Data Definitions
>>
>> ;; A Block is a (make-block Number Number Color)
>> (define-struct block (x y color))
>>
>> ;; A Tetra is a (make-tetra Posn BSet)
>> ;; The center point is the point around which the
>> tetra rotates
>> ;; when it is rotated.
>> (define-struct tetra (center blocks))
>>
>> ;; A Set of Blocks (BSet) is one of:
>> ;; - empty
>> ;; - (cons Block BSet)
>> ;; Order does not matter.  Repetitions are NOT
>> allowed.
>>
>> ;; A World is a (make-world Tetra BSet)
>> (define-struct world (tetra blocks))
>>
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;; Blocks
>>
>> ;; block=? : Block Block -> Boolean
>> ;; Determines if two blocks are the same (ignoring
>> color).
>> (define (block=? b1 b2)
>>   (and (= (block-x b1) (block-x b2))
>>        (= (block-y b1) (block-y b2))))
>>
>> ;; block-move : Number Number Block -> Block
>> (define (block-move dx dy b)
>>   (make-block (+ dx (block-x b))
>>               (+ dy (block-y b))
>>               (block-color b)))
>>
>> ;; block-rotate-ccw : Posn Block -> Block
>> ;; Rotate the block 90 counterclockwise around the
>> posn.
>> (define (block-rotate-ccw c b)
>>   (make-block (+ (posn-x c)
>> 		 (- (posn-y c)
>> 		    (block-y b)))
>> 	      (+ (posn-y c)
>> 		 (- (block-x b)
>> 		    (posn-x c)))
>> 	      (block-color b)))
>>
>> ;; block-rotate-cw : Posn Block -> Block
>> ;; Rotate the block 90 clockwise around the posn.
>> (define (block-rotate-cw c b)
>>   (block-rotate-ccw c (block-rotate-ccw c
>> (block-rotate-ccw c b))))
>>
>>
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;; Sets of blocks
>>
>> ;; blocks-contains? : BSet Block -> Boolean
>> (define (blocks-contains? bs b)
>>   (ormap (lambda (c) (block=? b c)) bs))
>>
>> ;; blocks-subset? : BSet BSet -> Boolean
>> ;; is every element in bs1 also in bs2?
>> (define (blocks-subset? bs1 bs2)
>>   (andmap (lambda (b) (blocks-contains? bs2 b))
>> bs1))
>>
>> ;; blocks=? : BSet BSet -> Boolean
>> (define (blocks=? bs1 bs2)
>>    (and (blocks-subset? bs1 bs2)
>>         (blocks-subset? bs2 bs1)))
>>
>> ;; blocks-intersect : BSet BSet -> BSet
>> ;; Return the set of blocks that appear in both
>> sets.
>> (define (blocks-intersect bs1 bs2)
>>   (filter (lambda (b) (blocks-contains? bs2 b))
>> bs1))
>>
>> ;; blocks-union : BSet BSet -> BSet
>> ;; Union the two sets of blocks.
>> (define (blocks-union bs1 bs2)
>>   (foldr (lambda (b bs)
>>            (cond [(blocks-contains? bs b) bs]
>>                  [else (cons b bs)]))
>>          bs2
>>          bs1))
>>
>> ;; blocks-counts : BSet -> Nat
>> ;; Return the number of blocks in the set.
>> (define (blocks-count bs)
>>   (length bs))  ;; No duplicates, cardinality =
>> length.
>>
>> ;; blocks-max-y : BSet -> Number
>> ;; Compute the maximum y coordinate;
>> ;; if set is empty, return 0, the coord of the
>> board's top edge.
>> (define (blocks-max-y bs)
>>   (foldr (lambda (b n) (max (block-y b) n)) 0 bs))
>>
>> ;; blocks-min-x : BSet -> Number
>> ;; Compute the minimum x coordinate;
>> ;; if set is empty, return the coord of the board's
>> right edge.
>> (define (blocks-min-x bs)
>>   (foldr (lambda (b n) (min (block-x b) n))
>> board-width bs))
>>
>> ;; blocks-max-x : BSet -> Number
>> ;; Compute the maximum x coordinate;
>> ;; if set is empty, return 0, the coord of the
>> board's left edge.
>> (define (blocks-max-x bs)
>>   (foldr (lambda (b n) (max (block-x b) n)) 0 bs))
>>
>> ;; blocks-move : Number Number BSet -> BSet
>> ;; Move each block by the given X & Y displacement.
>> (define (blocks-move dx dy bs)
>>   (map (lambda (b) (block-move dx dy b)) bs))
>>
>> ;; blocks-rotate-ccw : Posn BSet -> BSet
>> ;; Rotate the blocks 90 counterclockwise around the
>> posn.
>> (define (blocks-rotate-ccw c bs)
>>   (map (lambda (b) (block-rotate-ccw c b)) bs))
>>
>> ;; blocks-rotate-cw : Posn BSet -> BSet
>> ;; Rotate the blocks 90 clockwise around the posn.
>> (define (blocks-rotate-cw c bs)
>>   (map (lambda (b) (block-rotate-cw c b)) bs))
>>
>> ;; blocks-change-color : BSet Color -> BSet
>> (define (blocks-change-color bs c)
>>   (map (lambda (b) (make-block (block-x b)
>>                                (block-y b)
>>                                c))
>>        bs))
>>
>> ;; blocks-overflow? : BSet -> Boolean
>> ;; Have any of the blocks reach over the top of the
>> board?
>> (define (blocks-overflow? bs)
>>   (ormap (lambda (b) (<= (block-y b) 0)) bs))
>>
>> ;; blocks-row : BSet Number -> BSet
>> ;; Return the set of blocks in the given row.
>> (define (blocks-row bs i)
>>   (filter (lambda (b) (= i (block-y b))) bs))
>>
>> ;; full-row? : BSet Nat -> Boolean
>> ;; Are there a full row of blocks at the given row
>> in the set.
>> (define (full-row? bs i)
>>   (= board-width (blocks-count (blocks-row bs i))))
>>
>> ;; eliminate-full-rows : BSet -> BSet
>> ;; Eliminate all full rows and shift down
>> appropriately.
>> (define (eliminate-full-rows bs)
>>   (define (elim-row i offset)
>>             (cond [(< i 0) empty]
>>                   [(full-row? bs i)   (elim-row
>> (sub1 i) (add1 offset))]
>>                   [else (blocks-union (elim-row
>> (sub1 i) offset)
>>                                       (blocks-move 0
>> offset (blocks-row bs i)))]))
>>     (elim-row board-height 0))
>>
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> ;; Tetras
>>
>> ;; tetra-move : Number Number Tetra -> Tetra
>> ;; Move the Tetra by the given X & Y displacement.
>> (define (tetra-move dx dy t)
>>   (make-tetra (make-posn (+ dx (posn-x (tetra-center
>> t)))
>> 			 (+ dy (posn-y (tetra-center t))))
>> 	      (blocks-move dx dy (tetra-blocks t))))
>>
>>
> === message truncated ===>
> _________________________________________________
>>   For list-related administrative tasks:
>>
>> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>>
>
> _________________________________________________
>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme



Posted on the users mailing list.