tetris: some cleanup, simplify.

master
John Benediktsson 2020-02-11 13:57:19 -08:00
parent d2ab01a5d9
commit 2e644a2c7b
5 changed files with 48 additions and 33 deletions

View File

@ -1,18 +1,23 @@
! Copyright (C) 2006, 2007, 2008 Alex Chapman ! Copyright (C) 2006, 2007, 2008 Alex Chapman
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays kernel math sequences tetris.piece ; USING: accessors arrays combinators.short-circuit fry kernel
math sequences tetris.piece ;
IN: tetris.board IN: tetris.board
TUPLE: board { width integer } { height integer } rows ; TUPLE: board
{ width integer }
{ height integer }
{ rows array } ;
: make-rows ( width height -- rows ) : make-rows ( width height -- rows )
<iota> [ drop f <array> ] with map ; swap '[ _ f <array> ] replicate ;
: <board> ( width height -- board ) : <board> ( width height -- board )
2dup make-rows board boa ; 2dup make-rows board boa ;
! A block is simply an array of form { x y } where { 0 0 } is the top-left of ! A block is simply an array of form { x y } where { 0 0 } is
! the tetris board, and { 9 19 } is the bottom right on a 10x20 board. ! the top-left of the tetris board, and { 9 19 } is the bottom
! right on a 10x20 board.
: board@block ( board block -- n row ) : board@block ( board block -- n row )
[ second swap rows>> nth ] keep first swap ; [ second swap rows>> nth ] keep first swap ;
@ -28,7 +33,7 @@ TUPLE: board { width integer } { height integer } rows ;
[ second swap height>> <iota> bounds-check? ] 2bi and ; [ second swap height>> <iota> bounds-check? ] 2bi and ;
: location-valid? ( board block -- ? ) : location-valid? ( board block -- ? )
2dup block-in-bounds? [ block-free? ] [ 2drop f ] if ; { [ block-in-bounds? ] [ block-free? ] } 2&& ;
: piece-valid? ( board piece -- ? ) : piece-valid? ( board piece -- ? )
piece-blocks [ location-valid? ] with all? ; piece-blocks [ location-valid? ] with all? ;
@ -49,6 +54,6 @@ TUPLE: board { width integer } { height integer } rows ;
[ [ row-not-full? ] filter ] change-rows ; [ [ row-not-full? ] filter ] change-rows ;
: check-rows ( board -- n ) : check-rows ( board -- n )
! remove full rows, then add blank ones at the top, returning the number ! remove full rows, then add blank ones at the top,
! of rows removed (and added) ! returning the number of rows removed (and added)
remove-full-rows dup height>> over rows>> length - swap top-up-rows ; remove-full-rows dup height>> over rows>> length - swap top-up-rows ;

View File

@ -1,6 +1,9 @@
! Copyright (C) 2006, 2007, 2008 Alex Chapman ! Copyright (C) 2006, 2007, 2008 Alex Chapman
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors combinators kernel lists math math.functions sequences system tetris.board tetris.piece tetris.tetromino ;
USING: accessors combinators kernel lists math math.functions
sequences system tetris.board tetris.piece tetris.tetromino ;
IN: tetris.game IN: tetris.game
TUPLE: tetris TUPLE: tetris
@ -19,7 +22,8 @@ CONSTANT: default-height 20
dupd <board> swap <piece-llist> dupd <board> swap <piece-llist>
tetris new swap >>pieces swap >>board ; tetris new swap >>pieces swap >>board ;
: <default-tetris> ( -- tetris ) default-width default-height <tetris> ; : <default-tetris> ( -- tetris )
default-width default-height <tetris> ;
: <new-tetris> ( old -- new ) : <new-tetris> ( old -- new )
board>> [ width>> ] [ height>> ] bi <tetris> ; board>> [ width>> ] [ height>> ] bi <tetris> ;
@ -31,11 +35,11 @@ CONSTANT: default-height 20
: toggle-pause ( tetris -- ) : toggle-pause ( tetris -- )
[ not ] change-paused? drop ; [ not ] change-paused? drop ;
: level>> ( tetris -- level ) : level ( tetris -- level )
rows>> 1 + 10 / ceiling ; rows>> 1 + 10 / ceiling ;
: update-interval ( tetris -- interval ) : update-interval ( tetris -- interval )
level>> 1 - 60 * 1,000,000,000 swap - ; level 1 - 60 * 1,000,000,000 swap - ;
: add-block ( tetris block -- ) : add-block ( tetris block -- )
over [ board>> ] 2dip current-piece tetromino>> colour>> set-block ; over [ board>> ] 2dip current-piece tetromino>> colour>> set-block ;
@ -60,7 +64,7 @@ CONSTANT: default-height 20
} case swap 1 + * ; } case swap 1 + * ;
: add-score ( tetris n-rows -- tetris ) : add-score ( tetris n-rows -- tetris )
over level>> swap rows-score swap [ + ] change-score ; over level swap rows-score swap [ + ] change-score ;
: add-rows ( tetris rows -- tetris ) : add-rows ( tetris rows -- tetris )
swap [ + ] change-rows ; swap [ + ] change-rows ;
@ -69,8 +73,8 @@ CONSTANT: default-height 20
[ add-score ] keep add-rows drop ; [ add-score ] keep add-rows drop ;
: lock-piece ( tetris -- ) : lock-piece ( tetris -- )
[ dup current-piece piece-blocks [ add-block ] with each ] keep [ dup current-piece piece-blocks [ add-block ] with each ]
new-current-piece dup board>> check-rows score-rows ; [ new-current-piece dup board>> check-rows score-rows ] bi ;
: can-rotate? ( tetris -- ? ) : can-rotate? ( tetris -- ? )
[ board>> ] [ current-piece clone 1 rotate-piece ] bi piece-valid? ; [ board>> ] [ current-piece clone 1 rotate-piece ] bi piece-valid? ;

View File

@ -1,8 +1,9 @@
! Copyright (C) 2006, 2007, 2008 Alex Chapman ! Copyright (C) 2006, 2007, 2008 Alex Chapman
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays combinators kernel math math.vectors USING: accessors arrays colors colors.constants combinators
namespaces opengl opengl.gl sequences tetris.board tetris.game kernel math opengl opengl.gl sequences tetris.game tetris.piece
tetris.piece ui.render tetris.tetromino ui.gadgets colors ; ;
IN: tetris.gl IN: tetris.gl
! OpenGL rendering for tetris ! OpenGL rendering for tetris
@ -22,24 +23,32 @@ IN: tetris.gl
! TODO: move implementation specific stuff into tetris-board ! TODO: move implementation specific stuff into tetris-board
: (draw-row) ( x y row -- ) : (draw-row) ( x y row -- )
overd nth dup overd nth [ gl-color 2array draw-block ] [ 2drop ] if* ;
[ gl-color 2array draw-block ] [ 3drop ] if ;
: draw-row ( y row -- ) : draw-row ( y row -- )
[ length <iota> swap ] keep [ (draw-row) ] 2curry each ; [ length <iota> swap ] keep [ (draw-row) ] 2curry each ;
: draw-board ( board -- ) : draw-board ( board -- )
rows>> [ length <iota> ] keep rows>> [ swap draw-row ] each-index ;
[ dupd nth draw-row ] curry each ;
: scale-board ( width height board -- ) : scale-board ( width height board -- )
[ width>> ] [ height>> ] bi swapd [ / ] dup 2bi* 1 glScalef ; [ width>> ] [ height>> ] bi swapd [ / ] dup 2bi* 1 glScalef ;
: set-background-color ( tetris -- )
dup running?>> [
paused?>> COLOR: light-gray COLOR: white ?
] [ drop COLOR: black ] if gl-color ;
: draw-background ( board -- )
[ 0 0 ] dip [ width>> ] [ height>> ] bi glRectf ;
: draw-tetris ( width height tetris -- ) : draw-tetris ( width height tetris -- )
! width and height are in pixels ! width and height are in pixels
[ [
{ {
[ board>> scale-board ] [ board>> scale-board ]
[ set-background-color ]
[ board>> draw-background ]
[ board>> draw-board ] [ board>> draw-board ]
[ next-piece draw-next-piece ] [ next-piece draw-next-piece ]
[ current-piece draw-piece ] [ current-piece draw-piece ]

View File

@ -1,11 +1,13 @@
! Copyright (C) 2006, 2007, 2008 Alex Chapman ! Copyright (C) 2006, 2007, 2008 Alex Chapman
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays kernel math math.vectors sequences tetris.tetromino lists.lazy ; USING: accessors arrays kernel math math.vectors sequences
tetris.tetromino lists.lazy ;
IN: tetris.piece IN: tetris.piece
! The rotation is an index into the tetromino's states array, and the ! The rotation is an index into the tetromino's states array,
! position is added to the tetromino's blocks to give them their location on the ! and the position is added to the tetromino's blocks to give
! tetris board. If the location is f then the piece is not yet on the board. ! them their location on the tetris board. If the location is f
! then the piece is not yet on the board.
TUPLE: piece TUPLE: piece
{ tetromino tetromino } { tetromino tetromino }
@ -35,12 +37,8 @@ TUPLE: piece
: <piece-llist> ( board-width -- llist ) : <piece-llist> ( board-width -- llist )
[ [ <random-piece> ] curry ] keep [ <piece-llist> ] curry lazy-cons ; [ [ <random-piece> ] curry ] keep [ <piece-llist> ] curry lazy-cons ;
: modulo ( n m -- n )
! -2 7 mod => -2, -2 7 modulo => 5
[ mod ] [ + ] [ mod ] tri ;
: (rotate-piece) ( rotation inc n-states -- rotation' ) : (rotate-piece) ( rotation inc n-states -- rotation' )
[ + ] dip modulo ; [ + ] dip rem ;
: rotate-piece ( piece inc -- piece ) : rotate-piece ( piece inc -- piece )
over tetromino>> states>> length over tetromino>> states>> length

View File

@ -4,7 +4,6 @@ USING: accessors timers arrays calendar kernel make math math.rectangles
math.parser namespaces sequences system tetris.game tetris.gl ui.gadgets math.parser namespaces sequences system tetris.game tetris.gl ui.gadgets
ui.gadgets.labels ui.gadgets.worlds ui.gadgets.status-bar ui.gestures ui.gadgets.labels ui.gadgets.worlds ui.gadgets.status-bar ui.gestures
ui.render ui ; ui.render ui ;
FROM: tetris.game => level>> ;
IN: tetris IN: tetris
TUPLE: tetris-gadget < gadget { tetris tetris } { timer } ; TUPLE: tetris-gadget < gadget { tetris tetris } { timer } ;
@ -16,7 +15,7 @@ M: tetris-gadget pref-dim* drop { 200 400 } ;
: update-status ( gadget -- ) : update-status ( gadget -- )
dup tetris>> [ dup tetris>> [
[ "Level: " % level>> # ] [ "Level: " % level # ]
[ " Score: " % score>> # ] [ " Score: " % score>> # ]
[ paused?>> [ " (Paused)" % ] when ] tri [ paused?>> [ " (Paused)" % ] when ] tri
] "" make swap show-status ; ] "" make swap show-status ;